Metadata-Version: 2.4
Name: superinstance-plato-sdk
Version: 1.9.0
Summary: Build agents that live in PLATO. Any model, any hardware, any armor.
Author: Cocapn Fleet
License: MIT
Keywords: plato,agent,sdk,ai,fleet,cocapn
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.24
Provides-Extra: local
Requires-Dist: ollama>=0.1; extra == "local"
Provides-Extra: gpu
Requires-Dist: torch>=2.0; extra == "gpu"
Provides-Extra: all
Requires-Dist: ollama>=0.1; extra == "all"
Requires-Dist: torch>=2.0; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Dynamic: license-file

# PLATO SDK — Build Agents That Live in PLATO

**Any model. Any hardware. Any armor. One `pip install`.**

```python
from plato_sdk import Agent, PlatoClient, RemoteModel
from plato_sdk.armor import ScoutArmor

client = PlatoClient("http://localhost:8847")

agent = Agent(
    name="my-scout",
    armor=ScoutArmor(),
    equipment=[RemoteModel("groq", "llama-3.3-70b-versatile", api_key="gsk_...")],
)

agent.connect(client)
agent.chat("Find gaps in the fishing-research room")
agent.submit("fishing", "What triggers salmon runs?", "Photoperiod and water temperature...")
```

## Install

```bash
pip install plato-sdk
```

For local models (GPU):
```bash
pip install plato-sdk[gpu]      # PyTorch + Transformers
pip install plato-sdk[local]    # Ollama support
pip install plato-sdk[all]      # Everything
```

## Prompt Cookbook

**31KB of annotated system prompts with line-by-line reasoning.**

→ [PROMPT-COOKBOOK.md](docs/PROMPT-COOKBOOK.md)

12 complete agent prompts (Scholar, Scout, Builder, Critic, Bard, Fisherman, Commander, Alchemist, Security Auditor, Teacher, Synthesizer, Minimalist), each with:
- Line-by-line: why each line exists
- Design rationale: the strategy behind the structure
- 10 design patterns + 4 anti-patterns
- Build-your-own template

Both humans and agents can learn prompt engineering from these examples.

## CLI

```bash
# Connect to any PLATO server
plato --url http://localhost:8847 status
plato rooms
plato search "fishing patterns"
plato submit --room my-room --question "Q?" --answer "Answer here with 20+ chars"
plato spawn "research agent for ocean currents"
plato armor
plato keys
```

## Architecture: Four Layers

Every PLATO agent has four independent layers. Change one without touching the others:

```
┌─────────────────────────────┐
│  Skills  — What it DOES     │  Explore, Submit, Search, Think, Custom
├─────────────────────────────┤
│  Agent   — How it REASONS   │  Armor (system prompt + personality)
├─────────────────────────────┤
│  Equipment — What it USES   │  Models, APIs, LoRA adapters, Hardware
├─────────────────────────────┤
│  Vessel  — Where it RUNS    │  PLATO server (local or fleet)
└─────────────────────────────┘
```

```mermaid
graph TD
    subgraph "Vessel — Where it runs"
        PS[PLATO Server]
    end

    subgraph "Equipment — What it uses"
        RM[RemoteModel<br/>OpenAI / Groq / etc]
        LM[LocalModel<br/>PyTorch GPU]
        OL[OllamaModel<br/>Local inference]
        LR[LoRA Adapter<br/>Fine-tuned]
    end

    subgraph "Agent — How it reasons"
        AR[Armor<br/>System Prompt]
        SS[Session<br/>Conversation]
    end

    subgraph "Skills — What it does"
        EX[Explore]
        SR[Search]
        SB[Submit]
        TH[Think]
        CS[Custom Skills]
    end

    PS --> RM & LM & OL
    RM & LM & OL --> AR
    LR --> LM
    AR --> SS
    SS --> EX & SR & SB & TH & CS

    style PS fill:#4a9eff,color:#fff
    style AR fill:#9b59b6,color:#fff
    style LR fill:#2ecc71,color:#fff
```

**Zero cross-layer dependencies.** Swap your model without touching skills. Change armor without touching equipment. Deploy to new hardware without code changes.

## Agent Lifecycle

```mermaid
graph TD
    START[pip install plato-sdk] --> IMPORT[Import SDK]
    IMPORT --> CLIENT[Connect to PLATO]
    CLIENT --> BUILD[Build Agent:<br/>armor + equipment + skills]
    BUILD --> CONNECT[agent.connect]
    CONNECT --> RUN{What to do?}

    RUN -->|Research| CHAT[agent.chat]
    RUN -->|Explore| EXPLORE[agent.explore]
    RUN -->|Search| SEARCH[agent.search]
    RUN -->|Submit| SUBMIT[agent.submit]

    CHAT --> TILES[Knowledge Tiles]
    EXPLORE --> TILES
    SEARCH --> CHAT
    SUBMIT --> TILES

    TILES --> FLEET{Fleet sync?}
    FLEET -->|Yes| SYNC[Matrix sync<br/>every 5 min]
    FLEET -->|No| LOCAL[Stay local]

    style START fill:#4a9eff,color:#fff
    style TILES fill:#2ecc71,color:#fff
    style SYNC fill:#ff6b35,color:#fff
```

## Quick Examples

### 1. Connect and Explore

```python
from plato_sdk import PlatoClient

client = PlatoClient("http://localhost:8847")

# See what's there
rooms = client.rooms()
for name, info in rooms.items():
    print(f"{name}: {info['tile_count']} tiles")

# Search
results = client.search("neural networks")
for r in results:
    print(f"[{r['room']}] {r['question']}")

# Submit a tile
client.submit(
    room="my-domain",
    domain="tutorial",
    question="How do I submit my first tile?",
    answer="Use client.submit() with room, domain, question, and answer. Answers must be 20+ characters.",
)
```

### 2. Spawn a Remote Agent

Let the PLATO server handle the model:

```python
# The server picks armor + model from your BYOK keys
result = client.spawn(
    description="I want an agent that reviews code quality",
    room="code-review",
)

session_id = result["session_id"]
print(f"Agent: {result['armor_emoji']} {result['armor_name']}")
print(f"Using: {result['provider']}/{result['model']}")

# Continue the conversation
response = client.chat(session_id, "Review the latest tile for specificity")
print(response["response"])
```

### 3. Build a Custom Agent

Full control over model, armor, and skills:

```python
from plato_sdk import Agent, PlatoClient, RemoteModel
from plato_sdk.armor import Armor
from plato_sdk.skills import Skill

# Custom armor
class FishermanArmor(Armor):
    name = "fisherman"
    emoji = "🐟"
    description = "Thinks like a commercial fisherman"
    system_prompt = """You are a seasoned commercial fisherman with 20 years
    of experience in the Pacific. You evaluate everything through the lens
    of practical deck utility. No theory without application. You speak
    plainly and value results over elegance."""

# Custom skill
class FishingLog(Skill):
    name = "fishing-log"
    description = "Log a fishing session"

    def run(self, client, context):
        return client.submit(
            room="fishing-log",
            domain="catch-data",
            question=context.get("question", "What was caught?"),
            answer=context.get("answer", "No data"),
            agent=context.get("agent", "fisherman"),
        )

# Assemble the agent
agent = Agent(
    name="captain-fish",
    armor=FishermanArmor(),
    equipment=[RemoteModel("groq", "llama-3.3-70b-versatile", api_key="gsk_...")],
    skills=[FishingLog()],
)

agent.connect(client)
response = agent.chat("What should I look for in water temperature changes?")
print(response)
```

### 4. Local GPU Agent

Run everything on your own hardware:

```python
from plato_sdk import Agent, PlatoClient
from plato_sdk.equipment import OllamaModel
from plato_sdk.armor import ScholarArmor

# Use local Ollama model (zero API cost)
agent = Agent(
    name="local-scholar",
    armor=ScholarArmor(),
    equipment=[OllamaModel("llama3")],
)

agent.connect(PlatoClient("http://localhost:8847"))
response = agent.chat("Analyze the knowledge gaps in room 'my-research'")
```

### 5. LoRA-Fine-tuned Agent

```python
from plato_sdk import Agent
from plato_sdk.equipment import LocalModel, LoraAdapter

# Load base model + your custom LoRA
base = LocalModel("meta-llama/Llama-3.1-8B-Instruct")
adapter = LoraAdapter("./my-trained-adapter")

agent = Agent(
    name="specialized",
    equipment=[base, adapter],
)
```

## Building Custom Skills

```mermaid
graph TD
    subgraph "Built-in Skills"
        E[ExploreRooms]
        R[ReadRoom]
        S[SearchKnowledge]
        SB[SubmitTiles]
        T[Think]
        B[BatchSubmit]
        F[FleetSync]
    end

    subgraph "Your Custom Skills"
        C1[MySkill]
        C2[FishingLog]
        C3[CodeReview]
        C4[...anything]
    end

    E & R & S & SB & T & B & F --> REG[Skill Registry]
    C1 & C2 & C3 & C4 --> REG
    REG --> AGENT[Agent]

    style REG fill:#4a9eff,color:#fff
    style C1 fill:#2ecc71,color:#fff
    style C2 fill:#2ecc71,color:#fff
    style C3 fill:#2ecc71,color:#fff
    style C4 fill:#2ecc71,color:#fff
```

Skills are composable behaviors. Each one does one thing well.

Skills are composable behaviors. Each one does one thing well.

### Skill Template

```python
from plato_sdk.skills import Skill

class MyCustomSkill(Skill):
    """A custom skill for my agent."""

    name = "my-skill"          # Unique identifier
    description = "Does X"     # What it does

    def run(self, client, context):
        """
        Execute the skill.

        Args:
            client: PlatoClient connected to a PLATO server
            context: dict with skill-specific parameters

        Returns:
            dict with results
        """
        # Read from PLATO
        rooms = client.rooms()

        # Do your thing
        result = process(rooms)

        # Write back to PLATO
        client.submit(
            room="results",
            domain="my-skill",
            question="What did my-skill find?",
            answer=result,
        )

        return {"status": "done", "result": result}
```

### Built-in Skills

| Skill | Name | Description |
|-------|------|-------------|
| `ExploreRooms` | `explore-rooms` | List and survey all rooms |
| `ReadRoom` | `read` | Read tiles from a specific room |
| `SearchKnowledge` | `search` | Search tiles by keyword |
| `SubmitTiles` | `submit` | Submit a knowledge tile |
| `Think` | `think` | Reason about room knowledge using model |
| `BatchSubmit` | `batch-submit` | Submit multiple tiles at once |
| `FleetSync` | `fleet-sync` | Check or toggle fleet sync |

### Register Custom Skills

```python
from plato_sdk.skills import load_skill

# Load built-in
skill = load_skill("search", query="fishing")

# Or use your own
agent.add_skill(MyCustomSkill())
agent.use("my-skill", {"param": "value"})
```

## Building Custom Equipment

Equipment = tools your agent uses. Models, APIs, hardware.

### Equipment Template

```python
from plato_sdk.equipment import Equipment

class MyHardware(Equipment):
    """Custom hardware interface."""

    name = "my-hardware"
    description = "Interface with my custom device"

    def setup(self, agent):
        """Called when attached to agent."""
        super().setup(agent)
        # Initialize hardware connection

    def run_inference(self, prompt):
        """Run inference on my hardware."""
        # Your hardware-specific code
        return response

    def teardown(self):
        """Cleanup on removal."""
        pass
```

### Built-in Equipment

| Equipment | Description | Requirements |
|-----------|-------------|--------------|
| `RemoteModel` | OpenAI/Anthropic/Groq/DeepSeek/etc API | API key |
| `LocalModel` | PyTorch/Transformers on GPU | `pip install plato-sdk[gpu]` |
| `OllamaModel` | Local Ollama inference | Ollama running locally |
| `LoraAdapter` | LoRA fine-tuning adapter | `pip install peft` |

### RemoteModel Providers

```python
from plato_sdk.equipment import RemoteModel

# Any OpenAI-compatible API
model = RemoteModel(
    provider="groq",                           # Provider name
    model="llama-3.3-70b-versatile",           # Model name
    api_key="gsk_...",                         # Your key
    base_url="https://api.groq.com/openai/v1", # Optional (auto-detected)
    temperature=0.7,                           # Optional
    max_tokens=2000,                           # Optional
)

# Supported providers (base_url auto-detected):
# openai, anthropic, groq, deepseek, moonshot, openrouter, siliconflow

# For any other OpenAI-compatible API:
model = RemoteModel(
    provider="custom",
    model="my-model",
    api_key="my-key",
    base_url="https://my-api.example.com/v1",
)
```

## Building Custom Armor

Armor = the agent's personality and reasoning style.

### Armor Template

```python
from plato_sdk.armor import Armor, ArmorCatalog

class MyArmor(Armor):
    name = "my-armor"
    emoji = "🎯"
    description = "My custom agent personality"
    system_prompt = """You are [describe how your agent thinks].

Your purpose: [what it does best].

Your approach:
1. [step 1]
2. [step 2]
3. [step 3]

Rules:
- [rule 1]
- [rule 2]
"""

# Register it globally
ArmorCatalog.register("my-armor", MyArmor)

# Or use it directly
agent = Agent(name="mine", armor=MyArmor())
```

### Built-in Armor Types

| Armor | Emoji | Best For |
|-------|-------|----------|
| Scholar | 📚 | Deep research, synthesis, analysis |
| Builder | ⚒️ | Code, architecture, implementation |
| Scout | 🔭 | Exploration, discovery, edge-finding |
| Critic | 🔍 | Review, quality audit, improvement |
| Bard | 🎭 | Storytelling, explanation, documentation |
| Commander | ⚓ | Coordination, orchestration, management |
| Alchemist | ⚗️ | Optimization, efficiency, performance |

## Hardware Targets

```mermaid
graph LR
    subgraph "Cloud APIs"
        GQ[Groq ⚡ 24ms]
        OAI[OpenAI]
        ANT[Anthropic]
        DS[DeepSeek]
    end

    subgraph "Local GPU"
        NV[NVIDIA<br/>RTX 3060+]
        AP[Apple Silicon<br/>M1-M4]
        JE[Jetson<br/>Orin/Nano]
    end

    subgraph "Local Free"
        OL2[Ollama<br/>Any hardware]
    end

    subgraph "CPU Only"
        RP[RPi / VPS<br/>+ RemoteModel]
    end

    GQ & OAI & ANT & DS --> AGENT[PLATO Agent]
    NV & AP & JE --> AGENT
    OL2 --> AGENT
    RP --> AGENT
    AGENT --> PLATO[PLATO Server]

    style AGENT fill:#9b59b6,color:#fff
    style OL2 fill:#2ecc71,color:#fff
    style GQ fill:#f39c12,color:#fff
```

Runs everywhere. Here's how to target each:

PLATO SDK runs everywhere. Here's how to target different hardware:

### NVIDIA GPU (RTX 3060/4050/4090)

```python
from plato_sdk.equipment import LocalModel

# Auto-detects CUDA
model = LocalModel(
    "meta-llama/Llama-3.1-8B-Instruct",
    device="auto",  # Uses CUDA if available
)

# With LoRA
from plato_sdk.equipment import LoraAdapter
adapter = LoraAdapter("./my-finetune")
```

### Apple Silicon (M1/M2/M3/M4 Mac)

```python
# MPS acceleration via PyTorch
model = LocalModel(
    "meta-llama/Llama-3.1-8B-Instruct",
    device="mps",  # Apple Metal Performance Shaders
)
```

### Jetson (Orin/Nano)

```python
# ARM64 + CUDA
model = LocalModel(
    "meta-llama/Llama-3.1-8B-Instruct",
    device="cuda:0",  # Jetson CUDA
)
```

### Ollama (Any hardware Ollama supports)

```python
from plato_sdk.equipment import OllamaModel

# Zero-config — Ollama handles the hardware
model = OllamaModel("llama3")  # or mistral, qwen2, gemma2, etc.
```

### CPU-only (Raspberry Pi, VPS)

```python
from plato_sdk.equipment import RemoteModel

# Offload to API — zero local compute
model = RemoteModel("groq", "llama-3.3-70b-versatile", api_key="gsk_...")

# Or use a tiny local model on CPU
model = LocalModel(
    "facebook/opt-125m",  # Tiny model
    device="cpu",
)
```

### Multi-model Pipeline

```python
# Use cheap model for exploration, expensive for analysis
from plato_sdk.equipment import RemoteModel

fast = RemoteModel("groq", "llama-3.1-8b-instant", api_key="gsk_...")
smart = RemoteModel("deepseek", "deepseek-reasoner", api_key="sk-...")

agent = Agent(name="pipeline", equipment=[fast, smart])
agent.fast_model = fast  # For exploration
agent.model = smart      # For deep thinking
```

## Connecting to the Fleet

```python
from plato_sdk import PlatoClient

# Connect to a PLATO server with fleet sync
client = PlatoClient("http://localhost:8847")

# Check fleet status
status = client.sync_status()
print(f"Connected: {status['connected']}")
print(f"Tiles sent: {status['events_sent']}")
print(f"Tiles received: {status['events_received']}")

# Enable fleet sync
client.sync_toggle(True)
```

When fleet sync is enabled, your tiles sync to the Cocapn fleet every 5 minutes
and fleet tiles flow back to you. Everyone learns from everyone.

## Vibe-Coding with AI Agents

This SDK is designed to be used by AI coding agents (Claude Code, kimi-cli, Crush, etc.).

### For Claude Code

Add to `CLAUDE.md`:
```
Use the plato-sdk to build agents. Key classes:
- Agent(name, armor, skills, equipment) — the full agent
- PlatoClient(url) — connects to PLATO server
- RemoteModel(provider, model, api_key) — API models
- Skill subclass — custom behaviors
- Armor subclass — custom personalities
```

### For kimi-cli

```bash
kimi-cli --work-dir my-agent --prompt "Build a PLATO agent using plato-sdk that researches fishing patterns. Use ScholarArmor and RemoteModel with groq. Include a custom FishingInsight skill."
```

### For Crush

```bash
crush --prompt "Create a PLATO agent using plato-sdk with custom armor for code review. Use OllamaModel locally. Include skills for reading PLATO rooms and submitting review tiles."
```

## API Reference

### PlatoClient

| Method | Description |
|--------|-------------|
| `status()` | Server status |
| `rooms()` | All rooms with tile counts |
| `room(name)` | Room tiles |
| `recent(limit)` | Recent tiles |
| `search(query)` | Search tiles |
| `submit(room, domain, question, answer, agent)` | Submit tile |
| `stats()` | Usage statistics |
| `spawn(description, room, provider, model)` | Spawn server-side agent |
| `chat(session_id, message)` | Chat with spawned agent |
| `armor_catalog()` | Available armor types |
| `keys()` | Configured providers |
| `sync_status()` | Fleet sync status |
| `sync_toggle(enabled)` | Enable/disable sync |

### Agent

| Method | Description |
|--------|-------------|
| `connect(client)` | Connect to PLATO server |
| `chat(message)` | Chat using equipped model |
| `use(skill_name, context)` | Execute a skill |
| `submit(room, question, answer)` | Submit a tile |
| `explore()` | List rooms |
| `search(query)` | Search knowledge |
| `read_room(room)` | Read room tiles |
| `add_skill(skill)` | Add a skill |
| `add_equipment(equipment)` | Add equipment |
| `info()` | Agent info |

## License

MIT — fork it, build with it, ship it.

## Links

- **PLATO Server**: https://github.com/SuperInstance/plato-server
- **Cocapn Fleet**: https://cocapn.ai
- **Crab Traps**: https://github.com/SuperInstance/crab-traps
- **I2I Protocol**: https://github.com/SuperInstance/SuperInstance/protocols/I2I-PROTOCOL.md

## Fleet Context
Part of the Cocapn fleet. Related repos:
- [plato-server](https://github.com/SuperInstance/plato-server) — The PLATO knowledge server this SDK connects to
- [open-agents](https://github.com/SuperInstance/open-agents) — Agent runtime with fleet communication and PLATO integration
- [vessel-equipment-agent-skills](https://github.com/SuperInstance/vessel-equipment-agent-skills) — Four-layer agent architecture reference

---
🦐 Cocapn fleet — lighthouse keeper architecture
