# Send Teneo Agent SDK to your agent
Use the source page and any available docs to guide the install because the item currently does not return a direct package file.
## Fast path
- Open the source page via Open source listing.
- If you can obtain the package, extract it into a folder your agent can access.
- Paste one of the prompts below and point your agent at the source page and extracted files.
## Suggested prompts
### New install

```text
I tried to install a skill package from Yavira, but the item currently does not return a direct package file. Inspect the source page and any extracted docs, then tell me what you can confirm and any manual steps still required.
```
### Upgrade existing

```text
I tried to upgrade a skill package from Yavira, but the item currently does not return a direct package file. Compare the source page and any extracted docs with my current installation, then summarize what changed and what manual follow-up I still need.
```
## Machine-readable fields
```json
{
  "schemaVersion": "1.0",
  "item": {
    "slug": "teneo-agent-sdk",
    "name": "Teneo Agent SDK",
    "source": "tencent",
    "type": "skill",
    "category": "金融交易",
    "sourceUrl": "https://clawhub.ai/teneoprotocoldev/teneo-agent-sdk",
    "canonicalUrl": "https://clawhub.ai/teneoprotocoldev/teneo-agent-sdk",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadUrl": "/downloads/teneo-agent-sdk",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=teneo-agent-sdk",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "packageFormat": "ZIP package",
    "primaryDoc": "SKILL.md",
    "includedAssets": [
      "SKILL.md"
    ],
    "downloadMode": "manual_only",
    "sourceHealth": {
      "source": "tencent",
      "slug": "teneo-agent-sdk",
      "status": "source_issue",
      "reason": "not_found",
      "recommendedAction": "review_source",
      "checkedAt": "2026-04-29T06:02:16.252Z",
      "expiresAt": "2026-04-30T06:02:16.252Z",
      "httpStatus": 404,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=teneo-agent-sdk",
      "contentType": "text/plain",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=teneo-agent-sdk",
        "contentDisposition": null,
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "teneo-agent-sdk"
      },
      "scope": "item",
      "summary": "Known item issue.",
      "detail": "This item's current download entry is known to bounce back to a listing or homepage instead of returning a package file.",
      "primaryActionLabel": "Open source listing",
      "primaryActionHref": "https://clawhub.ai/teneoprotocoldev/teneo-agent-sdk"
    },
    "validation": {
      "installChecklist": [
        "Open the source listing and confirm there is a real package or setup artifact available.",
        "Review SKILL.md before asking your agent to continue.",
        "Treat this source as manual setup until the upstream download flow is fixed."
      ],
      "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/teneo-agent-sdk",
    "downloadUrl": "https://openagent3.xyz/downloads/teneo-agent-sdk",
    "agentUrl": "https://openagent3.xyz/skills/teneo-agent-sdk/agent",
    "manifestUrl": "https://openagent3.xyz/skills/teneo-agent-sdk/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/teneo-agent-sdk/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: teneoprotocoldev
- Version: 1.0.0
## Source health
- Status: source_issue
- Known item issue.
- This item's current download entry is known to bounce back to a listing or homepage instead of returning a package file.
- Health scope: item
- Reason: not_found
- Checked at: 2026-04-29T06:02:16.252Z
- Expires at: 2026-04-30T06:02:16.252Z
- Recommended action: Open source listing
## Links
- [Detail page](https://openagent3.xyz/skills/teneo-agent-sdk)
- [Send to Agent page](https://openagent3.xyz/skills/teneo-agent-sdk/agent)
- [JSON manifest](https://openagent3.xyz/skills/teneo-agent-sdk/agent.json)
- [Markdown brief](https://openagent3.xyz/skills/teneo-agent-sdk/agent.md)
- [Download page](https://openagent3.xyz/downloads/teneo-agent-sdk)