Last active
February 27, 2025 19:40
-
-
Save thearyanag/1087a05e8ede5e216d34a67d94f9b7a1 to your computer and use it in GitHub Desktop.
Sonic Agent Kit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| an example to show how to use sonic agent kit to connect ai with any sonic protocol |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SONIC_PRIVATE_KEY= | |
| RPC_URL=https://rpc.mainnet-alpha.sonic.game/ | |
| OPENAI_API_KEY=sk-proj- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { SonicAgentKit, createSonicTools } from "@sendaifun/sonic-agent-kit"; | |
| import { HumanMessage } from "@langchain/core/messages"; | |
| import { MemorySaver } from "@langchain/langgraph"; | |
| import { createReactAgent } from "@langchain/langgraph/prebuilt"; | |
| import { ChatOpenAI } from "@langchain/openai"; | |
| import * as dotenv from "dotenv"; | |
| import * as fs from "fs"; | |
| import * as readline from "readline"; | |
| import bs58 from "bs58"; | |
| dotenv.config(); | |
| function validateEnvironment(): void { | |
| const missingVars: string[] = []; | |
| const requiredVars = ["RPC_URL", "SONIC_PRIVATE_KEY"]; | |
| requiredVars.forEach((varName) => { | |
| if (!process.env[varName]) { | |
| missingVars.push(varName); | |
| } | |
| }); | |
| if (missingVars.length > 0) { | |
| console.error("Error: Required environment variables are not set"); | |
| missingVars.forEach((varName) => { | |
| console.error(`${varName}=your_${varName.toLowerCase()}_here`); | |
| }); | |
| process.exit(1); | |
| } | |
| } | |
| validateEnvironment(); | |
| const WALLET_DATA_FILE = "wallet_data.txt"; | |
| async function initializeAgent() { | |
| try { | |
| const llm = new ChatOpenAI({ | |
| modelName: "gpt-4o-mini", | |
| temperature: 0.7, | |
| apiKey: process.env.OPENAI_API_KEY!, | |
| }); | |
| let walletDataStr: string | null = null; | |
| if (fs.existsSync(WALLET_DATA_FILE)) { | |
| try { | |
| walletDataStr = fs.readFileSync(WALLET_DATA_FILE, "utf8"); | |
| } catch (error) { | |
| console.error("Error reading wallet data:", error); | |
| } | |
| } | |
| const sonicAgent = new SonicAgentKit( | |
| process.env.SONIC_PRIVATE_KEY!, | |
| process.env.RPC_URL!, | |
| { | |
| OPENAI_API_KEY: "", | |
| } | |
| ); | |
| const tools = createSonicTools(sonicAgent); | |
| const memory = new MemorySaver(); | |
| const config = { configurable: { thread_id: "Sonic Agent Kit!" } }; | |
| const agent = createReactAgent({ | |
| llm, | |
| tools, | |
| checkpointSaver: memory, | |
| messageModifier: ` | |
| You are a helpful agent that can interact onchain using the Sonic Agent Kit. You are | |
| empowered to interact onchain using your tools. If you ever need funds, you can request them from the | |
| faucet. If not, you can provide your wallet details and request funds from the user. If there is a 5XX | |
| (internal) HTTP error code, ask the user to try again later. If someone asks you to do something you | |
| can't do with your currently available tools, you must say so, and encourage them to implement it | |
| themselves using the Sonic Agent Kit, recommend they go to https://www.sonicagentkit.xyz for more information. Be | |
| concise and helpful with your responses. Refrain from restating your tools' descriptions unless it is explicitly requested. | |
| `, | |
| }); | |
| if (walletDataStr) { | |
| fs.writeFileSync(WALLET_DATA_FILE, walletDataStr); | |
| } | |
| return { agent, config }; | |
| } catch (error) { | |
| console.error("Failed to initialize agent:", error); | |
| throw error; | |
| } | |
| } | |
| async function runAutonomousMode(agent: any, config: any, interval = 10) { | |
| console.log("Starting autonomous mode..."); | |
| while (true) { | |
| try { | |
| const thought = | |
| "Be creative and do something interesting on the blockchain. " + | |
| "Choose an action or set of actions and execute it that highlights your abilities."; | |
| const stream = await agent.stream( | |
| { messages: [new HumanMessage(thought)] }, | |
| config, | |
| ); | |
| for await (const chunk of stream) { | |
| if ("agent" in chunk) { | |
| console.log(chunk.agent.messages[0].content); | |
| } else if ("tools" in chunk) { | |
| console.log(chunk.tools.messages[0].content); | |
| } | |
| console.log("-------------------"); | |
| } | |
| await new Promise((resolve) => setTimeout(resolve, interval * 1000)); | |
| } catch (error) { | |
| if (error instanceof Error) { | |
| console.error("Error:", error.message); | |
| } | |
| process.exit(1); | |
| } | |
| } | |
| } | |
| async function runChatMode(agent: any, config: any) { | |
| console.log("Starting chat mode... Type 'exit' to end."); | |
| const rl = readline.createInterface({ | |
| input: process.stdin, | |
| output: process.stdout, | |
| }); | |
| const question = (prompt: string): Promise<string> => | |
| new Promise((resolve) => rl.question(prompt, resolve)); | |
| try { | |
| while (true) { | |
| const userInput = await question("\nPrompt: "); | |
| if (userInput.toLowerCase() === "exit") { | |
| break; | |
| } | |
| const stream = await agent.stream( | |
| { messages: [new HumanMessage(userInput)] }, | |
| config, | |
| ); | |
| for await (const chunk of stream) { | |
| if ("agent" in chunk) { | |
| console.log(chunk.agent.messages[0].content); | |
| } else if ("tools" in chunk) { | |
| console.log(chunk.tools.messages[0].content); | |
| } | |
| console.log("-------------------"); | |
| } | |
| } | |
| } catch (error) { | |
| if (error instanceof Error) { | |
| console.error("Error:", error.message); | |
| } | |
| process.exit(1); | |
| } finally { | |
| rl.close(); | |
| } | |
| } | |
| async function chooseMode(): Promise<"chat" | "auto"> { | |
| const rl = readline.createInterface({ | |
| input: process.stdin, | |
| output: process.stdout, | |
| }); | |
| const question = (prompt: string): Promise<string> => | |
| new Promise((resolve) => rl.question(prompt, resolve)); | |
| while (true) { | |
| console.log("\nAvailable modes:"); | |
| console.log("1. chat - Interactive chat mode"); | |
| console.log("2. auto - Autonomous action mode"); | |
| const choice = (await question("\nChoose a mode (enter number or name): ")) | |
| .toLowerCase() | |
| .trim(); | |
| rl.close(); | |
| if (choice === "1" || choice === "chat") { | |
| return "chat"; | |
| } else if (choice === "2" || choice === "auto") { | |
| return "auto"; | |
| } | |
| console.log("Invalid choice. Please try again."); | |
| } | |
| } | |
| async function main() { | |
| try { | |
| console.log("Starting Agent..."); | |
| const { agent, config } = await initializeAgent(); | |
| const mode = await chooseMode(); | |
| if (mode === "chat") { | |
| await runChatMode(agent, config); | |
| } else { | |
| await runAutonomousMode(agent, config); | |
| } | |
| } catch (error) { | |
| if (error instanceof Error) { | |
| console.error("Error:", error.message); | |
| } | |
| process.exit(1); | |
| } | |
| } | |
| if (require.main === module) { | |
| main().catch((error) => { | |
| console.error("Fatal error:", error); | |
| process.exit(1); | |
| }); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "dependencies": { | |
| "@langchain/core": "^0.3.41", | |
| "@langchain/langgraph": "^0.2.49", | |
| "@langchain/openai": "^0.4.4", | |
| "@sendaifun/sonic-agent-kit": "^1.0.0", | |
| "bs58": "^6.0.0", | |
| "dotenv": "^16.4.7" | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment