From 0d1ae7b7c55dbb149550a5f711d8603390c993ab Mon Sep 17 00:00:00 2001 From: plagtech Date: Sun, 10 May 2026 15:55:02 -0700 Subject: [PATCH] Add Spraay x402 partner notebook: payment-enabled AI agents with Oracle AI Database --- README.md | 6 +- partners/spraay/README.md | 40 + .../spraay_x402_payment_agents_oracle.ipynb | 833 ++++++++++++++++++ 3 files changed, 876 insertions(+), 3 deletions(-) create mode 100644 partners/spraay/README.md create mode 100644 partners/spraay/spraay_x402_payment_agents_oracle.ipynb diff --git a/README.md b/README.md index c428994f..21c28b3c 100644 --- a/README.md +++ b/README.md @@ -83,9 +83,9 @@ Hands-on workshops and guided learning experiences that take developers from fun Notebooks and apps contributed by partners in the AI ecosystem. AI Developers can use these resources to understand how to use Oracle AI Database and OCI alongside tools such as LangChain, Galileo, LlamaIndex, and other popular AI/ML frameworks and platforms. -| Name | Description | Stack | Link | -| ------------- | ------------------------------------------------ | ----- | ---- | -| _Coming soon_ | Partner-contributed resources will be added here | - | - | +| Name | Description | Stack | Link | +| --- | --- | --- | --- | +| spraay_x402_payment_agents_oracle | Build payment-enabled AI agents with Oracle AI Database and Spraay x402 Gateway — cost-aware agents that pay for premium inference via USDC micropayments | Oracle AI Database, langchain-oracledb, LangChain, Spraay x402 | [Open Notebook](partners/spraay/spraay_x402_payment_agents_oracle.ipynb) | ## Getting Started diff --git a/partners/spraay/README.md b/partners/spraay/README.md new file mode 100644 index 00000000..e170267a --- /dev/null +++ b/partners/spraay/README.md @@ -0,0 +1,40 @@ +# Spraay Protocol — Payment-Enabled AI Agents + +## About Spraay + +[Spraay Protocol](https://spraay.app) is a multi-chain batch payment protocol deployed across **15 blockchains** and an [x402](https://www.x402.org) payment gateway with **88 pay-per-call endpoints** across **19 categories**. The [Spraay x402 Gateway](https://gateway.spraay.app) enables AI agents to pay for premium services — inference (200+ models), Bittensor decentralized AI, search/RAG, compute, storage, robotics, and more — using USDC micropayments over standard HTTP. No API keys required. + +Spraay's batch payment tool is an official community tool in [Google's Agent Development Kit (ADK)](https://github.com/google/adk-python-community) — merged as PR #95. + +## Notebook + +| Name | Description | Stack | +| --- | --- | --- | +| `spraay_x402_payment_agents_oracle.ipynb` | Build a cost-aware AI agent that retrieves context from Oracle AI Database and pays for premium inference via Spraay's x402 gateway | Oracle AI Database, langchain-oracledb, LangChain, Spraay x402, httpx | + +## What You'll Learn + +- How to combine Oracle AI Vector Search with paid external services in a single agent loop +- Implementing the x402 payment protocol for autonomous machine-to-machine payments +- Building cost-aware agents that prefer free resources before escalating to paid ones +- Choosing between centralized AI (200+ models) and decentralized Bittensor inference (43+ models) +- Using Oracle's hybrid search (vector + SQL) for agent memory and context retrieval + +## Prerequisites + +- Python 3.9+ +- Oracle Database 23ai or Oracle Autonomous Database with AI Vector Search +- Ethereum wallet with USDC on Base +- OpenAI API key + +## Links + +- [Spraay Protocol](https://spraay.app) +- [Spraay x402 Gateway Docs](https://docs.spraay.app) — 88 endpoints, 19 categories +- [Gateway](https://gateway.spraay.app) +- [MCP Server](https://smithery.ai/server/@plagtech/spraay-x402-mcp) — 60 tools for Claude Desktop, Cursor, Cline +- [Google ADK Community Tool](https://github.com/google/adk-python-community) — PR #95 +- [x402 Protocol](https://www.x402.org) +- [GitHub](https://github.com/plagtech) +- [Twitter](https://twitter.com/Spraay_app) +- [Contract on Base](https://basescan.org/address/0x1646452F98E36A3c9Cfc3eDD8868221E207B5eEC) diff --git a/partners/spraay/spraay_x402_payment_agents_oracle.ipynb b/partners/spraay/spraay_x402_payment_agents_oracle.ipynb new file mode 100644 index 00000000..08b608b0 --- /dev/null +++ b/partners/spraay/spraay_x402_payment_agents_oracle.ipynb @@ -0,0 +1,833 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b532bea1", + "metadata": {}, + "source": [ + "# Building Payment-Enabled AI Agents with Oracle AI Database & Spraay x402\n", + "\n", + "**Partner Notebook** | [Spraay Protocol](https://spraay.app) | [Oracle AI Database](https://www.oracle.com/database/ai/)\n", + "\n", + "---\n", + "\n", + "## Overview\n", + "\n", + "AI agents can reason, retrieve context, and generate responses — but they can't **pay for resources** autonomously. As agents move toward production, they need the ability to pay for premium inference, external data, and services without human intervention.\n", + "\n", + "This notebook demonstrates how to combine:\n", + "- **Oracle AI Database** — vector storage, semantic search, and agent memory\n", + "- **Spraay x402 Gateway** — autonomous USDC micropayments over HTTP (the [x402 protocol](https://www.x402.org))\n", + "- **LangChain** — agent orchestration and tool use\n", + "\n", + "The result is an agent that retrieves context from Oracle's vector store, decides when it needs premium AI inference, and **pays for it automatically** via Spraay's x402 gateway — all in a single agentic loop.\n", + "\n", + "### What is x402?\n", + "\n", + "x402 is an open payment protocol built on HTTP status code 402 (\"Payment Required\"). When an agent requests a paid resource, the server responds with a `402` status and payment requirements. The agent's payment middleware automatically signs a USDC payment on Base and retries the request with a payment proof header. No API keys, no subscriptions — just pay-per-request.\n", + "\n", + "### What is Spraay?\n", + "\n", + "[Spraay Protocol](https://spraay.app) is a multi-chain batch payment protocol deployed across **15 blockchains** (Base, Ethereum, Bitcoin, Arbitrum, Polygon, BNB Chain, Avalanche, Unichain, Plasma, BOB, Bittensor, Solana, Stacks, Stellar, and XRP Ledger). The [Spraay x402 Gateway](https://gateway.spraay.app) exposes **88 pay-per-call endpoints** across **19 categories** — AI inference (200+ models), Bittensor decentralized AI, search/RAG, batch payments, escrow, RPC, IPFS storage, robotics (RTP), supply chain (SCTP), agent wallets (ERC-4337), and more.\n", + "\n", + "Spraay's batch payment tool is an official community tool in [Google's Agent Development Kit (ADK)](https://github.com/google/adk-python-community) — merged as PR #95.\n", + "\n", + "### Architecture\n", + "\n", + "```\n", + "User Query\n", + " │\n", + " ▼\n", + "┌─────────────────────┐\n", + "│ LangChain Agent │\n", + "│ (Orchestrator) │\n", + "└────────┬────────────┘\n", + " │\n", + " ┌────┴────┐\n", + " │ │\n", + " ▼ ▼\n", + "┌────────┐ ┌──────────────────┐\n", + "│ Oracle │ │ Spraay x402 │\n", + "│ AI DB │ │ Gateway │\n", + "│ (RAG) │ │ (Paid Inference)│\n", + "└────────┘ └──────────────────┘\n", + " │ │\n", + " ▼ ▼\n", + " Context Premium Response\n", + " │ │\n", + " └──────┬───────┘\n", + " ▼\n", + " Final Answer\n", + "```\n", + "\n", + "### Prerequisites\n", + "\n", + "- Python 3.9+\n", + "- Oracle Database 23ai (or Oracle Autonomous Database with AI Vector Search)\n", + "- An Ethereum wallet with USDC on Base (for x402 payments)\n", + "- OpenAI API key (for embeddings)\n" + ] + }, + { + "cell_type": "markdown", + "id": "35b1b209", + "metadata": {}, + "source": [ + "## 1. Environment Setup\n", + "\n", + "Install the required packages. We use `langchain-oracledb` for Oracle AI Database integration, `httpx` for HTTP calls to the Spraay gateway, and standard crypto libraries for x402 payment signing.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23d33d32", + "metadata": {}, + "outputs": [], + "source": [ + "# Install dependencies\n", + "%pip install --quiet \\\n", + " langchain \\\n", + " langchain-openai \\\n", + " langchain-community \\\n", + " langchain-oracledb \\\n", + " oracledb \\\n", + " httpx \\\n", + " eth-account \\\n", + " python-dotenv" + ] + }, + { + "cell_type": "markdown", + "id": "2aeb43e3", + "metadata": {}, + "source": [ + "## 2. Configuration\n", + "\n", + "Set up your environment variables. You'll need:\n", + "- Oracle Database connection details\n", + "- OpenAI API key (for embeddings)\n", + "- An Ethereum private key with USDC on Base (for x402 payments)\n", + "\n", + "> ⚠️ **Security**: Never commit private keys to version control. Use environment variables or a `.env` file.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "57db076b", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from dotenv import load_dotenv\n", + "\n", + "load_dotenv()\n", + "\n", + "# Oracle Database Configuration\n", + "ORACLE_USER = os.getenv(\"ORACLE_USER\", \"your_user\")\n", + "ORACLE_PASSWORD = os.getenv(\"ORACLE_PASSWORD\", \"your_password\")\n", + "ORACLE_DSN = os.getenv(\"ORACLE_DSN\", \"your_host:1521/your_service\")\n", + "\n", + "# OpenAI (for embeddings)\n", + "OPENAI_API_KEY = os.getenv(\"OPENAI_API_KEY\")\n", + "\n", + "# Spraay x402 Gateway\n", + "SPRAAY_GATEWAY_URL = \"https://gateway.spraay.app\"\n", + "\n", + "# Ethereum wallet for x402 payments (must hold USDC on Base)\n", + "WALLET_PRIVATE_KEY = os.getenv(\"WALLET_PRIVATE_KEY\")\n", + "\n", + "print(\"✅ Configuration loaded\")" + ] + }, + { + "cell_type": "markdown", + "id": "0ef0224f", + "metadata": {}, + "source": [ + "## 3. Connect to Oracle AI Database\n", + "\n", + "Establish a connection to Oracle Database and set up the vector store for RAG. Oracle AI Database supports native vector search with `AI Vector Search`, making it ideal for agent memory and context retrieval.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d52c41c", + "metadata": {}, + "outputs": [], + "source": [ + "import oracledb\n", + "\n", + "# Connect to Oracle Database\n", + "connection = oracledb.connect(\n", + " user=ORACLE_USER,\n", + " password=ORACLE_PASSWORD,\n", + " dsn=ORACLE_DSN\n", + ")\n", + "\n", + "print(f\"✅ Connected to Oracle Database: {connection.version}\")" + ] + }, + { + "cell_type": "markdown", + "id": "355cf3d6", + "metadata": {}, + "source": [ + "## 4. Set Up Oracle Vector Store\n", + "\n", + "We'll create a vector table and populate it with sample documents. In production, this would contain your knowledge base — product docs, internal wikis, compliance data, etc.\n", + "\n", + "The Oracle vector store uses `langchain-oracledb` for native integration with LangChain's retrieval chain.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2d546db7", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_openai import OpenAIEmbeddings\n", + "from langchain_oracledb import OracleVS\n", + "from langchain_core.documents import Document\n", + "\n", + "# Initialize embeddings\n", + "embeddings = OpenAIEmbeddings(\n", + " model=\"text-embedding-3-small\",\n", + " openai_api_key=OPENAI_API_KEY\n", + ")\n", + "\n", + "# Sample knowledge base documents\n", + "# In production, load from your actual data sources\n", + "documents = [\n", + " Document(\n", + " page_content=\"Spraay Protocol is a multi-chain batch payment protocol deployed across 15 blockchains \"\n", + " \"including Base, Ethereum, Bitcoin, Arbitrum, Polygon, BNB Chain, Avalanche, Unichain, \"\n", + " \"Plasma, BOB, Bittensor, Solana, Stacks, Stellar, and XRP Ledger. It enables sending \"\n", + " \"payments to 200+ recipients in a single transaction, reducing gas costs by up to 80%.\",\n", + " metadata={\"source\": \"spraay_docs\", \"topic\": \"overview\"}\n", + " ),\n", + " Document(\n", + " page_content=\"The x402 payment protocol uses HTTP status code 402 (Payment Required) to enable \"\n", + " \"machine-to-machine payments. When a server returns a 402 response, the client's payment \"\n", + " \"middleware automatically handles USDC payment on Base mainnet and retries the request \"\n", + " \"with a payment proof in the X-PAYMENT header.\",\n", + " metadata={\"source\": \"x402_spec\", \"topic\": \"protocol\"}\n", + " ),\n", + " Document(\n", + " page_content=\"Oracle AI Vector Search enables semantic similarity search directly in the database. \"\n", + " \"Vectors can be stored alongside relational data, enabling hybrid queries that combine \"\n", + " \"traditional SQL filtering with vector similarity search in a single query.\",\n", + " metadata={\"source\": \"oracle_docs\", \"topic\": \"vector_search\"}\n", + " ),\n", + " Document(\n", + " page_content=\"AI agent payments solve the API key management problem. Instead of provisioning and \"\n", + " \"rotating API keys for each service, agents pay per-request with USDC micropayments. \"\n", + " \"This is more secure (no stored credentials) and more flexible (pay only for what you use).\",\n", + " metadata={\"source\": \"agent_payments\", \"topic\": \"benefits\"}\n", + " ),\n", + " Document(\n", + " page_content=\"The Spraay x402 Gateway provides 88 paid endpoints across 19 categories including \"\n", + " \"AI inference (200+ models), Bittensor decentralized AI (43+ models via SN64 Chutes AI), \"\n", + " \"search/RAG (Tavily-powered), batch payments, escrow, swaps, bridges, RPC (Alchemy), \"\n", + " \"IPFS storage (Pinata), robotics (RTP), supply chain (SCTP), and ERC-4337 agent wallets. \"\n", + " \"Each endpoint costs fractions of a cent in USDC per request.\",\n", + " metadata={\"source\": \"spraay_docs\", \"topic\": \"gateway_endpoints\"}\n", + " ),\n", + " Document(\n", + " page_content=\"Spraay's batch payment tool is an official community tool in Google's Agent Development \"\n", + " \"Kit (ADK), merged as PR #95 in google/adk-python-community. This means any Google ADK \"\n", + " \"agent can natively batch-send crypto payments via Spraay's smart contract on Base.\",\n", + " metadata={\"source\": \"spraay_docs\", \"topic\": \"google_adk\"}\n", + " ),\n", + "]\n", + "\n", + "# Create Oracle Vector Store\n", + "vector_store = OracleVS.from_documents(\n", + " documents,\n", + " embeddings,\n", + " client=connection,\n", + " table_name=\"SPRAAY_AGENT_KNOWLEDGE\",\n", + " distance_strategy=\"COSINE\"\n", + ")\n", + "\n", + "print(f\"✅ Oracle Vector Store created with {len(documents)} documents\")" + ] + }, + { + "cell_type": "markdown", + "id": "a05321fb", + "metadata": {}, + "source": [ + "## 5. Build the x402 Payment Client\n", + "\n", + "The x402 payment flow works like this:\n", + "\n", + "1. Agent makes an HTTP request to a paid endpoint\n", + "2. Server responds with `402 Payment Required` + payment requirements (price, recipient, token)\n", + "3. Client signs a USDC payment authorization on Base\n", + "4. Client retries the request with `X-PAYMENT` header containing the signed payment\n", + "5. Server verifies payment and returns the response\n", + "\n", + "We'll build a lightweight client that handles this flow automatically.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72266b69", + "metadata": {}, + "outputs": [], + "source": [ + "import httpx\n", + "import json\n", + "import time\n", + "from eth_account import Account\n", + "from eth_account.messages import encode_defunct\n", + "\n", + "class SpraayX402Client:\n", + " \"\"\"Client for making x402 payments to the Spraay Gateway.\n", + " \n", + " Gateway: https://gateway.spraay.app\n", + " Docs: https://docs.spraay.app\n", + " 88 endpoints across 19 categories, all payable with USDC on Base.\n", + " \"\"\"\n", + "\n", + " def __init__(self, gateway_url: str, private_key: str):\n", + " self.gateway_url = gateway_url.rstrip(\"/\")\n", + " self.account = Account.from_key(private_key)\n", + " self.client = httpx.Client(timeout=30.0)\n", + " self.payment_log = []\n", + "\n", + " def _sign_payment(self, payment_requirements: dict) -> str:\n", + " \"\"\"Sign a USDC payment authorization for x402.\"\"\"\n", + " # Extract payment details from 402 response\n", + " amount = payment_requirements.get(\"maxAmountRequired\", \"0\")\n", + " recipient = payment_requirements.get(\"resource\")\n", + " network = payment_requirements.get(\"network\", \"base\")\n", + "\n", + " # Create payment payload\n", + " payment = {\n", + " \"x402Version\": 1,\n", + " \"scheme\": \"exact\",\n", + " \"network\": network,\n", + " \"payload\": {\n", + " \"signature\": \"\",\n", + " \"authorization\": {\n", + " \"from\": self.account.address,\n", + " \"to\": recipient,\n", + " \"value\": amount,\n", + " \"validAfter\": 0,\n", + " \"validBefore\": int(time.time()) + 3600,\n", + " \"nonce\": hex(int(time.time() * 1000)),\n", + " }\n", + " }\n", + " }\n", + "\n", + " # Sign the authorization\n", + " message = json.dumps(payment[\"payload\"][\"authorization\"], sort_keys=True)\n", + " signed = self.account.sign_message(encode_defunct(text=message))\n", + " payment[\"payload\"][\"signature\"] = signed.signature.hex()\n", + "\n", + " return json.dumps(payment)\n", + "\n", + " def request(self, endpoint: str, method: str = \"GET\", **kwargs) -> dict:\n", + " \"\"\"Make an x402-enabled request to the Spraay Gateway.\"\"\"\n", + " url = f\"{self.gateway_url}{endpoint}\"\n", + "\n", + " # First attempt — may return 402\n", + " response = self.client.request(method, url, **kwargs)\n", + "\n", + " if response.status_code == 402:\n", + " # Parse payment requirements\n", + " requirements = response.json()\n", + " print(f\" 💰 Payment required: {requirements.get('maxAmountRequired', 'unknown')} USDC\")\n", + "\n", + " # Sign payment\n", + " payment_header = self._sign_payment(requirements)\n", + "\n", + " # Retry with payment\n", + " headers = kwargs.get(\"headers\", {})\n", + " headers[\"X-PAYMENT\"] = payment_header\n", + " kwargs[\"headers\"] = headers\n", + "\n", + " response = self.client.request(method, url, **kwargs)\n", + "\n", + " # Log the payment\n", + " self.payment_log.append({\n", + " \"endpoint\": endpoint,\n", + " \"amount\": requirements.get(\"maxAmountRequired\"),\n", + " \"timestamp\": time.time()\n", + " })\n", + "\n", + " if response.status_code == 200:\n", + " return response.json()\n", + " else:\n", + " return {\"error\": f\"Request failed with status {response.status_code}\"}\n", + "\n", + " def get_payment_summary(self) -> dict:\n", + " \"\"\"Get a summary of all payments made in this session.\"\"\"\n", + " total = sum(float(p.get(\"amount\", 0)) for p in self.payment_log)\n", + " return {\n", + " \"total_payments\": len(self.payment_log),\n", + " \"total_usdc_spent\": total,\n", + " \"payments\": self.payment_log\n", + " }\n", + "\n", + "\n", + "# Initialize the x402 client\n", + "x402_client = SpraayX402Client(\n", + " gateway_url=SPRAAY_GATEWAY_URL,\n", + " private_key=WALLET_PRIVATE_KEY\n", + ")\n", + "\n", + "print(f\"✅ x402 Client initialized\")\n", + "print(f\" Wallet: {x402_client.account.address}\")\n", + "print(f\" Gateway: {SPRAAY_GATEWAY_URL}\")" + ] + }, + { + "cell_type": "markdown", + "id": "5cbd059d", + "metadata": {}, + "source": [ + "## 6. Define Agent Tools\n", + "\n", + "Now we create LangChain tools that the agent can use:\n", + "\n", + "1. **`search_knowledge_base`** — Retrieves relevant context from Oracle AI Database (free)\n", + "2. **`spraay_ai_inference`** — Calls 200+ AI models via Spraay's x402 gateway ($0.04 USDC/request)\n", + "3. **`spraay_web_search`** — Searches the web via Tavily through Spraay ($0.02 USDC/request)\n", + "\n", + "The agent decides which tools to use based on the query. Free retrieval first, paid inference only when needed.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f6b0b6b", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_core.tools import tool\n", + "\n", + "@tool\n", + "def search_knowledge_base(query: str) -> str:\n", + " \"\"\"Search the Oracle AI Database vector store for relevant context.\n", + " Use this FIRST to check if the answer exists in our knowledge base.\n", + " This is a free operation — no payment required.\"\"\"\n", + "\n", + " results = vector_store.similarity_search(query, k=3)\n", + "\n", + " if not results:\n", + " return \"No relevant documents found in the knowledge base.\"\n", + "\n", + " context = \"\\n\\n\".join([\n", + " f\"[Source: {doc.metadata.get('source', 'unknown')}] {doc.page_content}\"\n", + " for doc in results\n", + " ])\n", + " return f\"Found {len(results)} relevant documents:\\n\\n{context}\"\n", + "\n", + "\n", + "@tool\n", + "def spraay_ai_inference(prompt: str) -> str:\n", + " \"\"\"Call a premium AI model via the Spraay x402 Gateway.\n", + " Costs $0.04 USDC per request. Uses /api/v1/chat/completions (200+ models).\n", + " Use ONLY when the knowledge base doesn't have the answer.\"\"\"\n", + "\n", + " print(f\" 🤖 Calling AI inference via Spraay x402 ($0.04 USDC)...\")\n", + " response = x402_client.request(\n", + " \"/api/v1/chat/completions\",\n", + " method=\"POST\",\n", + " json={\n", + " \"model\": \"gpt-4\",\n", + " \"messages\": [{\"role\": \"user\", \"content\": prompt}],\n", + " \"max_tokens\": 500\n", + " }\n", + " )\n", + "\n", + " if \"error\" in response:\n", + " return f\"Inference failed: {response['error']}\"\n", + "\n", + " return response.get(\"choices\", [{}])[0].get(\"message\", {}).get(\"content\", \"No response\")\n", + "\n", + "\n", + "@tool\n", + "def spraay_bittensor_inference(prompt: str) -> str:\n", + " \"\"\"Call decentralized AI via Bittensor through Spraay's x402 Gateway.\n", + " Costs $0.03 USDC per request. Uses /bittensor/v1/chat/completions.\n", + " OpenAI-compatible drop-in routed through Bittensor SN64 (Chutes AI).\n", + " 43+ models including DeepSeek, Qwen, Llama, Mistral.\"\"\"\n", + "\n", + " print(f\" 🧬 Calling Bittensor inference via Spraay x402 ($0.03 USDC)...\")\n", + " response = x402_client.request(\n", + " \"/bittensor/v1/chat/completions\",\n", + " method=\"POST\",\n", + " json={\n", + " \"model\": \"deepseek-ai/DeepSeek-V3-0324\",\n", + " \"messages\": [{\"role\": \"user\", \"content\": prompt}],\n", + " \"max_tokens\": 500\n", + " }\n", + " )\n", + "\n", + " if \"error\" in response:\n", + " return f\"Bittensor inference failed: {response['error']}\"\n", + "\n", + " return response.get(\"choices\", [{}])[0].get(\"message\", {}).get(\"content\", \"No response\")\n", + "\n", + "\n", + "@tool\n", + "def spraay_web_search(query: str) -> str:\n", + " \"\"\"Search the web via Spraay's x402 search endpoint (Tavily-powered).\n", + " Costs $0.02 USDC per request. Uses /api/v1/search/web.\n", + " Use when you need current information not available in the knowledge base.\"\"\"\n", + "\n", + " print(f\" 🔍 Searching the web via Spraay x402 ($0.02 USDC)...\")\n", + " response = x402_client.request(\n", + " \"/api/v1/search/web\",\n", + " method=\"POST\",\n", + " json={\"query\": query, \"search_depth\": \"basic\", \"max_results\": 5}\n", + " )\n", + "\n", + " if \"error\" in response:\n", + " return f\"Search failed: {response['error']}\"\n", + "\n", + " results = response.get(\"results\", [])\n", + " if not results:\n", + " return \"No web results found.\"\n", + "\n", + " formatted = \"\\n\".join([\n", + " f\"- {r.get('title', 'Untitled')}: {r.get('snippet', 'No snippet')}\"\n", + " for r in results[:5]\n", + " ])\n", + " return f\"Web search results:\\n{formatted}\"\n", + "\n", + "\n", + "tools = [search_knowledge_base, spraay_ai_inference, spraay_bittensor_inference, spraay_web_search]\n", + "print(f\"✅ {len(tools)} agent tools registered\")\n", + "print(\" - search_knowledge_base (free — Oracle AI DB)\")\n", + "print(\" - spraay_ai_inference ($0.04 USDC — 200+ models)\")\n", + "print(\" - spraay_bittensor_inference ($0.03 USDC — Bittensor SN64)\")\n", + "print(\" - spraay_web_search ($0.02 USDC — Tavily)\")" + ] + }, + { + "cell_type": "markdown", + "id": "03d8c22e", + "metadata": {}, + "source": [ + "## 7. Build the Payment-Enabled Agent\n", + "\n", + "We create a LangChain ReAct agent that:\n", + "1. **Always checks the knowledge base first** (free)\n", + "2. **Escalates to paid inference** only when local context is insufficient\n", + "3. **Can choose between centralized AI or decentralized Bittensor inference**\n", + "4. **Logs all payments** for transparency and auditing\n", + "\n", + "This cost-aware behavior is guided by the system prompt — the agent is instructed to prefer free tools and only pay when necessary.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e8a5e107", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_openai import ChatOpenAI\n", + "from langchain.agents import AgentExecutor, create_react_agent\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "\n", + "# Initialize LLM for agent reasoning\n", + "llm = ChatOpenAI(\n", + " model=\"gpt-4\",\n", + " temperature=0,\n", + " openai_api_key=OPENAI_API_KEY\n", + ")\n", + "\n", + "# System prompt that enforces cost-aware behavior\n", + "system_prompt = \"\"\"You are an AI research agent with access to both free and paid tools.\n", + "\n", + "IMPORTANT RULES:\n", + "1. ALWAYS search the knowledge base first using search_knowledge_base (this is FREE)\n", + "2. Only use paid tools if the knowledge base doesn't have a sufficient answer\n", + "3. For AI analysis, prefer spraay_ai_inference ($0.04) for complex tasks or\n", + " spraay_bittensor_inference ($0.03) for decentralized/censorship-resistant inference\n", + "4. Use spraay_web_search ($0.02) only for current/real-time information\n", + "5. When using paid tools, be specific in your queries to minimize cost\n", + "6. After answering, briefly note which tools you used and whether any payments were made\n", + "\n", + "Available tools:\n", + "{tools}\n", + "\n", + "Tool names: {tool_names}\n", + "\n", + "Use this format:\n", + "Question: the question to answer\n", + "Thought: think about which tool to use (prefer free tools first)\n", + "Action: the tool to use\n", + "Action Input: the input to the tool\n", + "Observation: the result\n", + "... (repeat as needed)\n", + "Thought: I now know the final answer\n", + "Final Answer: the answer with sources noted\n", + "\n", + "Question: {input}\n", + "{agent_scratchpad}\"\"\"\n", + "\n", + "prompt = ChatPromptTemplate.from_template(system_prompt)\n", + "\n", + "# Create the agent\n", + "agent = create_react_agent(llm, tools, prompt)\n", + "agent_executor = AgentExecutor(\n", + " agent=agent,\n", + " tools=tools,\n", + " verbose=True,\n", + " max_iterations=5,\n", + " handle_parsing_errors=True\n", + ")\n", + "\n", + "print(\"✅ Payment-enabled agent ready\")" + ] + }, + { + "cell_type": "markdown", + "id": "8f4bc496", + "metadata": {}, + "source": [ + "## 8. Run the Agent\n", + "\n", + "Let's test the agent with different types of queries:\n", + "- **Query 1**: Answerable from the knowledge base (should be free)\n", + "- **Query 2**: Requires premium inference (should trigger x402 payment)\n", + "- **Query 3**: Requires current web data (should trigger x402 payment)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eaa02001", + "metadata": {}, + "outputs": [], + "source": [ + "# Query 1: Should be answered from Oracle AI DB (free)\n", + "print(\"=\" * 60)\n", + "print(\"QUERY 1: Knowledge base lookup (expected: FREE)\")\n", + "print(\"=\" * 60)\n", + "\n", + "result1 = agent_executor.invoke({\n", + " \"input\": \"What is the x402 payment protocol and how does it work?\"\n", + "})\n", + "\n", + "print(f\"\\n📝 Answer: {result1['output']}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "307b3920", + "metadata": {}, + "outputs": [], + "source": [ + "# Query 2: Requires premium AI inference (expected: PAID)\n", + "print(\"=\" * 60)\n", + "print(\"QUERY 2: Analysis requiring premium inference (expected: PAID)\")\n", + "print(\"=\" * 60)\n", + "\n", + "result2 = agent_executor.invoke({\n", + " \"input\": \"Compare the economic efficiency of x402 micropayments vs traditional \"\n", + " \"API key subscriptions for AI agent deployments at scale. \"\n", + " \"Include specific cost breakdowns.\"\n", + "})\n", + "\n", + "print(f\"\\n📝 Answer: {result2['output']}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ca493eae", + "metadata": {}, + "outputs": [], + "source": [ + "# Query 3: Current web data (expected: PAID)\n", + "print(\"=\" * 60)\n", + "print(\"QUERY 3: Current information lookup (expected: PAID)\")\n", + "print(\"=\" * 60)\n", + "\n", + "result3 = agent_executor.invoke({\n", + " \"input\": \"What are the latest developments in the x402 payment protocol ecosystem?\"\n", + "})\n", + "\n", + "print(f\"\\n📝 Answer: {result3['output']}\")" + ] + }, + { + "cell_type": "markdown", + "id": "b9f67727", + "metadata": {}, + "source": [ + "## 9. Payment Audit Trail\n", + "\n", + "One of the key benefits of x402 is full payment transparency. Every micropayment is an on-chain USDC transfer on Base, providing a complete audit trail. Let's review what the agent spent during this session.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c4de6828", + "metadata": {}, + "outputs": [], + "source": [ + "# Review all payments made during this session\n", + "summary = x402_client.get_payment_summary()\n", + "\n", + "print(\"=\" * 60)\n", + "print(\"💰 PAYMENT SUMMARY\")\n", + "print(\"=\" * 60)\n", + "print(f\"Total requests with payment: {summary['total_payments']}\")\n", + "print(f\"Total USDC spent: ${summary['total_usdc_spent']:.6f}\")\n", + "print()\n", + "\n", + "if summary['payments']:\n", + " print(\"Individual payments:\")\n", + " for i, payment in enumerate(summary['payments'], 1):\n", + " print(f\" {i}. {payment['endpoint']} — ${float(payment.get('amount', 0)):.6f} USDC\")\n", + "else:\n", + " print(\"No paid requests were made (all answered from knowledge base)\")\n", + "\n", + "print()\n", + "print(\"All payments are verifiable on-chain at:\")\n", + "print(\"https://basescan.org/address/\" + x402_client.account.address)" + ] + }, + { + "cell_type": "markdown", + "id": "17f88c50", + "metadata": {}, + "source": [ + "## 10. Bonus: Oracle Hybrid Search with Payment Context\n", + "\n", + "Oracle AI Database supports hybrid search — combining vector similarity with traditional SQL filtering in a single query. This is powerful for agents that need to search payment history alongside semantic context.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fdb4fd9f", + "metadata": {}, + "outputs": [], + "source": [ + "# Example: Hybrid search combining vector similarity with metadata filtering\n", + "# This shows Oracle's unique ability to mix SQL + vector search\n", + "\n", + "hybrid_results = vector_store.similarity_search(\n", + " \"payment protocol benefits\",\n", + " k=3,\n", + " filter={\"topic\": \"benefits\"} # SQL filter on metadata\n", + ")\n", + "\n", + "print(\"🔎 Hybrid Search Results (vector + SQL filter):\")\n", + "print(f\" Filter: topic = 'benefits'\")\n", + "print(f\" Found: {len(hybrid_results)} documents\")\n", + "print()\n", + "for doc in hybrid_results:\n", + " print(f\" [{doc.metadata.get('source')}] {doc.page_content[:120]}...\")" + ] + }, + { + "cell_type": "markdown", + "id": "52bcf941", + "metadata": {}, + "source": [ + "## 11. Cleanup\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10ca0a8f", + "metadata": {}, + "outputs": [], + "source": [ + "# Close connections\n", + "x402_client.client.close()\n", + "connection.close()\n", + "print(\"✅ Connections closed\")" + ] + }, + { + "cell_type": "markdown", + "id": "f75dd3f2", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "This notebook demonstrated how to build a **payment-enabled AI agent** that combines:\n", + "\n", + "| Component | Role | Cost |\n", + "|-----------|------|------|\n", + "| **Oracle AI Database** | Vector storage, semantic search, hybrid queries | Free (self-hosted) |\n", + "| **Spraay x402 Gateway** | 88 endpoints: AI inference, Bittensor, search, batch payments, and more | Pay-per-request (USDC on Base) |\n", + "| **LangChain** | Agent orchestration, tool routing, reasoning | Free (open source) |\n", + "\n", + "### Key Takeaways\n", + "\n", + "1. **Cost-aware agents** — The agent checks free resources (Oracle AI DB) before escalating to paid services (Spraay x402), minimizing spend automatically.\n", + "\n", + "2. **No API keys needed** — x402 replaces API key management with per-request USDC micropayments. No credentials to rotate, no subscriptions to manage.\n", + "\n", + "3. **Centralized + Decentralized AI** — Agents can choose between 200+ centralized models (`/api/v1/chat/completions` at $0.04) or 43+ decentralized Bittensor models (`/bittensor/v1/chat/completions` at $0.03) — same OpenAI-compatible interface.\n", + "\n", + "4. **Full audit trail** — Every payment is an on-chain USDC transfer on Base, providing transparent, verifiable spend tracking.\n", + "\n", + "5. **Oracle's hybrid search** — Combining vector similarity with SQL filtering in a single query is uniquely powerful for agents that need structured + semantic retrieval.\n", + "\n", + "6. **Production-ready integrations** — Spraay's batch payment tool is merged into Google's ADK (PR #95 in `google/adk-python-community`), with integrations across LangChain, CrewAI, and more.\n", + "\n", + "### Gateway at a Glance\n", + "\n", + "| Stat | Value |\n", + "|------|-------|\n", + "| Endpoints | 88 |\n", + "| Categories | 19 |\n", + "| Chains | 15 |\n", + "| AI Models | 200+ (centralized) + 43+ (Bittensor) |\n", + "| Payment | USDC on Base |\n", + "| Contract | [`0x1646452F98E36A3c9Cfc3eDD8868221E207B5eEC`](https://basescan.org/address/0x1646452F98E36A3c9Cfc3eDD8868221E207B5eEC) |\n", + "\n", + "### Learn More\n", + "\n", + "- **Spraay Protocol**: [spraay.app](https://spraay.app)\n", + "- **Spraay x402 Gateway Docs**: [docs.spraay.app](https://docs.spraay.app)\n", + "- **Gateway**: [gateway.spraay.app](https://gateway.spraay.app)\n", + "- **MCP Server**: [Smithery — @plagtech/spraay-x402-mcp](https://smithery.ai/server/@plagtech/spraay-x402-mcp) (60 tools for Claude Desktop, Cursor, Cline)\n", + "- **Google ADK Tool**: [google/adk-python-community](https://github.com/google/adk-python-community) (PR #95)\n", + "- **x402 Protocol Spec**: [x402.org](https://www.x402.org)\n", + "- **Oracle AI Vector Search**: [oracle.com/database/ai](https://www.oracle.com/database/ai/)\n", + "- **LangChain Oracle Integration**: [langchain-oracledb](https://python.langchain.com/docs/integrations/vectorstores/oracle/)\n", + "- **GitHub**: [github.com/plagtech](https://github.com/plagtech)\n", + "- **Twitter**: [@Spraay_app](https://twitter.com/Spraay_app)\n", + "\n", + "---\n", + "\n", + "*Contributed by [Spraay Protocol](https://spraay.app) — Multi-chain batch payments & x402 payment gateway for AI agents.*\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}