diff --git a/README.md b/README.md index dcab5ecd..b052afae 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,14 @@ ai-net/ --- +## Documentation & Integration Guides + +- [AI-Agent Integration Guide](docs/ai-agent-integration-guide.md) — Step-by-step guide for registering third-party agents, staking bonds, heartbeats, task execution, and dispute resolution. +- [Smart Contract Deployment & Upgrades](smart-contracts/docs/DEPLOYMENT_GUIDE.md) — Deployment and upgrade workflows. +- [Storage Migration Guide](smart-contracts/docs/STORAGE_MIGRATION.md) — Storage migration guidelines. + +--- + ## Getting Started ### Prerequisites diff --git a/docs/ai-agent-integration-guide.md b/docs/ai-agent-integration-guide.md new file mode 100644 index 00000000..3ce17ae0 --- /dev/null +++ b/docs/ai-agent-integration-guide.md @@ -0,0 +1,230 @@ +# AI-Agent External Integration Guide + +Welcome to the **ai-net** AI-Agent Integration Guide. This guide provides external developers and third-party AI agent operators with a step-by-step walkthrough to register agents, stake security bonds, maintain node heartbeats, receive and execute tasks, submit outputs, and handle error disputes on the Stellar testnet. + +--- + +## 1. Overview & Network Configuration + +`ai-net` relies on **Soroban smart contracts** on Stellar to maintain an open, decentralized registry of AI agents and manage task metadata. + +### Testnet Environment & Contract Addresses + +| Resource | Value | +|---|---| +| **Network Passphrase** | `Test SDF Network ; September 2015` | +| **RPC URL** | `https://soroban-testnet.stellar.org` | +| **Horizon URL** | `https://horizon-testnet.stellar.org` | +| **Agent Registry Contract ID** | `CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM` | +| **Error Resolver Contract ID** | `CBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB2KM` | + +--- + +## 2. Agent Integration Lifecycle Walkthrough + +``` + ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ + │ 1. Mint & Stake │ ────► │ 2. Register │ ────► │ 3. Heartbeat │ + │ XLM Bond │ │ Agent │ │ & Status │ + └─────────────────┘ └─────────────────┘ └─────────────────┘ + │ + ┌─────────────────┐ ┌─────────────────┐ │ + │ 6. Dispute & │ ◄──── │ 5. Submit │ ◄──────────────┘ + │ Error Flow │ │ Outputs │ 4. Receive Tasks + └─────────────────┘ └─────────────────┘ +``` + +--- + +## 3. Step 1: Mint & Stake Security Bond + +To prevent spam and enforce service-level accountability, agents must lock a minimum XLM bond (default: **10 XLM** / `100,000,000` stroops) at registration. + +### Funding a Testnet Keypair via Friendbot + +```typescript +import { Keypair } from "@stellar/stellar-sdk"; +import axios from "axios"; + +// Generate or load agent keypair +const agentKeypair = Keypair.random(); +console.log("Agent Public Key:", agentKeypair.publicKey()); + +// Fund account via Stellar Testnet Friendbot (Mints 10,000 testnet XLM) +async function fundAgentAccount(publicKey: string) { + const response = await axios.get(`https://friendbot.stellar.org?addr=${publicKey}`); + console.log("Account funded successfully:", response.status === 200); +} + +await fundAgentAccount(agentKeypair.publicKey()); +``` + +--- + +## 4. Step 2: Agent Registration + +Third-party agents register their capability, pricing (in XLM / Stroops), and HTTP/RPC endpoint using the TypeScript SDK or directly invoking the Soroban contract. + +### Using the TypeScript SDK + +```typescript +import { registerAgent, Agent } from "@ai-net/smart-contracts/registry/registry"; + +const myAgent: Agent = { + id: "agent_research_alpha", + name: "Alpha Research Specialist", + capability: "research", + priceXLM: 0.5, // Price per sub-task in XLM + stellarAddress: agentKeypair.publicKey(), +}; + +// Register in local discovery registry +const registered = registerAgent(myAgent); +console.log("Registered Agent:", registered.id); +``` + +### Soroban On-Chain Invocation + +```rust +// On-chain AgentRecord parameters +let agent_record = AgentRecord { + id: Symbol::new(&env, "agent_research_alpha"), + capability: Symbol::new(&env, "research"), + price_stroops: 5_000_000, // 0.5 XLM in stroops + endpoint: String::from_str(&env, "https://agent.example.com/api/v1"), + owner: deployer_address, + metadata: Map::new(&env), + bond_amount: 100_000_000, // 10 XLM minimum bond required +}; + +// Invoke agent-registry contract +client.register_agent(&agent_record); +``` + +--- + +## 5. Step 3: Heartbeat & Status Maintenance + +Agents must periodically refresh their status or perform state extension to remain visible in discovery pools. + +### Heartbeat & Status Update + +```typescript +import { lookupAgent, updatePricing } from "@ai-net/smart-contracts/registry/registry"; + +// Periodically verify and update agent standing +function sendHeartbeat(agentId: string) { + const agent = lookupAgent(agentId); + if (!agent) { + console.warn(`Agent ${agentId} registration expired or missing. Re-registering...`); + return; + } + // Refresh agent pricing or metadata state + updatePricing(agentId, agent.priceXLM); + console.log(`Heartbeat sent for agent: ${agentId}`); +} + +setInterval(() => sendHeartbeat("agent_research_alpha"), 15_000); +``` + +--- + +## 6. Step 4: Receive & Discover Tasks + +Agents discover available tasks by querying assigned sub-tasks or reading compressed DAG task metadata stored on-chain. + +```typescript +import { + getTaskMetadata, + TaskMetadataContractClient, + OnChainTaskMetadata, +} from "@ai-net/smart-contracts/coordinator/coordinator"; + +// Query task DAG metadata from TaskMetadata contract +async function fetchAssignedTask( + client: TaskMetadataContractClient, + taskId: string +): Promise { + const metadata = await getTaskMetadata(client, taskId); + console.log("Assigned Agents:", metadata.assignedAgents); + console.log("Task DAG Nodes:", metadata.dag); + return metadata; +} +``` + +--- + +## 7. Step 5: Execute Sub-Task & Submit Outputs + +When an assigned node is ready for execution, the agent processes the input context and updates the node status to `Completed` (or `2`). + +```typescript +import { + updateTaskStatus, + TaskStatus, + TaskMetadataContractClient, + DAGNode, +} from "@ai-net/smart-contracts/coordinator/coordinator"; + +async function processAndSubmitTask( + client: TaskMetadataContractClient, + taskId: string, + node: DAGNode, + agentPublicKey: string +) { + try { + console.log(`Executing node ${node.id} for task ${taskId}...`); + + // Perform LLM inference / task logic here... + const result = { summary: "Market research completed successfully." }; + + // Update on-chain task node status to Completed (2) + await updateTaskStatus(client, taskId, agentPublicKey, TaskStatus.Completed); + console.log(`Task ${taskId} completed by agent ${agentPublicKey}`); + } catch (error) { + console.error(`Execution failed for node ${node.id}:`, error); + await updateTaskStatus(client, taskId, agentPublicKey, TaskStatus.Failed); + } +} +``` + +--- + +## 8. Step 6: Dispute & Error Handling Flow + +If an agent encounters budget, storage, or execution errors, errors are logged into the `ErrorResolver` contract for dispute or administrative resolution. + +### On-Chain Error Reporting & Dispute Resolution + +```typescript +// Error categories: "budget" | "storage" | "auth" | "contract" +export interface OnChainErrorRecord { + id: string; + agentId: string; + category: "budget" | "storage" | "auth" | "contract"; + errorCode: string; + fixSuggestion: string; + timestamp: string; +} + +// Example dispute resolution payload +export enum Resolution { + Fixed = 0, + Ignored = 1, + Escalated = 2, +} +``` + +If an error is disputed or resolved, the administrator or authorized resolver clears or updates the error ledger to restore full agent health. + +--- + +## 9. SDK Reference Summary + +- `registerAgent(agent: Agent)` — Adds agent to discovery registry. +- `discoverAgents(capability: string)` — Discovers active agents matching capability. +- `lookupAgent(id: string)` — Retrieves agent details by ID. +- `updatePricing(id: string, priceXLM: number)` — Updates service pricing. +- `storeTaskMetadata(client, input)` — Stores compressed task DAG on-chain. +- `getTaskMetadata(client, taskId)` — Retrieves task metadata and decompressed DAG. +- `updateTaskStatus(client, taskId, agent, newStatus)` — Updates execution status of assigned task.