{
  "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": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/teneo-agent-sdk",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=teneo-agent-sdk",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "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."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "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."
        },
        {
          "label": "Upgrade existing",
          "body": "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."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/teneo-agent-sdk"
    },
    "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."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/teneo-agent-sdk",
    "agentPageUrl": "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"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "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."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "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."
      },
      {
        "label": "Upgrade existing",
        "body": "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."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Overview",
        "body": "The Teneo SDK (@teneo-protocol/sdk) enables connection to AI agents on the Teneo Protocol platform. It provides:\n\nWebSocket-based real-time communication with AI agents\nWallet-based authentication using Ethereum private keys\nRoom management (private/public rooms, agent invitations)\nx402 micropayment protocol for paid agent interactions\nMulti-chain payment support (Base, Peaq, Avalanche)"
      },
      {
        "title": "Installation",
        "body": "npm install @teneo-protocol/sdk\n# or\npnpm add @teneo-protocol/sdk"
      },
      {
        "title": "Rooms",
        "body": "Rooms are communication channels where users interact with AI agents:\n\nPrivate rooms: Auto-available after authentication, no subscription needed\nPublic rooms: Require explicit subscription via subscribeToRoom()\nRoom ownership determines ability to invite agents"
      },
      {
        "title": "Agents",
        "body": "AI agents are identified by their @handle (e.g., @x-agent-enterprise-v2). Agents can be:\n\nDiscovered via listAgents() or searchAgents()\nInvited to private rooms by room owners\nSome require x402 payments for each interaction"
      },
      {
        "title": "x402 Payment Protocol",
        "body": "Micropayments for agent interactions using USDC on supported chains:\n\nBase (chain ID: 8453) - Recommended for low fees\nPeaq (chain ID: 3338)\nAvalanche (chain ID: 43114)\n\nPayment amounts are typically $0.01 - $0.10 per request."
      },
      {
        "title": "Authentication & Connection",
        "body": "import { TeneoSDK } from \"@teneo-protocol/sdk\";\n\nconst sdk = new TeneoSDK({\n  wsUrl: \"wss://backend.developer.chatroom.teneo-protocol.ai/ws\",\n  privateKey: \"0x...\", // Ethereum private key\n  logLevel: \"silent\", // or \"debug\", \"info\", \"warn\", \"error\"\n  maxReconnectAttempts: 30,\n\n  // Payment configuration (required for paid agents)\n  paymentNetwork: \"eip155:8453\", // Base network in CAIP-2 format\n  paymentAsset: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", // Base USDC\n});\n\n// Connect (handles WebSocket + wallet signature auth)\nawait sdk.connect();\n\n// Get authenticated wallet address\nconst authState = sdk.getAuthState();\nconsole.log(`Authenticated as: ${authState.walletAddress}`);\n\n// Check connection status\nif (sdk.isConnected) {\n  console.log(\"Connected!\");\n}\n\n// Disconnect when done\nsdk.disconnect();"
      },
      {
        "title": "Payment Network Configuration",
        "body": "Use CAIP-2 format for paymentNetwork:\n\nNetworkCAIP-2 IDChain IDUSDC ContractBaseeip155:845384530x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913Peaqeip155:333833380xbbA60da06c2c5424f03f7434542280FCAd453d10Avalancheeip155:43114431140xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"
      },
      {
        "title": "Discovering Rooms",
        "body": "// Get all rooms available to this wallet (sync - cached after connect)\nconst rooms = sdk.getRooms();\n\nfor (const room of rooms) {\n  console.log(`Room: ${room.name} [${room.id}]`);\n  console.log(`  Public: ${room.is_public}`);\n  console.log(`  Owner: ${room.is_owner}`);\n}"
      },
      {
        "title": "Subscribing to Rooms",
        "body": "// Private rooms: auto-available after auth, no subscription needed\n// Public rooms: require explicit subscription\n\nconst publicRoom = rooms.find(r => r.is_public);\nif (publicRoom) {\n  await sdk.subscribeToRoom(publicRoom.id);\n}\n\n// Check subscribed rooms\nconst subscribedRooms = sdk.getSubscribedRooms();\nconsole.log(`Subscribed to: ${subscribedRooms.join(\", \")}`);"
      },
      {
        "title": "Finding Available Agents",
        "body": "// List all available agents on the platform\nconst agents = await sdk.listAgents();\n\nfor (const agent of agents) {\n  console.log(`Agent: ${agent.name} (@${agent.handle})`);\n  console.log(`  ID: ${agent.agent_id}`);\n  console.log(`  Description: ${agent.description}`);\n  console.log(`  Price: $${agent.price_per_request || 0}`);\n}\n\n// Search for agents by name or keyword\nconst results = await sdk.searchAgents(\"twitter\");\nconsole.log(`Found ${results.length} agents matching \"twitter\"`);"
      },
      {
        "title": "Listing Agents in a Room",
        "body": "// Get agents currently in a specific room\nconst roomAgents = await sdk.listRoomAgents(roomId);\n\nfor (const agent of roomAgents) {\n  console.log(`  - ${agent.name} (${agent.agent_id})`);\n}"
      },
      {
        "title": "Inviting Agents to Rooms",
        "body": "Only room owners can invite agents:\n\n// First, find the agent you want to invite\nconst agents = await sdk.listAgents();\nconst xAgent = agents.find(a => a.handle === \"x-agent-enterprise-v2\");\n\nif (xAgent) {\n  // Add agent to your room by their agent_id\n  await sdk.addAgentToRoom(roomId, xAgent.agent_id);\n  console.log(`Invited ${xAgent.name} to room`);\n}\n\n// Or invite directly by known agent ID\nawait sdk.addAgentToRoom(roomId, \"x-agent-enterprise-v2\");"
      },
      {
        "title": "Ensuring Required Agents Are in Room",
        "body": "async function ensureAgentsInRoom(\n  sdk: TeneoSDK,\n  roomId: string,\n  requiredAgentIds: string[]\n): Promise<void> {\n  // Get agents currently in the room\n  const roomAgents = await sdk.listRoomAgents(roomId);\n  const existingIds = new Set(roomAgents.map(a => a.agent_id?.toLowerCase()));\n\n  // Find missing agents\n  const missing = requiredAgentIds.filter(\n    id => !existingIds.has(id.toLowerCase())\n  );\n\n  // Invite missing agents\n  for (const agentId of missing) {\n    try {\n      await sdk.addAgentToRoom(roomId, agentId);\n      console.log(`Invited agent \"${agentId}\" to room`);\n    } catch (err: any) {\n      console.warn(`Failed to invite \"${agentId}\": ${err.message}`);\n    }\n  }\n}\n\n// Usage\nawait ensureAgentsInRoom(sdk, roomId, [\n  \"x-agent-enterprise-v2\",\n  \"another-agent-id\",\n]);"
      },
      {
        "title": "Basic Message",
        "body": "const response = await sdk.sendMessage(\"@x-agent-enterprise-v2 user @elonmusk\", {\n  waitForResponse: true,\n  timeout: 60000, // 60 seconds\n  format: \"both\", // Get both raw content and humanized version\n});\n\nconsole.log(response.humanized || response.content);"
      },
      {
        "title": "Message with Room Context",
        "body": "const response = await sdk.sendMessage(\"@x-agent-enterprise-v2 post_stats 123456\", {\n  waitForResponse: true,\n  timeout: 60000,\n  format: \"both\",\n  room: \"room-id-here\", // Specify target room\n});"
      },
      {
        "title": "Common Agent Commands",
        "body": "// X/Twitter agent - Get user profile stats\n\"@x-agent-enterprise-v2 user @username\"\n\n// X/Twitter agent - Get post/tweet stats\n\"@x-agent-enterprise-v2 post_stats 1234567890123456789\""
      },
      {
        "title": "Agent Responses",
        "body": "sdk.on(\"agent:response\", (data) => {\n  console.log(`Agent: ${data.agentName || data.agentId}`);\n  console.log(`Success: ${data.success}`);\n  console.log(`Content: ${data.humanized || data.content}`);\n\n  if (data.error) {\n    console.error(`Error: ${data.error}`);\n  }\n});"
      },
      {
        "title": "Payment Detection",
        "body": "x402 payments are reflected in agent responses. Parse the response to detect payment amounts:\n\nsdk.on(\"agent:response\", (data) => {\n  const content = data.humanized || data.content || \"\";\n\n  // Common patterns for payment detection\n  const patterns = [\n    /x402 Payment \\$([0-9.]+)/i,\n    /Payment[:\\s]+\\$([0-9.]+)/i,\n    /charged \\$([0-9.]+)/i,\n    /\\$([0-9.]+)\\s*(?:USDC|usdc)/i,\n  ];\n\n  for (const pattern of patterns) {\n    const match = content.match(pattern);\n    if (match) {\n      const usdAmount = parseFloat(match[1]);\n      console.log(`Payment: $${usdAmount} USDC`);\n      break;\n    }\n  }\n});"
      },
      {
        "title": "Connection Events",
        "body": "sdk.on(\"connection:open\", () => {\n  console.log(\"WebSocket connected\");\n});\n\nsdk.on(\"disconnect\", () => {\n  console.log(\"Disconnected\");\n});\n\nsdk.on(\"ready\", () => {\n  console.log(\"SDK ready for messages\");\n});\n\nsdk.on(\"error\", (err) => {\n  // Handle rate limiting\n  const rateLimitMatch = err.message.match(/Please wait (\\d+)ms/);\n  if (rateLimitMatch) {\n    const waitMs = parseInt(rateLimitMatch[1], 10);\n    console.log(`Rate limited, wait ${waitMs}ms`);\n    return;\n  }\n\n  // Handle auth failures\n  if (err.message.includes(\"Invalid challenge\") ||\n      err.message.includes(\"authentication failed\")) {\n    console.log(\"Authentication failed, reconnecting...\");\n    return;\n  }\n\n  console.error(`SDK Error: ${err.message}`);\n});"
      },
      {
        "title": "Complete Example: Base Network Agent Interaction",
        "body": "import \"dotenv/config\";\nimport { TeneoSDK } from \"@teneo-protocol/sdk\";\n\n// Configuration\nconst BASE_USDC = \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\";\nconst BASE_NETWORK = \"eip155:8453\";\n\nasync function main() {\n  // Initialize SDK with Base payment config\n  const sdk = new TeneoSDK({\n    wsUrl: \"wss://backend.developer.chatroom.teneo-protocol.ai/ws\",\n    privateKey: process.env.PRIVATE_KEY!,\n    logLevel: \"info\",\n    maxReconnectAttempts: 10,\n    paymentNetwork: BASE_NETWORK,\n    paymentAsset: BASE_USDC,\n  });\n\n  // Track payments\n  let totalSpent = 0;\n\n  sdk.on(\"agent:response\", (data) => {\n    const content = data.humanized || data.content || \"\";\n\n    // Detect x402 payment\n    const match = content.match(/\\$([0-9.]+)/);\n    if (match) {\n      const amount = parseFloat(match[1]);\n      if (amount > 0 && amount < 1) { // Sanity check\n        totalSpent += amount;\n        console.log(`Payment: $${amount} | Total: $${totalSpent.toFixed(4)}`);\n      }\n    }\n  });\n\n  // Connect with retry logic\n  for (let attempt = 1; attempt <= 5; attempt++) {\n    try {\n      await sdk.connect();\n      console.log(\"Connected!\");\n      break;\n    } catch (err: any) {\n      // Handle rate limiting\n      const rateLimitMatch = err.message?.match(/Please wait (\\d+)ms/);\n      if (rateLimitMatch) {\n        const waitMs = parseInt(rateLimitMatch[1], 10) + 100;\n        console.log(`Rate limited, waiting ${waitMs}ms...`);\n        await sleep(waitMs);\n        continue;\n      }\n      throw err;\n    }\n  }\n\n  // Get wallet address\n  const authState = sdk.getAuthState();\n  console.log(`Wallet: ${authState.walletAddress}`);\n\n  // Find a room (prefer private rooms)\n  const rooms = sdk.getRooms();\n  let selectedRoom = rooms.find(r => !r.is_public) || rooms[0];\n\n  if (selectedRoom?.is_public) {\n    await sdk.subscribeToRoom(selectedRoom.id);\n  }\n\n  console.log(`Using room: ${selectedRoom?.name || selectedRoom?.id}`);\n\n  // Discover available agents\n  const agents = await sdk.listAgents();\n  console.log(`\\nAvailable agents (${agents.length}):`);\n  for (const agent of agents.slice(0, 5)) {\n    console.log(`  - @${agent.handle}: ${agent.name}`);\n  }\n\n  // Ensure agent is in room (if we own it)\n  if (selectedRoom?.is_owner) {\n    try {\n      await sdk.addAgentToRoom(selectedRoom.id, \"x-agent-enterprise-v2\");\n      console.log(\"Agent invited to room\");\n    } catch (e) {\n      // Agent may already be in room\n    }\n  }\n\n  // Send command to X agent\n  console.log(\"\\nSending request to @x-agent-enterprise-v2...\");\n\n  const response = await sdk.sendMessage(\n    \"@x-agent-enterprise-v2 user @VitalikButerin\",\n    {\n      waitForResponse: true,\n      timeout: 60000,\n      format: \"both\",\n      room: selectedRoom?.id,\n    }\n  );\n\n  console.log(\"\\nResponse:\");\n  console.log(response.humanized || response.content);\n\n  // Cleanup\n  sdk.disconnect();\n  console.log(`\\nTotal spent: $${totalSpent.toFixed(4)} USDC`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nmain().catch(console.error);"
      },
      {
        "title": "Connection Errors",
        "body": "async function connectWithRetry(sdk: TeneoSDK, maxAttempts = 10): Promise<void> {\n  for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n    try {\n      await sdk.connect();\n      return;\n    } catch (err: any) {\n      const msg = err?.message || String(err);\n\n      // Rate limiting - wait and retry\n      const rateLimitMatch = msg.match(/Please wait (\\d+)ms/);\n      if (rateLimitMatch) {\n        const waitMs = parseInt(rateLimitMatch[1], 10) + 100;\n        await sleep(waitMs);\n        continue;\n      }\n\n      // Auth errors - exponential backoff\n      if (msg.includes(\"Invalid challenge\") ||\n          msg.includes(\"authentication failed\")) {\n        const backoff = Math.min(5000 * Math.pow(2, attempt - 1), 60000);\n        await sleep(backoff);\n        continue;\n      }\n\n      // Other errors - shorter retry\n      if (attempt < maxAttempts) {\n        await sleep(3000 * attempt);\n        continue;\n      }\n\n      throw err;\n    }\n  }\n}"
      },
      {
        "title": "Payment Errors",
        "body": "try {\n  const response = await sdk.sendMessage(command, options);\n  // Handle success\n} catch (err: any) {\n  if (err.message.includes(\"Payment verification failed\")) {\n    // Insufficient USDC balance - need to fund wallet\n    console.log(\"Payment failed - check USDC balance\");\n  } else if (err.message.includes(\"payment\")) {\n    // Other payment issue\n    console.log(\"Payment error:\", err.message);\n  }\n}"
      },
      {
        "title": "Multi-Network Support",
        "body": "Switch between networks by creating SDK instances with different payment configs:\n\nconst NETWORKS = {\n  base: {\n    paymentNetwork: \"eip155:8453\",\n    paymentAsset: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n  },\n  peaq: {\n    paymentNetwork: \"eip155:3338\",\n    paymentAsset: \"0xbbA60da06c2c5424f03f7434542280FCAd453d10\",\n  },\n  avax: {\n    paymentNetwork: \"eip155:43114\",\n    paymentAsset: \"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E\",\n  },\n};\n\nfunction createSDK(network: keyof typeof NETWORKS, privateKey: string): TeneoSDK {\n  const config = NETWORKS[network];\n  return new TeneoSDK({\n    wsUrl: \"wss://backend.developer.chatroom.teneo-protocol.ai/ws\",\n    privateKey,\n    paymentNetwork: config.paymentNetwork,\n    paymentAsset: config.paymentAsset,\n  });\n}"
      },
      {
        "title": "Environment Variables",
        "body": "Typical .env configuration:\n\n# Required\nPRIVATE_KEY=0x...\n\n# Optional\nWS_URL=wss://backend.developer.chatroom.teneo-protocol.ai/ws\nROOM=my-room-name\n\n# Network-specific RPC URLs (for balance checks)\nBASE_RPC_URL=https://mainnet.base.org\nPEAQ_RPC_URL=https://peaq.api.onfinality.io/public\nAVAX_RPC_URL=https://api.avax.network/ext/bc/C/rpc"
      },
      {
        "title": "TypeScript Types",
        "body": "interface SDKConfig {\n  wsUrl: string;\n  privateKey: string;\n  logLevel?: \"silent\" | \"debug\" | \"info\" | \"warn\" | \"error\";\n  maxReconnectAttempts?: number;\n  paymentNetwork?: string;  // CAIP-2 format: \"eip155:chainId\"\n  paymentAsset?: string;    // USDC contract address\n}\n\ninterface Room {\n  id: string;\n  name: string;\n  is_public?: boolean;\n  is_owner?: boolean;\n}\n\ninterface Agent {\n  agent_id: string;\n  name: string;\n  handle: string;\n  description?: string;\n  price_per_request?: number;\n}\n\ninterface AgentResponse {\n  taskId: string;\n  agentId: string;\n  agentName?: string;\n  content: string;\n  success: boolean;\n  error?: string;\n  humanized?: string;\n}\n\ninterface MessageOptions {\n  waitForResponse?: boolean;\n  timeout?: number;\n  format?: \"raw\" | \"humanized\" | \"both\";\n  room?: string;\n}\n\ninterface AuthState {\n  walletAddress?: string;\n}"
      },
      {
        "title": "Tips",
        "body": "Always check USDC balance before sending paid requests\nUse private rooms when possible - no subscription needed\nHandle rate limits gracefully - the SDK enforces connection limits\nSet appropriate timeouts - agent responses can take 30-60 seconds\nPrefer Base network for lowest transaction fees\nDisconnect cleanly to avoid orphaned WebSocket connections\nDiscover agents first - use listAgents() to find available agents before inviting"
      }
    ],
    "body": "Teneo SDK Skill\nOverview\n\nThe Teneo SDK (@teneo-protocol/sdk) enables connection to AI agents on the Teneo Protocol platform. It provides:\n\nWebSocket-based real-time communication with AI agents\nWallet-based authentication using Ethereum private keys\nRoom management (private/public rooms, agent invitations)\nx402 micropayment protocol for paid agent interactions\nMulti-chain payment support (Base, Peaq, Avalanche)\nInstallation\nnpm install @teneo-protocol/sdk\n# or\npnpm add @teneo-protocol/sdk\n\nCore Concepts\nRooms\n\nRooms are communication channels where users interact with AI agents:\n\nPrivate rooms: Auto-available after authentication, no subscription needed\nPublic rooms: Require explicit subscription via subscribeToRoom()\nRoom ownership determines ability to invite agents\nAgents\n\nAI agents are identified by their @handle (e.g., @x-agent-enterprise-v2). Agents can be:\n\nDiscovered via listAgents() or searchAgents()\nInvited to private rooms by room owners\nSome require x402 payments for each interaction\nx402 Payment Protocol\n\nMicropayments for agent interactions using USDC on supported chains:\n\nBase (chain ID: 8453) - Recommended for low fees\nPeaq (chain ID: 3338)\nAvalanche (chain ID: 43114)\n\nPayment amounts are typically $0.01 - $0.10 per request.\n\nAuthentication & Connection\nimport { TeneoSDK } from \"@teneo-protocol/sdk\";\n\nconst sdk = new TeneoSDK({\n  wsUrl: \"wss://backend.developer.chatroom.teneo-protocol.ai/ws\",\n  privateKey: \"0x...\", // Ethereum private key\n  logLevel: \"silent\", // or \"debug\", \"info\", \"warn\", \"error\"\n  maxReconnectAttempts: 30,\n\n  // Payment configuration (required for paid agents)\n  paymentNetwork: \"eip155:8453\", // Base network in CAIP-2 format\n  paymentAsset: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", // Base USDC\n});\n\n// Connect (handles WebSocket + wallet signature auth)\nawait sdk.connect();\n\n// Get authenticated wallet address\nconst authState = sdk.getAuthState();\nconsole.log(`Authenticated as: ${authState.walletAddress}`);\n\n// Check connection status\nif (sdk.isConnected) {\n  console.log(\"Connected!\");\n}\n\n// Disconnect when done\nsdk.disconnect();\n\nPayment Network Configuration\n\nUse CAIP-2 format for paymentNetwork:\n\nNetwork\tCAIP-2 ID\tChain ID\tUSDC Contract\nBase\teip155:8453\t8453\t0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\nPeaq\teip155:3338\t3338\t0xbbA60da06c2c5424f03f7434542280FCAd453d10\nAvalanche\teip155:43114\t43114\t0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E\nRoom Management\nDiscovering Rooms\n// Get all rooms available to this wallet (sync - cached after connect)\nconst rooms = sdk.getRooms();\n\nfor (const room of rooms) {\n  console.log(`Room: ${room.name} [${room.id}]`);\n  console.log(`  Public: ${room.is_public}`);\n  console.log(`  Owner: ${room.is_owner}`);\n}\n\nSubscribing to Rooms\n// Private rooms: auto-available after auth, no subscription needed\n// Public rooms: require explicit subscription\n\nconst publicRoom = rooms.find(r => r.is_public);\nif (publicRoom) {\n  await sdk.subscribeToRoom(publicRoom.id);\n}\n\n// Check subscribed rooms\nconst subscribedRooms = sdk.getSubscribedRooms();\nconsole.log(`Subscribed to: ${subscribedRooms.join(\", \")}`);\n\nAgent Discovery & Invitation\nFinding Available Agents\n// List all available agents on the platform\nconst agents = await sdk.listAgents();\n\nfor (const agent of agents) {\n  console.log(`Agent: ${agent.name} (@${agent.handle})`);\n  console.log(`  ID: ${agent.agent_id}`);\n  console.log(`  Description: ${agent.description}`);\n  console.log(`  Price: $${agent.price_per_request || 0}`);\n}\n\n// Search for agents by name or keyword\nconst results = await sdk.searchAgents(\"twitter\");\nconsole.log(`Found ${results.length} agents matching \"twitter\"`);\n\nListing Agents in a Room\n// Get agents currently in a specific room\nconst roomAgents = await sdk.listRoomAgents(roomId);\n\nfor (const agent of roomAgents) {\n  console.log(`  - ${agent.name} (${agent.agent_id})`);\n}\n\nInviting Agents to Rooms\n\nOnly room owners can invite agents:\n\n// First, find the agent you want to invite\nconst agents = await sdk.listAgents();\nconst xAgent = agents.find(a => a.handle === \"x-agent-enterprise-v2\");\n\nif (xAgent) {\n  // Add agent to your room by their agent_id\n  await sdk.addAgentToRoom(roomId, xAgent.agent_id);\n  console.log(`Invited ${xAgent.name} to room`);\n}\n\n// Or invite directly by known agent ID\nawait sdk.addAgentToRoom(roomId, \"x-agent-enterprise-v2\");\n\nEnsuring Required Agents Are in Room\nasync function ensureAgentsInRoom(\n  sdk: TeneoSDK,\n  roomId: string,\n  requiredAgentIds: string[]\n): Promise<void> {\n  // Get agents currently in the room\n  const roomAgents = await sdk.listRoomAgents(roomId);\n  const existingIds = new Set(roomAgents.map(a => a.agent_id?.toLowerCase()));\n\n  // Find missing agents\n  const missing = requiredAgentIds.filter(\n    id => !existingIds.has(id.toLowerCase())\n  );\n\n  // Invite missing agents\n  for (const agentId of missing) {\n    try {\n      await sdk.addAgentToRoom(roomId, agentId);\n      console.log(`Invited agent \"${agentId}\" to room`);\n    } catch (err: any) {\n      console.warn(`Failed to invite \"${agentId}\": ${err.message}`);\n    }\n  }\n}\n\n// Usage\nawait ensureAgentsInRoom(sdk, roomId, [\n  \"x-agent-enterprise-v2\",\n  \"another-agent-id\",\n]);\n\nSending Messages to Agents\nBasic Message\nconst response = await sdk.sendMessage(\"@x-agent-enterprise-v2 user @elonmusk\", {\n  waitForResponse: true,\n  timeout: 60000, // 60 seconds\n  format: \"both\", // Get both raw content and humanized version\n});\n\nconsole.log(response.humanized || response.content);\n\nMessage with Room Context\nconst response = await sdk.sendMessage(\"@x-agent-enterprise-v2 post_stats 123456\", {\n  waitForResponse: true,\n  timeout: 60000,\n  format: \"both\",\n  room: \"room-id-here\", // Specify target room\n});\n\nCommon Agent Commands\n// X/Twitter agent - Get user profile stats\n\"@x-agent-enterprise-v2 user @username\"\n\n// X/Twitter agent - Get post/tweet stats\n\"@x-agent-enterprise-v2 post_stats 1234567890123456789\"\n\nEvent Handling\nAgent Responses\nsdk.on(\"agent:response\", (data) => {\n  console.log(`Agent: ${data.agentName || data.agentId}`);\n  console.log(`Success: ${data.success}`);\n  console.log(`Content: ${data.humanized || data.content}`);\n\n  if (data.error) {\n    console.error(`Error: ${data.error}`);\n  }\n});\n\nPayment Detection\n\nx402 payments are reflected in agent responses. Parse the response to detect payment amounts:\n\nsdk.on(\"agent:response\", (data) => {\n  const content = data.humanized || data.content || \"\";\n\n  // Common patterns for payment detection\n  const patterns = [\n    /x402 Payment \\$([0-9.]+)/i,\n    /Payment[:\\s]+\\$([0-9.]+)/i,\n    /charged \\$([0-9.]+)/i,\n    /\\$([0-9.]+)\\s*(?:USDC|usdc)/i,\n  ];\n\n  for (const pattern of patterns) {\n    const match = content.match(pattern);\n    if (match) {\n      const usdAmount = parseFloat(match[1]);\n      console.log(`Payment: $${usdAmount} USDC`);\n      break;\n    }\n  }\n});\n\nConnection Events\nsdk.on(\"connection:open\", () => {\n  console.log(\"WebSocket connected\");\n});\n\nsdk.on(\"disconnect\", () => {\n  console.log(\"Disconnected\");\n});\n\nsdk.on(\"ready\", () => {\n  console.log(\"SDK ready for messages\");\n});\n\nsdk.on(\"error\", (err) => {\n  // Handle rate limiting\n  const rateLimitMatch = err.message.match(/Please wait (\\d+)ms/);\n  if (rateLimitMatch) {\n    const waitMs = parseInt(rateLimitMatch[1], 10);\n    console.log(`Rate limited, wait ${waitMs}ms`);\n    return;\n  }\n\n  // Handle auth failures\n  if (err.message.includes(\"Invalid challenge\") ||\n      err.message.includes(\"authentication failed\")) {\n    console.log(\"Authentication failed, reconnecting...\");\n    return;\n  }\n\n  console.error(`SDK Error: ${err.message}`);\n});\n\nComplete Example: Base Network Agent Interaction\nimport \"dotenv/config\";\nimport { TeneoSDK } from \"@teneo-protocol/sdk\";\n\n// Configuration\nconst BASE_USDC = \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\";\nconst BASE_NETWORK = \"eip155:8453\";\n\nasync function main() {\n  // Initialize SDK with Base payment config\n  const sdk = new TeneoSDK({\n    wsUrl: \"wss://backend.developer.chatroom.teneo-protocol.ai/ws\",\n    privateKey: process.env.PRIVATE_KEY!,\n    logLevel: \"info\",\n    maxReconnectAttempts: 10,\n    paymentNetwork: BASE_NETWORK,\n    paymentAsset: BASE_USDC,\n  });\n\n  // Track payments\n  let totalSpent = 0;\n\n  sdk.on(\"agent:response\", (data) => {\n    const content = data.humanized || data.content || \"\";\n\n    // Detect x402 payment\n    const match = content.match(/\\$([0-9.]+)/);\n    if (match) {\n      const amount = parseFloat(match[1]);\n      if (amount > 0 && amount < 1) { // Sanity check\n        totalSpent += amount;\n        console.log(`Payment: $${amount} | Total: $${totalSpent.toFixed(4)}`);\n      }\n    }\n  });\n\n  // Connect with retry logic\n  for (let attempt = 1; attempt <= 5; attempt++) {\n    try {\n      await sdk.connect();\n      console.log(\"Connected!\");\n      break;\n    } catch (err: any) {\n      // Handle rate limiting\n      const rateLimitMatch = err.message?.match(/Please wait (\\d+)ms/);\n      if (rateLimitMatch) {\n        const waitMs = parseInt(rateLimitMatch[1], 10) + 100;\n        console.log(`Rate limited, waiting ${waitMs}ms...`);\n        await sleep(waitMs);\n        continue;\n      }\n      throw err;\n    }\n  }\n\n  // Get wallet address\n  const authState = sdk.getAuthState();\n  console.log(`Wallet: ${authState.walletAddress}`);\n\n  // Find a room (prefer private rooms)\n  const rooms = sdk.getRooms();\n  let selectedRoom = rooms.find(r => !r.is_public) || rooms[0];\n\n  if (selectedRoom?.is_public) {\n    await sdk.subscribeToRoom(selectedRoom.id);\n  }\n\n  console.log(`Using room: ${selectedRoom?.name || selectedRoom?.id}`);\n\n  // Discover available agents\n  const agents = await sdk.listAgents();\n  console.log(`\\nAvailable agents (${agents.length}):`);\n  for (const agent of agents.slice(0, 5)) {\n    console.log(`  - @${agent.handle}: ${agent.name}`);\n  }\n\n  // Ensure agent is in room (if we own it)\n  if (selectedRoom?.is_owner) {\n    try {\n      await sdk.addAgentToRoom(selectedRoom.id, \"x-agent-enterprise-v2\");\n      console.log(\"Agent invited to room\");\n    } catch (e) {\n      // Agent may already be in room\n    }\n  }\n\n  // Send command to X agent\n  console.log(\"\\nSending request to @x-agent-enterprise-v2...\");\n\n  const response = await sdk.sendMessage(\n    \"@x-agent-enterprise-v2 user @VitalikButerin\",\n    {\n      waitForResponse: true,\n      timeout: 60000,\n      format: \"both\",\n      room: selectedRoom?.id,\n    }\n  );\n\n  console.log(\"\\nResponse:\");\n  console.log(response.humanized || response.content);\n\n  // Cleanup\n  sdk.disconnect();\n  console.log(`\\nTotal spent: $${totalSpent.toFixed(4)} USDC`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nmain().catch(console.error);\n\nError Handling Best Practices\nConnection Errors\nasync function connectWithRetry(sdk: TeneoSDK, maxAttempts = 10): Promise<void> {\n  for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n    try {\n      await sdk.connect();\n      return;\n    } catch (err: any) {\n      const msg = err?.message || String(err);\n\n      // Rate limiting - wait and retry\n      const rateLimitMatch = msg.match(/Please wait (\\d+)ms/);\n      if (rateLimitMatch) {\n        const waitMs = parseInt(rateLimitMatch[1], 10) + 100;\n        await sleep(waitMs);\n        continue;\n      }\n\n      // Auth errors - exponential backoff\n      if (msg.includes(\"Invalid challenge\") ||\n          msg.includes(\"authentication failed\")) {\n        const backoff = Math.min(5000 * Math.pow(2, attempt - 1), 60000);\n        await sleep(backoff);\n        continue;\n      }\n\n      // Other errors - shorter retry\n      if (attempt < maxAttempts) {\n        await sleep(3000 * attempt);\n        continue;\n      }\n\n      throw err;\n    }\n  }\n}\n\nPayment Errors\ntry {\n  const response = await sdk.sendMessage(command, options);\n  // Handle success\n} catch (err: any) {\n  if (err.message.includes(\"Payment verification failed\")) {\n    // Insufficient USDC balance - need to fund wallet\n    console.log(\"Payment failed - check USDC balance\");\n  } else if (err.message.includes(\"payment\")) {\n    // Other payment issue\n    console.log(\"Payment error:\", err.message);\n  }\n}\n\nMulti-Network Support\n\nSwitch between networks by creating SDK instances with different payment configs:\n\nconst NETWORKS = {\n  base: {\n    paymentNetwork: \"eip155:8453\",\n    paymentAsset: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n  },\n  peaq: {\n    paymentNetwork: \"eip155:3338\",\n    paymentAsset: \"0xbbA60da06c2c5424f03f7434542280FCAd453d10\",\n  },\n  avax: {\n    paymentNetwork: \"eip155:43114\",\n    paymentAsset: \"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E\",\n  },\n};\n\nfunction createSDK(network: keyof typeof NETWORKS, privateKey: string): TeneoSDK {\n  const config = NETWORKS[network];\n  return new TeneoSDK({\n    wsUrl: \"wss://backend.developer.chatroom.teneo-protocol.ai/ws\",\n    privateKey,\n    paymentNetwork: config.paymentNetwork,\n    paymentAsset: config.paymentAsset,\n  });\n}\n\nEnvironment Variables\n\nTypical .env configuration:\n\n# Required\nPRIVATE_KEY=0x...\n\n# Optional\nWS_URL=wss://backend.developer.chatroom.teneo-protocol.ai/ws\nROOM=my-room-name\n\n# Network-specific RPC URLs (for balance checks)\nBASE_RPC_URL=https://mainnet.base.org\nPEAQ_RPC_URL=https://peaq.api.onfinality.io/public\nAVAX_RPC_URL=https://api.avax.network/ext/bc/C/rpc\n\nTypeScript Types\ninterface SDKConfig {\n  wsUrl: string;\n  privateKey: string;\n  logLevel?: \"silent\" | \"debug\" | \"info\" | \"warn\" | \"error\";\n  maxReconnectAttempts?: number;\n  paymentNetwork?: string;  // CAIP-2 format: \"eip155:chainId\"\n  paymentAsset?: string;    // USDC contract address\n}\n\ninterface Room {\n  id: string;\n  name: string;\n  is_public?: boolean;\n  is_owner?: boolean;\n}\n\ninterface Agent {\n  agent_id: string;\n  name: string;\n  handle: string;\n  description?: string;\n  price_per_request?: number;\n}\n\ninterface AgentResponse {\n  taskId: string;\n  agentId: string;\n  agentName?: string;\n  content: string;\n  success: boolean;\n  error?: string;\n  humanized?: string;\n}\n\ninterface MessageOptions {\n  waitForResponse?: boolean;\n  timeout?: number;\n  format?: \"raw\" | \"humanized\" | \"both\";\n  room?: string;\n}\n\ninterface AuthState {\n  walletAddress?: string;\n}\n\nTips\nAlways check USDC balance before sending paid requests\nUse private rooms when possible - no subscription needed\nHandle rate limits gracefully - the SDK enforces connection limits\nSet appropriate timeouts - agent responses can take 30-60 seconds\nPrefer Base network for lowest transaction fees\nDisconnect cleanly to avoid orphaned WebSocket connections\nDiscover agents first - use listAgents() to find available agents before inviting"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/teneoprotocoldev/teneo-agent-sdk",
    "publisherUrl": "https://clawhub.ai/teneoprotocoldev/teneo-agent-sdk",
    "owner": "teneoprotocoldev",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "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"
  }
}