-
Notifications
You must be signed in to change notification settings - Fork 443
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement framework-independent Action interface (#72)
This PR implements a framework-independent Action interface inspired by Eliza, making the tools more flexible and reusable across different frameworks. Changes: - Created independent actions under `src/actions/` - Implemented Zod validation for type safety - Converted all LangChain tools to use actions - Added natural language matching with similes - Improved error handling and response formats
- Loading branch information
Showing
40 changed files
with
2,540 additions
and
18 deletions.
There are no files selected for viewing
This file contains 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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { PublicKey } from "@solana/web3.js"; | ||
import { Action } from "../types/action"; | ||
import { SolanaAgentKit } from "../agent"; | ||
import { z } from "zod"; | ||
import { get_balance } from "../tools"; | ||
|
||
const balanceAction: Action = { | ||
name: "solana_balance", | ||
similes: [ | ||
"check balance", | ||
"get wallet balance", | ||
"view balance", | ||
"show balance", | ||
"check token balance", | ||
], | ||
description: `Get the balance of a Solana wallet or token account. | ||
If you want to get the balance of your wallet, you don't need to provide the tokenAddress. | ||
If no tokenAddress is provided, the balance will be in SOL.`, | ||
examples: [ | ||
[ | ||
{ | ||
input: {}, | ||
output: { | ||
status: "success", | ||
balance: "100", | ||
token: "SOL", | ||
}, | ||
explanation: "Get SOL balance of the wallet", | ||
}, | ||
], | ||
[ | ||
{ | ||
input: { | ||
tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", | ||
}, | ||
output: { | ||
status: "success", | ||
balance: "1000", | ||
token: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", | ||
}, | ||
explanation: "Get USDC token balance", | ||
}, | ||
], | ||
], | ||
schema: z.object({ | ||
tokenAddress: z.string().optional(), | ||
}), | ||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => { | ||
const balance = await get_balance( | ||
agent, | ||
input.tokenAddress && new PublicKey(input.tokenAddress), | ||
); | ||
|
||
return { | ||
status: "success", | ||
balance: balance, | ||
token: input.tokenAddress || "SOL", | ||
}; | ||
}, | ||
}; | ||
|
||
export default balanceAction; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { Action } from "../types/action"; | ||
import { SolanaAgentKit } from "../agent"; | ||
import { z } from "zod"; | ||
import { sendCompressedAirdrop } from "../tools"; | ||
|
||
const compressedAirdropAction: Action = { | ||
name: "solana_compressed_airdrop", | ||
similes: [ | ||
"ZK Compressed airdrop", | ||
"Airdrop tokens with compression", | ||
"Send compressed SPL airdrop", | ||
"Airdrop to multiple recipients", | ||
], | ||
description: | ||
"Airdrop SPL tokens with ZK Compression (also known as airdropping tokens) to multiple recipients", | ||
examples: [ | ||
[ | ||
{ | ||
input: { | ||
mintAddress: "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN", | ||
amount: 42, | ||
decimals: 6, | ||
recipients: [ | ||
"1nc1nerator11111111111111111111111111111111", | ||
"BrFndAe111111111111111111111111111111111", | ||
], | ||
priorityFeeInLamports: 30000, | ||
shouldLog: true, | ||
}, | ||
output: { | ||
status: "success", | ||
message: "Airdropped 42 tokens to 2 recipients.", | ||
transactionHashes: ["4uyfBN...", "9XsF2N..."], | ||
}, | ||
explanation: | ||
"Airdrops 42 tokens (with 6 decimals) to 2 recipients, optionally logging progress to stdout.", | ||
}, | ||
], | ||
], | ||
// Validate inputs with zod | ||
schema: z.object({ | ||
mintAddress: z | ||
.string() | ||
.min(1) | ||
.describe("Mint address of the token, e.g., 'JUPy...'"), | ||
amount: z | ||
.number() | ||
.positive() | ||
.describe("Number of tokens to airdrop per recipient, e.g., 42"), | ||
decimals: z | ||
.number() | ||
.nonnegative() | ||
.int() | ||
.describe("Decimals of the token, e.g., 6"), | ||
recipients: z | ||
.array(z.string()) | ||
.nonempty() | ||
.describe("Array of recipient addresses, e.g., ['1nc1n...']"), | ||
priorityFeeInLamports: z | ||
.number() | ||
.optional() | ||
.describe("Priority fee in lamports (default is 30_000)"), | ||
shouldLog: z | ||
.boolean() | ||
.optional() | ||
.describe("Whether to log progress to stdout (default is false)"), | ||
}), | ||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => { | ||
try { | ||
const { | ||
mintAddress, | ||
amount, | ||
decimals, | ||
recipients, | ||
priorityFeeInLamports, | ||
shouldLog, | ||
} = input; | ||
|
||
// Call your airdrop method on the SolanaAgentKit | ||
const txs = await sendCompressedAirdrop( | ||
mintAddress, | ||
amount, | ||
decimals, | ||
recipients, | ||
priorityFeeInLamports || 30_000, | ||
shouldLog || false, | ||
); | ||
|
||
return { | ||
status: "success", | ||
message: `Airdropped ${amount} tokens to ${recipients.length} recipients.`, | ||
transactionHashes: txs, | ||
}; | ||
} catch (error: any) { | ||
return { | ||
status: "error", | ||
message: `Failed to airdrop tokens: ${error.message}`, | ||
code: error.code || "UNKNOWN_ERROR", | ||
}; | ||
} | ||
}, | ||
}; | ||
|
||
export default compressedAirdropAction; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { Action } from "../types/action"; | ||
import { SolanaAgentKit } from "../agent"; | ||
import { z } from "zod"; | ||
import { PublicKey } from "@solana/web3.js"; | ||
import { create_gibwork_task } from "../tools"; | ||
|
||
const createGibworkTaskAction: Action = { | ||
name: "solana_create_gibwork_task", | ||
similes: [ | ||
"create task", | ||
"post job", | ||
"create gig", | ||
"post task", | ||
"create work", | ||
"new task on gibwork", | ||
], | ||
description: | ||
"Create a new task on the Gibwork platform with payment in SPL tokens", | ||
examples: [ | ||
[ | ||
{ | ||
input: { | ||
title: "Build a Solana dApp", | ||
content: "Create a simple Solana dApp with React frontend", | ||
requirements: "Experience with Rust and React", | ||
tags: ["solana", "rust", "react"], | ||
tokenMintAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", | ||
tokenAmount: 100, | ||
}, | ||
output: { | ||
status: "success", | ||
taskId: "task_123", | ||
signature: "3YKpM1...", | ||
message: "Successfully created task: Build a Solana dApp", | ||
}, | ||
explanation: "Create a new task on Gibwork with 100 USDC payment", | ||
}, | ||
], | ||
], | ||
schema: z.object({ | ||
title: z.string().min(1).describe("Title of the task"), | ||
content: z.string().min(1).describe("Description of the task"), | ||
requirements: z | ||
.string() | ||
.min(1) | ||
.describe("Requirements to complete the task"), | ||
tags: z | ||
.array(z.string()) | ||
.min(1) | ||
.describe("List of tags associated with the task"), | ||
tokenMintAddress: z.string().describe("Token mint address for payment"), | ||
tokenAmount: z.number().positive().describe("Payment amount for the task"), | ||
payer: z | ||
.string() | ||
.optional() | ||
.describe("Optional payer address (defaults to wallet address)"), | ||
}), | ||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => { | ||
try { | ||
const responseData = await create_gibwork_task( | ||
agent, | ||
input.title, | ||
input.content, | ||
input.requirements, | ||
input.tags, | ||
new PublicKey(input.tokenMintAddress), | ||
input.tokenAmount, | ||
input.payer ? new PublicKey(input.payer) : undefined, | ||
); | ||
|
||
return { | ||
status: "success", | ||
taskId: responseData.taskId, | ||
signature: responseData.signature, | ||
message: `Successfully created task: ${input.title}`, | ||
}; | ||
} catch (error: any) { | ||
return { | ||
status: "error", | ||
message: `Failed to create task: ${error.message}`, | ||
}; | ||
} | ||
}, | ||
}; | ||
|
||
export default createGibworkTaskAction; |
Oops, something went wrong.