# Send tytyt to your agent
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
## Fast path
- Download the package from Yavira.
- Extract it into a folder your agent can access.
- Paste one of the prompts below and point your agent at the extracted folder.
## Suggested prompts
### New install

```text
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
```
### Upgrade existing

```text
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
```
## Machine-readable fields
```json
{
  "schemaVersion": "1.0",
  "item": {
    "slug": "tyt",
    "name": "tytyt",
    "source": "tencent",
    "type": "skill",
    "category": "通讯协作",
    "sourceUrl": "https://clawhub.ai/HunterDrop22/tyt",
    "canonicalUrl": "https://clawhub.ai/HunterDrop22/tyt",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadUrl": "/downloads/tyt",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=tyt",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "packageFormat": "ZIP package",
    "primaryDoc": "SKILL.md",
    "includedAssets": [
      "SKILL.md",
      "_meta.json"
    ],
    "downloadMode": "redirect",
    "sourceHealth": {
      "source": "tencent",
      "slug": "tyt",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-02T04:31:08.980Z",
      "expiresAt": "2026-05-09T04:31:08.980Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=tyt",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=tyt",
        "contentDisposition": "attachment; filename=\"tyt-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "tyt"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/tyt"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    }
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/tyt",
    "downloadUrl": "https://openagent3.xyz/downloads/tyt",
    "agentUrl": "https://openagent3.xyz/skills/tyt/agent",
    "manifestUrl": "https://openagent3.xyz/skills/tyt/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/tyt/agent.md"
  }
}
```
## Documentation

### Overview

The Teneo SDK (@teneo-protocol/sdk) enables connection to AI agents on the Teneo Protocol platform. It provides:

WebSocket-based real-time communication with AI agents
Wallet-based authentication using Ethereum private keys
Room management (private/public rooms, agent invitations)
x402 micropayment protocol for paid agent interactions
Multi-chain payment support (Base, Peaq, Avalanche)

### Installation

npm install @teneo-protocol/sdk
# or
pnpm add @teneo-protocol/sdk

### Rooms

Rooms are communication channels where users interact with AI agents:

Private rooms: Auto-available after authentication, no subscription needed
Public rooms: Require explicit subscription via subscribeToRoom()
Room ownership determines ability to invite agents

### Agents

AI agents are identified by their @handle (e.g., @x-agent-enterprise-v2). Agents can be:

Discovered via listAgents() or searchAgents()
Invited to private rooms by room owners
Some require x402 payments for each interaction

### x402 Payment Protocol

Micropayments for agent interactions using USDC on supported chains:

Base (chain ID: 8453) - Recommended for low fees
Peaq (chain ID: 3338)
Avalanche (chain ID: 43114)

Payment amounts are typically $0.01 - $0.10 per request.

### Authentication & Connection

import { TeneoSDK } from "@teneo-protocol/sdk";

const sdk = new TeneoSDK({
  wsUrl: "wss://backend.developer.chatroom.teneo-protocol.ai/ws",
  privateKey: "0x...", // Ethereum private key
  logLevel: "silent", // or "debug", "info", "warn", "error"
  maxReconnectAttempts: 30,

  // Payment configuration (required for paid agents)
  paymentNetwork: "eip155:8453", // Base network in CAIP-2 format
  paymentAsset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // Base USDC
});

// Connect (handles WebSocket + wallet signature auth)
await sdk.connect();

// Get authenticated wallet address
const authState = sdk.getAuthState();
console.log(\`Authenticated as: ${authState.walletAddress}\`);

// Check connection status
if (sdk.isConnected) {
  console.log("Connected!");
}

// Disconnect when done
sdk.disconnect();

### Payment Network Configuration

Use CAIP-2 format for paymentNetwork:

NetworkCAIP-2 IDChain IDUSDC ContractBaseeip155:845384530x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913Peaqeip155:333833380xbbA60da06c2c5424f03f7434542280FCAd453d10Avalancheeip155:43114431140xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E

### Discovering Rooms

// Get all rooms available to this wallet (sync - cached after connect)
const rooms = sdk.getRooms();

for (const room of rooms) {
  console.log(\`Room: ${room.name} [${room.id}]\`);
  console.log(\`  Public: ${room.is_public}\`);
  console.log(\`  Owner: ${room.is_owner}\`);
}

### Subscribing to Rooms

// Private rooms: auto-available after auth, no subscription needed
// Public rooms: require explicit subscription

const publicRoom = rooms.find(r => r.is_public);
if (publicRoom) {
  await sdk.subscribeToRoom(publicRoom.id);
}

// Check subscribed rooms
const subscribedRooms = sdk.getSubscribedRooms();
console.log(\`Subscribed to: ${subscribedRooms.join(", ")}\`);

### Finding Available Agents

// List all available agents on the platform
const agents = await sdk.listAgents();

for (const agent of agents) {
  console.log(\`Agent: ${agent.name} (@${agent.handle})\`);
  console.log(\`  ID: ${agent.agent_id}\`);
  console.log(\`  Description: ${agent.description}\`);
  console.log(\`  Price: $${agent.price_per_request || 0}\`);
}

// Search for agents by name or keyword
const results = await sdk.searchAgents("twitter");
console.log(\`Found ${results.length} agents matching "twitter"\`);

### Listing Agents in a Room

// Get agents currently in a specific room
const roomAgents = await sdk.listRoomAgents(roomId);

for (const agent of roomAgents) {
  console.log(\`  - ${agent.name} (${agent.agent_id})\`);
}

### Inviting Agents to Rooms

Only room owners can invite agents:

// First, find the agent you want to invite
const agents = await sdk.listAgents();
const xAgent = agents.find(a => a.handle === "x-agent-enterprise-v2");

if (xAgent) {
  // Add agent to your room by their agent_id
  await sdk.addAgentToRoom(roomId, xAgent.agent_id);
  console.log(\`Invited ${xAgent.name} to room\`);
}

// Or invite directly by known agent ID
await sdk.addAgentToRoom(roomId, "x-agent-enterprise-v2");

### Ensuring Required Agents Are in Room

async function ensureAgentsInRoom(
  sdk: TeneoSDK,
  roomId: string,
  requiredAgentIds: string[]
): Promise<void> {
  // Get agents currently in the room
  const roomAgents = await sdk.listRoomAgents(roomId);
  const existingIds = new Set(roomAgents.map(a => a.agent_id?.toLowerCase()));

  // Find missing agents
  const missing = requiredAgentIds.filter(
    id => !existingIds.has(id.toLowerCase())
  );

  // Invite missing agents
  for (const agentId of missing) {
    try {
      await sdk.addAgentToRoom(roomId, agentId);
      console.log(\`Invited agent "${agentId}" to room\`);
    } catch (err: any) {
      console.warn(\`Failed to invite "${agentId}": ${err.message}\`);
    }
  }
}

// Usage
await ensureAgentsInRoom(sdk, roomId, [
  "x-agent-enterprise-v2",
  "another-agent-id",
]);

### Basic Message

const response = await sdk.sendMessage("@x-agent-enterprise-v2 user @elonmusk", {
  waitForResponse: true,
  timeout: 60000, // 60 seconds
  format: "both", // Get both raw content and humanized version
});

console.log(response.humanized || response.content);

### Message with Room Context

const response = await sdk.sendMessage("@x-agent-enterprise-v2 post_stats 123456", {
  waitForResponse: true,
  timeout: 60000,
  format: "both",
  room: "room-id-here", // Specify target room
});

### Common Agent Commands

// X/Twitter agent - Get user profile stats
"@x-agent-enterprise-v2 user @username"

// X/Twitter agent - Get post/tweet stats
"@x-agent-enterprise-v2 post_stats 1234567890123456789"

### Agent Responses

sdk.on("agent:response", (data) => {
  console.log(\`Agent: ${data.agentName || data.agentId}\`);
  console.log(\`Success: ${data.success}\`);
  console.log(\`Content: ${data.humanized || data.content}\`);

  if (data.error) {
    console.error(\`Error: ${data.error}\`);
  }
});

### Payment Detection

x402 payments are reflected in agent responses. Parse the response to detect payment amounts:

sdk.on("agent:response", (data) => {
  const content = data.humanized || data.content || "";

  // Common patterns for payment detection
  const patterns = [
    /x402 Payment \\$([0-9.]+)/i,
    /Payment[:\\s]+\\$([0-9.]+)/i,
    /charged \\$([0-9.]+)/i,
    /\\$([0-9.]+)\\s*(?:USDC|usdc)/i,
  ];

  for (const pattern of patterns) {
    const match = content.match(pattern);
    if (match) {
      const usdAmount = parseFloat(match[1]);
      console.log(\`Payment: $${usdAmount} USDC\`);
      break;
    }
  }
});

### Connection Events

sdk.on("connection:open", () => {
  console.log("WebSocket connected");
});

sdk.on("disconnect", () => {
  console.log("Disconnected");
});

sdk.on("ready", () => {
  console.log("SDK ready for messages");
});

sdk.on("error", (err) => {
  // Handle rate limiting
  const rateLimitMatch = err.message.match(/Please wait (\\d+)ms/);
  if (rateLimitMatch) {
    const waitMs = parseInt(rateLimitMatch[1], 10);
    console.log(\`Rate limited, wait ${waitMs}ms\`);
    return;
  }

  // Handle auth failures
  if (err.message.includes("Invalid challenge") ||
      err.message.includes("authentication failed")) {
    console.log("Authentication failed, reconnecting...");
    return;
  }

  console.error(\`SDK Error: ${err.message}\`);
});

### Complete Example: Base Network Agent Interaction

import "dotenv/config";
import { TeneoSDK } from "@teneo-protocol/sdk";

// Configuration
const BASE_USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
const BASE_NETWORK = "eip155:8453";

async function main() {
  // Initialize SDK with Base payment config
  const sdk = new TeneoSDK({
    wsUrl: "wss://backend.developer.chatroom.teneo-protocol.ai/ws",
    privateKey: process.env.PRIVATE_KEY!,
    logLevel: "info",
    maxReconnectAttempts: 10,
    paymentNetwork: BASE_NETWORK,
    paymentAsset: BASE_USDC,
  });

  // Track payments
  let totalSpent = 0;

  sdk.on("agent:response", (data) => {
    const content = data.humanized || data.content || "";

    // Detect x402 payment
    const match = content.match(/\\$([0-9.]+)/);
    if (match) {
      const amount = parseFloat(match[1]);
      if (amount > 0 && amount < 1) { // Sanity check
        totalSpent += amount;
        console.log(\`Payment: $${amount} | Total: $${totalSpent.toFixed(4)}\`);
      }
    }
  });

  // Connect with retry logic
  for (let attempt = 1; attempt <= 5; attempt++) {
    try {
      await sdk.connect();
      console.log("Connected!");
      break;
    } catch (err: any) {
      // Handle rate limiting
      const rateLimitMatch = err.message?.match(/Please wait (\\d+)ms/);
      if (rateLimitMatch) {
        const waitMs = parseInt(rateLimitMatch[1], 10) + 100;
        console.log(\`Rate limited, waiting ${waitMs}ms...\`);
        await sleep(waitMs);
        continue;
      }
      throw err;
    }
  }

  // Get wallet address
  const authState = sdk.getAuthState();
  console.log(\`Wallet: ${authState.walletAddress}\`);

  // Find a room (prefer private rooms)
  const rooms = sdk.getRooms();
  let selectedRoom = rooms.find(r => !r.is_public) || rooms[0];

  if (selectedRoom?.is_public) {
    await sdk.subscribeToRoom(selectedRoom.id);
  }

  console.log(\`Using room: ${selectedRoom?.name || selectedRoom?.id}\`);

  // Discover available agents
  const agents = await sdk.listAgents();
  console.log(\`\\nAvailable agents (${agents.length}):\`);
  for (const agent of agents.slice(0, 5)) {
    console.log(\`  - @${agent.handle}: ${agent.name}\`);
  }

  // Ensure agent is in room (if we own it)
  if (selectedRoom?.is_owner) {
    try {
      await sdk.addAgentToRoom(selectedRoom.id, "x-agent-enterprise-v2");
      console.log("Agent invited to room");
    } catch (e) {
      // Agent may already be in room
    }
  }

  // Send command to X agent
  console.log("\\nSending request to @x-agent-enterprise-v2...");

  const response = await sdk.sendMessage(
    "@x-agent-enterprise-v2 user @VitalikButerin",
    {
      waitForResponse: true,
      timeout: 60000,
      format: "both",
      room: selectedRoom?.id,
    }
  );

  console.log("\\nResponse:");
  console.log(response.humanized || response.content);

  // Cleanup
  sdk.disconnect();
  console.log(\`\\nTotal spent: $${totalSpent.toFixed(4)} USDC\`);
}

function sleep(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms));
}

main().catch(console.error);

### Connection Errors

async function connectWithRetry(sdk: TeneoSDK, maxAttempts = 10): Promise<void> {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      await sdk.connect();
      return;
    } catch (err: any) {
      const msg = err?.message || String(err);

      // Rate limiting - wait and retry
      const rateLimitMatch = msg.match(/Please wait (\\d+)ms/);
      if (rateLimitMatch) {
        const waitMs = parseInt(rateLimitMatch[1], 10) + 100;
        await sleep(waitMs);
        continue;
      }

      // Auth errors - exponential backoff
      if (msg.includes("Invalid challenge") ||
          msg.includes("authentication failed")) {
        const backoff = Math.min(5000 * Math.pow(2, attempt - 1), 60000);
        await sleep(backoff);
        continue;
      }

      // Other errors - shorter retry
      if (attempt < maxAttempts) {
        await sleep(3000 * attempt);
        continue;
      }

      throw err;
    }
  }
}

### Payment Errors

try {
  const response = await sdk.sendMessage(command, options);
  // Handle success
} catch (err: any) {
  if (err.message.includes("Payment verification failed")) {
    // Insufficient USDC balance - need to fund wallet
    console.log("Payment failed - check USDC balance");
  } else if (err.message.includes("payment")) {
    // Other payment issue
    console.log("Payment error:", err.message);
  }
}

### Multi-Network Support

Switch between networks by creating SDK instances with different payment configs:

const NETWORKS = {
  base: {
    paymentNetwork: "eip155:8453",
    paymentAsset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  },
  peaq: {
    paymentNetwork: "eip155:3338",
    paymentAsset: "0xbbA60da06c2c5424f03f7434542280FCAd453d10",
  },
  avax: {
    paymentNetwork: "eip155:43114",
    paymentAsset: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
  },
};

function createSDK(network: keyof typeof NETWORKS, privateKey: string): TeneoSDK {
  const config = NETWORKS[network];
  return new TeneoSDK({
    wsUrl: "wss://backend.developer.chatroom.teneo-protocol.ai/ws",
    privateKey,
    paymentNetwork: config.paymentNetwork,
    paymentAsset: config.paymentAsset,
  });
}

### Environment Variables

Typical .env configuration:

# Required
PRIVATE_KEY=0x...

# Optional
WS_URL=wss://backend.developer.chatroom.teneo-protocol.ai/ws
ROOM=my-room-name

# Network-specific RPC URLs (for balance checks)
BASE_RPC_URL=https://mainnet.base.org
PEAQ_RPC_URL=https://peaq.api.onfinality.io/public
AVAX_RPC_URL=https://api.avax.network/ext/bc/C/rpc

### TypeScript Types

interface SDKConfig {
  wsUrl: string;
  privateKey: string;
  logLevel?: "silent" | "debug" | "info" | "warn" | "error";
  maxReconnectAttempts?: number;
  paymentNetwork?: string;  // CAIP-2 format: "eip155:chainId"
  paymentAsset?: string;    // USDC contract address
}

interface Room {
  id: string;
  name: string;
  is_public?: boolean;
  is_owner?: boolean;
}

interface Agent {
  agent_id: string;
  name: string;
  handle: string;
  description?: string;
  price_per_request?: number;
}

interface AgentResponse {
  taskId: string;
  agentId: string;
  agentName?: string;
  content: string;
  success: boolean;
  error?: string;
  humanized?: string;
}

interface MessageOptions {
  waitForResponse?: boolean;
  timeout?: number;
  format?: "raw" | "humanized" | "both";
  room?: string;
}

interface AuthState {
  walletAddress?: string;
}

### Tips

Always check USDC balance before sending paid requests
Use private rooms when possible - no subscription needed
Handle rate limits gracefully - the SDK enforces connection limits
Set appropriate timeouts - agent responses can take 30-60 seconds
Prefer Base network for lowest transaction fees
Disconnect cleanly to avoid orphaned WebSocket connections
Discover agents first - use listAgents() to find available agents before inviting
## Trust
- Source: tencent
- Verification: Indexed source record
- Publisher: HunterDrop22
- Version: 1.0.0
## Source health
- Status: healthy
- Item download looks usable.
- Yavira can redirect you to the upstream package for this item.
- Health scope: item
- Reason: direct_download_ok
- Checked at: 2026-05-02T04:31:08.980Z
- Expires at: 2026-05-09T04:31:08.980Z
- Recommended action: Download for OpenClaw
## Links
- [Detail page](https://openagent3.xyz/skills/tyt)
- [Send to Agent page](https://openagent3.xyz/skills/tyt/agent)
- [JSON manifest](https://openagent3.xyz/skills/tyt/agent.json)
- [Markdown brief](https://openagent3.xyz/skills/tyt/agent.md)
- [Download page](https://openagent3.xyz/downloads/tyt)