mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-17 15:10:27 +00:00
Langgraph (#78)
# Pull Request Description ## Related Issue Fixes #61 ## Changes Made This PR adds the following changes: - Added a new example demonstrating LangGraph integration with Solana Agent Kit - Implemented a multi-agent system with specialized agents for different tasks - Added state management and routing logic using LangGraph's StateGraph - Integrated Tavily search capabilities for enhanced general-purpose queries - Added support for token swaps using Jupiter DEX - Implemented TypeScript-based project structure with full type safety - Added comprehensive documentation and architecture diagram ## Implementation Details - Created a directed workflow using StateGraph with the following components: - Manager Agent: Handles query classification and routing - General Agent: Processes basic queries with Tavily search integration - Transfer/Swap Agent: Handles token transfers and DEX operations - Read Agent: Manages blockchain data queries - Implemented state management using LangGraph annotations for query classification - Added environment-based configuration for API keys and RPC endpoints - Integrated with external dependencies: - @langchain/community v0.3.20 - @langchain/core v0.3.26 - @langchain/langgraph v0.2.36 - solana-agent-kit v1.3.0 - Set up TypeScript configuration with ESM support ## Architecture <img width="801" alt="Screenshot 2024-12-27 at 5 59 26 PM" src="https://github.com/user-attachments/assets/a90597ac-3bfc-47e1-b1de-5a17a3de106b" /> ## Transaction executed by agent Example transaction: ## Additional Notes - The implementation follows a modular architecture as shown in the architecture diagram - Supports both read and write operations on the Solana blockchain - Includes comprehensive error handling and type safety - Provides flexible configuration through environment variables - Project structure follows best practices with clear separation of concerns - Includes example queries for testing different agent pathways ## Checklist - [x] I have tested these changes locally - [x] I have updated the documentation - [x] I have added a transaction link - [x] I have added the prompt used to test it
This commit is contained in:
17
README.md
17
README.md
@@ -202,6 +202,23 @@ const price = await agent.pythFetchPrice(
|
||||
console.log("Price in BTC/USD:", price);
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### LangGraph Multi-Agent System
|
||||
|
||||
The repository includes an advanced example of building a multi-agent system using LangGraph and Solana Agent Kit. Located in `examples/agent-kit-langgraph`, this example demonstrates:
|
||||
|
||||
- Multi-agent architecture using LangGraph's StateGraph
|
||||
- Specialized agents for different tasks:
|
||||
- General purpose agent for basic queries
|
||||
- Transfer/Swap agent for transaction operations
|
||||
- Read agent for blockchain data queries
|
||||
- Manager agent for routing and orchestration
|
||||
- Fully typed TypeScript implementation
|
||||
- Environment-based configuration
|
||||
|
||||
Check out the [LangGraph example](examples/agent-kit-langgraph) for a complete implementation of an advanced Solana agent system.
|
||||
|
||||
## Dependencies
|
||||
|
||||
The toolkit relies on several key Solana and Metaplex libraries:
|
||||
|
||||
4
examples/agent-kit-langgraph/.env.example
Normal file
4
examples/agent-kit-langgraph/.env.example
Normal file
@@ -0,0 +1,4 @@
|
||||
OPENAI_API_KEY=
|
||||
RPC_URL=
|
||||
SOLANA_PRIVATE_KEY=
|
||||
TAVILY_API_KEY= #Optional: for search functionality
|
||||
11
examples/agent-kit-langgraph/.gitignore
vendored
Normal file
11
examples/agent-kit-langgraph/.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# Dependencies
|
||||
node_modules/
|
||||
package-lock.json
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
|
||||
# Build output
|
||||
dist/
|
||||
build/
|
||||
87
examples/agent-kit-langgraph/README.md
Normal file
87
examples/agent-kit-langgraph/README.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Agent Kit LangGraph Example
|
||||
|
||||
This example demonstrates how to build an advanced Solana agent using LangGraph and the Solana Agent Kit. It showcases a multi-agent system that can handle various Solana-related tasks through a directed workflow.
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- Multi-agent architecture using LangGraph's StateGraph
|
||||
- Specialized agents for different tasks:
|
||||
- General purpose agent for basic queries (with optional Tavily search integration)
|
||||
- Transfer/Swap agent for transaction operations
|
||||
- Read agent for blockchain data queries
|
||||
- Manager agent for routing and orchestration
|
||||
- Environment-based configuration
|
||||
- TypeScript implementation with full type safety
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js (v16 or higher)
|
||||
- pnpm package manager
|
||||
- Solana development environment
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone the repository and navigate to the example directory:
|
||||
```bash
|
||||
cd examples/agent-kit-langgraph
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
3. Configure environment variables:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Edit the `.env` file with your configuration:
|
||||
- Add your OpenAI API key
|
||||
- Add your Tavily API key (optional, enables web search capabilities)
|
||||
- Configure any other required environment variables
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── agents/ # Individual agent implementations
|
||||
├── helper/ # Helper utilities and examples
|
||||
├── prompts/ # Agent prompts and templates
|
||||
├── tools/ # Custom tools for agents
|
||||
└── utils/ # Utility functions and configurations
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
To run the example:
|
||||
|
||||
```bash
|
||||
pnpm dev src/index.ts
|
||||
```
|
||||
|
||||
The example demonstrates a workflow where:
|
||||
1. The manager agent receives the initial query
|
||||
2. Based on the query type, it routes to the appropriate specialized agent:
|
||||
- General queries → Generalist Agent
|
||||
- Transfer/Swap operations → TransferSwap Agent
|
||||
- Blockchain data queries → Read Agent
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `@langchain/community`: LangChain community tools and utilities
|
||||
- Includes Tavily search integration for enhanced query responses
|
||||
- `@langchain/core`: Core LangChain functionality
|
||||
- `@langchain/langgraph`: Graph-based agent workflows
|
||||
- `solana-agent-kit`: Solana Agent Kit for blockchain interactions
|
||||
- `zod`: Runtime type checking
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
||||
|
||||
## License
|
||||
|
||||
ISC License
|
||||
BIN
examples/agent-kit-langgraph/assets/architecture.png
Normal file
BIN
examples/agent-kit-langgraph/assets/architecture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 213 KiB |
9
examples/agent-kit-langgraph/langgraph.json
Normal file
9
examples/agent-kit-langgraph/langgraph.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"node_version": "20",
|
||||
"dockerfile_lines": [],
|
||||
"dependencies": ["."],
|
||||
"graphs": {
|
||||
"solanaAgent": "./src/index.ts:graph"
|
||||
},
|
||||
"env": ".env"
|
||||
}
|
||||
31
examples/agent-kit-langgraph/package.json
Normal file
31
examples/agent-kit-langgraph/package.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "agent-kit-langgraph",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"dev": "tsx"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@langchain/community": "^0.3.20",
|
||||
"@langchain/core": "^0.3.26",
|
||||
"@langchain/langgraph": "^0.2.36",
|
||||
"dotenv": "^16.4.7",
|
||||
"solana-agent-kit": "^1.3.0",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ts-node": "^10.9.2",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"ts-node": {
|
||||
"esm": true,
|
||||
"experimentalSpecifierResolution": "node"
|
||||
}
|
||||
}
|
||||
4462
examples/agent-kit-langgraph/pnpm-lock.yaml
generated
Normal file
4462
examples/agent-kit-langgraph/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
examples/agent-kit-langgraph/src/agents/generalAgent.ts
Normal file
25
examples/agent-kit-langgraph/src/agents/generalAgent.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
||||
import { gpt4o } from "../utils/model";
|
||||
import { solanaAgentState } from "../utils/state";
|
||||
import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
|
||||
|
||||
// Initialize tools array
|
||||
const searchTools = [];
|
||||
|
||||
// Only add Tavily search if API key is available
|
||||
if (process.env.TAVILY_API_KEY) {
|
||||
searchTools.push(new TavilySearchResults());
|
||||
}
|
||||
|
||||
const generalAgent = createReactAgent({
|
||||
llm: gpt4o,
|
||||
tools: searchTools,
|
||||
});
|
||||
|
||||
export const generalistNode = async (state: typeof solanaAgentState.State) => {
|
||||
const { messages } = state;
|
||||
|
||||
const result = await generalAgent.invoke({ messages });
|
||||
|
||||
return { messages: [...result.messages] };
|
||||
};
|
||||
23
examples/agent-kit-langgraph/src/agents/manager.ts
Normal file
23
examples/agent-kit-langgraph/src/agents/manager.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { prompt, parser } from "../prompts/manager";
|
||||
import { RunnableSequence } from "@langchain/core/runnables";
|
||||
import { solanaAgentState } from "../utils/state";
|
||||
import { gpt4o } from "../utils/model";
|
||||
|
||||
const chain = RunnableSequence.from([prompt, gpt4o, parser]);
|
||||
|
||||
export const managerNode = async (state: typeof solanaAgentState.State) => {
|
||||
const { messages } = state;
|
||||
|
||||
const result = await chain.invoke({
|
||||
formatInstructions: parser.getFormatInstructions(),
|
||||
messages: messages,
|
||||
});
|
||||
|
||||
const { isSolanaReadQuery, isSolanaWriteQuery, isGeneralQuery } = result;
|
||||
|
||||
return {
|
||||
isSolanaReadQuery,
|
||||
isSolanaWriteQuery,
|
||||
isGeneralQuery,
|
||||
};
|
||||
};
|
||||
22
examples/agent-kit-langgraph/src/agents/readAgent.ts
Normal file
22
examples/agent-kit-langgraph/src/agents/readAgent.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
||||
import { gpt4o } from "../utils/model";
|
||||
import { solanaAgentState } from "../utils/state";
|
||||
import { HumanMessage } from "@langchain/core/messages";
|
||||
import { agentKit } from "../utils/solanaAgent";
|
||||
import {
|
||||
SolanaBalanceTool,
|
||||
SolanaFetchPriceTool,
|
||||
} from "solana-agent-kit/dist/langchain";
|
||||
|
||||
const readAgent = createReactAgent({
|
||||
llm: gpt4o,
|
||||
tools: [new SolanaBalanceTool(agentKit), new SolanaFetchPriceTool(agentKit)],
|
||||
});
|
||||
|
||||
export const readNode = async (state: typeof solanaAgentState.State) => {
|
||||
const { messages } = state;
|
||||
|
||||
const result = await readAgent.invoke({ messages });
|
||||
|
||||
return { messages: [...result.messages] };
|
||||
};
|
||||
25
examples/agent-kit-langgraph/src/agents/transferOrSwap.ts
Normal file
25
examples/agent-kit-langgraph/src/agents/transferOrSwap.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { gpt4o } from "../utils/model";
|
||||
import { agentKit } from "../utils/solanaAgent";
|
||||
import { solanaAgentState } from "../utils/state";
|
||||
import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
||||
import { SolanaTransferTool } from "solana-agent-kit/dist/langchain";
|
||||
import { transferSwapPrompt } from "../prompts/transferSwap";
|
||||
import { swapTool } from "../tools/swap";
|
||||
|
||||
const transferOrSwapAgent = createReactAgent({
|
||||
stateModifier: transferSwapPrompt,
|
||||
llm: gpt4o,
|
||||
tools: [new SolanaTransferTool(agentKit), swapTool],
|
||||
});
|
||||
|
||||
export const transferSwapNode = async (
|
||||
state: typeof solanaAgentState.State,
|
||||
) => {
|
||||
const { messages } = state;
|
||||
|
||||
const result = await transferOrSwapAgent.invoke({
|
||||
messages,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
9
examples/agent-kit-langgraph/src/helper/examples.ts
Normal file
9
examples/agent-kit-langgraph/src/helper/examples.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { HumanMessage } from "@langchain/core/messages";
|
||||
|
||||
export const generalQuestion = [
|
||||
new HumanMessage("Who is the president of Ecuador?"),
|
||||
];
|
||||
|
||||
export const solanaReadQuery = [new HumanMessage("what is the price of SOL")];
|
||||
|
||||
export const solanaWriteQuery = [new HumanMessage("swap 0.1 usdc to sol")];
|
||||
50
examples/agent-kit-langgraph/src/helper/tokenList.ts
Normal file
50
examples/agent-kit-langgraph/src/helper/tokenList.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
export const tokenList = [
|
||||
{
|
||||
name: "USDC",
|
||||
ticker: "USDC",
|
||||
decimal: 6,
|
||||
mintAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
},
|
||||
{
|
||||
name: "USDT",
|
||||
ticker: "USDT",
|
||||
decimal: 6,
|
||||
mintAddress: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
|
||||
},
|
||||
{
|
||||
name: "USDS",
|
||||
ticker: "USDS",
|
||||
decimal: 6,
|
||||
mintAddress: "USDSwr9ApdHk5bvJKMjzff41FfuX8bSxdKcR81vTwcA",
|
||||
},
|
||||
{
|
||||
name: "SOL",
|
||||
ticker: "SOL",
|
||||
decimal: 9,
|
||||
mintAddress: "So11111111111111111111111111111111111111112",
|
||||
},
|
||||
{
|
||||
name: "jitoSOL",
|
||||
ticker: "jitoSOL",
|
||||
decimal: 9,
|
||||
mintAddress: "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn",
|
||||
},
|
||||
{
|
||||
name: "bSOL",
|
||||
ticker: "bSOL",
|
||||
decimal: 9,
|
||||
mintAddress: "bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1",
|
||||
},
|
||||
{
|
||||
name: "mSOL",
|
||||
ticker: "mSOL",
|
||||
decimal: 9,
|
||||
mintAddress: "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So",
|
||||
},
|
||||
{
|
||||
name: "BONK",
|
||||
ticker: "BONK",
|
||||
decimal: 9,
|
||||
mintAddress: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
|
||||
},
|
||||
];
|
||||
28
examples/agent-kit-langgraph/src/index.ts
Normal file
28
examples/agent-kit-langgraph/src/index.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { StateGraph } from "@langchain/langgraph";
|
||||
import { solanaAgentState } from "./utils/state";
|
||||
import { generalistNode } from "./agents/generalAgent";
|
||||
import { transferSwapNode } from "./agents/transferOrSwap";
|
||||
import { managerNode } from "./agents/manager";
|
||||
import { readNode } from "./agents/readAgent";
|
||||
import { START, END } from "@langchain/langgraph";
|
||||
import { managerRouter } from "./utils/route";
|
||||
import { HumanMessage } from "@langchain/core/messages";
|
||||
|
||||
const workflow = new StateGraph(solanaAgentState)
|
||||
.addNode("generalist", generalistNode)
|
||||
.addNode("manager", managerNode)
|
||||
.addNode("transferSwap", transferSwapNode)
|
||||
.addNode("read", readNode)
|
||||
.addEdge(START, "manager")
|
||||
.addConditionalEdges("manager", managerRouter)
|
||||
.addEdge("generalist", END)
|
||||
.addEdge("transferSwap", END)
|
||||
.addEdge("read", END);
|
||||
|
||||
export const graph = workflow.compile();
|
||||
|
||||
const result = await graph.invoke({
|
||||
messages: [new HumanMessage("what is the price of SOL")],
|
||||
});
|
||||
|
||||
console.log(result);
|
||||
48
examples/agent-kit-langgraph/src/prompts/manager.ts
Normal file
48
examples/agent-kit-langgraph/src/prompts/manager.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { StructuredOutputParser } from "@langchain/core/output_parsers";
|
||||
import { z } from "zod";
|
||||
import { PromptTemplate } from "@langchain/core/prompts";
|
||||
|
||||
export const parser = StructuredOutputParser.fromZodSchema(
|
||||
z.object({
|
||||
isSolanaReadQuery: z
|
||||
.boolean()
|
||||
.describe("Query requires reading data from Solana blockchain"),
|
||||
isSolanaWriteQuery: z
|
||||
.boolean()
|
||||
.describe("Query requires writing/modifying data on Solana blockchain"),
|
||||
isGeneralQuery: z
|
||||
.boolean()
|
||||
.describe("Query is about non-blockchain topics"),
|
||||
}),
|
||||
);
|
||||
|
||||
export const prompt = PromptTemplate.fromTemplate(
|
||||
`
|
||||
You are the Chief Routing Officer for a multi-blockchain agent network. Your role is to:
|
||||
1. Analyze and classify incoming queries
|
||||
2. Determine if the query requires Solana read operations, write operations, or is general
|
||||
|
||||
Format your response according to:
|
||||
{formatInstructions}
|
||||
|
||||
Classification Guidelines:
|
||||
- Solana Read Operations include:
|
||||
* Checking account balances
|
||||
* Viewing NFT metadata
|
||||
* Getting program data
|
||||
* Querying transaction history
|
||||
* Checking token prices or holdings
|
||||
- Solana Write Operations include:
|
||||
* Creating or updating programs
|
||||
* Sending tokens or SOL
|
||||
* Minting NFTs
|
||||
* Creating accounts
|
||||
* Any transaction that modifies blockchain state
|
||||
- General queries include:
|
||||
* Non-blockchain topics
|
||||
* Internet searches
|
||||
* General knowledge questions
|
||||
|
||||
\n {messages} \n
|
||||
`,
|
||||
);
|
||||
43
examples/agent-kit-langgraph/src/prompts/transferSwap.ts
Normal file
43
examples/agent-kit-langgraph/src/prompts/transferSwap.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import {
|
||||
ChatPromptTemplate,
|
||||
MessagesPlaceholder,
|
||||
} from "@langchain/core/prompts";
|
||||
import { tokenList } from "../helper/tokenList";
|
||||
|
||||
// Convert token list to a more readable format for the prompt
|
||||
const formattedTokenList = tokenList
|
||||
.map(
|
||||
(token) =>
|
||||
`- ${token.name} (${token.ticker}) - Decimals: ${token.decimal} - Address: ${token.mintAddress}`,
|
||||
)
|
||||
.join("\n ");
|
||||
|
||||
export const transferSwapPrompt = ChatPromptTemplate.fromMessages([
|
||||
[
|
||||
"system",
|
||||
`You are an agent that is an expert in Solana transactions, specialized in token transfers and swaps. You can execute these transactions using the available tools based on user input.
|
||||
|
||||
When processing token amounts:
|
||||
1. Use EXACTLY the decimal amount specified by the user without any modifications
|
||||
2. Do not round or adjust the numbers
|
||||
3. Maintain precise decimal places as provided in the user input
|
||||
|
||||
For transfers:
|
||||
- User must specify the token, amount, and recipient address
|
||||
- The same token will be used for input and output
|
||||
|
||||
For swaps:
|
||||
- User must specify the input token, output token, and amount to swap
|
||||
- Input and output tokens must be different
|
||||
- Select tokens from this list of supported tokens:
|
||||
|
||||
${formattedTokenList}
|
||||
|
||||
Example amounts:
|
||||
If you say "0.01 SOL", I will use exactly 0.01 (not 0.010 or 0.0100)
|
||||
If you say "1.234 USDC", I will use exactly 1.234 (not 1.23 or 1.2340)
|
||||
For swaps, have the slippage be 200 bps
|
||||
`,
|
||||
],
|
||||
new MessagesPlaceholder("messages"),
|
||||
]);
|
||||
45
examples/agent-kit-langgraph/src/tools/swap.ts
Normal file
45
examples/agent-kit-langgraph/src/tools/swap.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { agentKit } from "../utils/solanaAgent";
|
||||
import { tool } from "@langchain/core/tools";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
|
||||
export const swapTool = tool(
|
||||
async ({ outputMint, inputAmount, inputMint, inputDecimal }) => {
|
||||
try {
|
||||
const inputAmountWithDecimals = inputAmount * 10 ** inputDecimal;
|
||||
const outputMintAddress = new PublicKey(outputMint);
|
||||
const inputMintAddress = new PublicKey(inputMint);
|
||||
|
||||
console.log(inputAmountWithDecimals, outputMintAddress, inputMintAddress);
|
||||
const tx = await agentKit.trade(
|
||||
outputMintAddress,
|
||||
inputAmountWithDecimals,
|
||||
inputMintAddress,
|
||||
200,
|
||||
);
|
||||
return tx;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return "error";
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "swap",
|
||||
description:
|
||||
"call to swap/trade tokens from one token to the other using Jupiter exchange",
|
||||
schema: z.object({
|
||||
outputMint: z
|
||||
.string()
|
||||
.describe("The mint address of destination token to be swapped to"),
|
||||
inputAmount: z
|
||||
.number()
|
||||
.describe(
|
||||
"the input amount of the token to be swapped without adding any decimals",
|
||||
),
|
||||
inputMint: z.string().describe("The mint address of the origin token "),
|
||||
inputDecimal: z
|
||||
.number()
|
||||
.describe("The decimal of the input token that is being traded"),
|
||||
}),
|
||||
},
|
||||
);
|
||||
12
examples/agent-kit-langgraph/src/utils/model.ts
Normal file
12
examples/agent-kit-langgraph/src/utils/model.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
import "dotenv/config";
|
||||
|
||||
export const gpt4o = new ChatOpenAI({
|
||||
modelName: "gpt-4o",
|
||||
apiKey: process.env.OPENAI_API_KEY!,
|
||||
});
|
||||
|
||||
export const gpt4oMini = new ChatOpenAI({
|
||||
modelName: "gpt-4o-mini",
|
||||
apiKey: process.env.OPENAI_API_KEY!,
|
||||
});
|
||||
16
examples/agent-kit-langgraph/src/utils/route.ts
Normal file
16
examples/agent-kit-langgraph/src/utils/route.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { solanaAgentState } from "./state";
|
||||
import { END } from "@langchain/langgraph";
|
||||
|
||||
export const managerRouter = (state: typeof solanaAgentState.State) => {
|
||||
const { isSolanaReadQuery, isSolanaWriteQuery, isGeneralQuery } = state;
|
||||
|
||||
if (isGeneralQuery) {
|
||||
return "generalist";
|
||||
} else if (isSolanaWriteQuery) {
|
||||
return "transferSwap";
|
||||
} else if (isSolanaReadQuery) {
|
||||
return "read";
|
||||
} else {
|
||||
return END;
|
||||
}
|
||||
};
|
||||
9
examples/agent-kit-langgraph/src/utils/solanaAgent.ts
Normal file
9
examples/agent-kit-langgraph/src/utils/solanaAgent.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { SolanaAgentKit, createSolanaTools } from "solana-agent-kit";
|
||||
|
||||
export const agentKit = new SolanaAgentKit(
|
||||
process.env.SOLANA_PRIVATE_KEY!,
|
||||
process.env.RPC_URL!,
|
||||
process.env.OPENAI_API_KEY!,
|
||||
);
|
||||
|
||||
export const solanaTools = createSolanaTools(agentKit);
|
||||
25
examples/agent-kit-langgraph/src/utils/state.ts
Normal file
25
examples/agent-kit-langgraph/src/utils/state.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Annotation } from "@langchain/langgraph";
|
||||
import { BaseMessage } from "@langchain/core/messages";
|
||||
import { messagesStateReducer } from "@langchain/langgraph";
|
||||
|
||||
export const solanaAgentState = Annotation.Root({
|
||||
messages: Annotation<BaseMessage[]>({
|
||||
reducer: messagesStateReducer,
|
||||
default: () => [],
|
||||
}),
|
||||
|
||||
isSolanaReadQuery: Annotation<boolean>({
|
||||
reducer: (x, y) => y ?? x ?? false,
|
||||
default: () => false,
|
||||
}),
|
||||
|
||||
isSolanaWriteQuery: Annotation<boolean>({
|
||||
reducer: (x, y) => y ?? x ?? false,
|
||||
default: () => false,
|
||||
}),
|
||||
|
||||
isGeneralQuery: Annotation<boolean>({
|
||||
reducer: (x, y) => y ?? x ?? false,
|
||||
default: () => false,
|
||||
}),
|
||||
});
|
||||
12
examples/agent-kit-langgraph/tsconfig.json
Normal file
12
examples/agent-kit-langgraph/tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"module": "es2022",
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"strict": true,
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -23,9 +23,9 @@
|
||||
"dependencies": {
|
||||
"@bonfida/spl-name-service": "^3.0.7",
|
||||
"@coral-xyz/anchor": "0.29",
|
||||
"@langchain/core": "^0.3.18",
|
||||
"@langchain/core": "^0.3.26",
|
||||
"@langchain/groq": "^0.1.2",
|
||||
"@langchain/langgraph": "^0.2.27",
|
||||
"@langchain/langgraph": "^0.2.34",
|
||||
"@langchain/openai": "^0.3.13",
|
||||
"@lightprotocol/compressed-token": "^0.17.1",
|
||||
"@lightprotocol/stateless.js": "^0.17.1",
|
||||
|
||||
4
pnpm-lock.yaml
generated
4
pnpm-lock.yaml
generated
@@ -15,13 +15,13 @@ importers:
|
||||
specifier: '0.29'
|
||||
version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)
|
||||
'@langchain/core':
|
||||
specifier: ^0.3.18
|
||||
specifier: ^0.3.26
|
||||
version: 0.3.26(openai@4.77.0(zod@3.24.1))
|
||||
'@langchain/groq':
|
||||
specifier: ^0.1.2
|
||||
version: 0.1.2(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1)))
|
||||
'@langchain/langgraph':
|
||||
specifier: ^0.2.27
|
||||
specifier: ^0.2.34
|
||||
version: 0.2.34(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1)))
|
||||
'@langchain/openai':
|
||||
specifier: ^0.3.13
|
||||
|
||||
Reference in New Issue
Block a user