Skip to main content

Build agents that live in PLATO. Any model, any hardware, any armor.

Project description

PLATO SDK — Build Agents That Live in PLATO

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

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

pip install plato-sdk

For local models (GPU):

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

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

# 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)
└─────────────────────────────┘
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

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

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:

# 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:

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:

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

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

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

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

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

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

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

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

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)

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)

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

Jetson (Orin/Nano)

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

Ollama (Any hardware Ollama supports)

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)

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

# 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

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

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

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

Fleet Context

Part of the Cocapn fleet. Related repos:


🦐 Cocapn fleet — lighthouse keeper architecture

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

superinstance_plato_sdk-1.9.0-py3-none-any.whl (23.4 kB view details)

Uploaded Python 3

File details

Details for the file superinstance_plato_sdk-1.9.0-py3-none-any.whl.

File metadata

File hashes

Hashes for superinstance_plato_sdk-1.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 db2ebdec21598b1c87238c141eedfae2dd89e433f0fa6a592a3fb23e2530843d
MD5 58680531e7bb82c1d95ff9c865a96f04
BLAKE2b-256 860c8e40703f7f172e13698fa064e5b421c9fc86e2c625f25ba80cc4f56e46fd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page