solagent/tools/
fetch_price.rs

1// Copyright 2025 zTgx
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::{actions::fetch_price, parameters_json_schema};
16use rig::{
17    completion::ToolDefinition,
18    tool::{Tool, ToolEmbedding},
19};
20use serde::{Deserialize, Serialize};
21use serde_json::json;
22
23#[derive(Debug, Deserialize)]
24pub struct FetchPriceArgs {
25    token_address: String,
26}
27
28#[derive(Deserialize, Serialize)]
29pub struct FetchPriceOutput {
30    pub price: String,
31}
32
33#[derive(Debug, thiserror::Error)]
34#[error("FetchPrice error")]
35pub struct FetchPriceError;
36
37#[derive(Default)]
38pub struct FetchPrice;
39impl FetchPrice {
40    pub fn new() -> Self {
41        FetchPrice {}
42    }
43}
44
45impl Tool for FetchPrice {
46    const NAME: &'static str = "fetch_price";
47
48    type Error = FetchPriceError;
49    type Args = FetchPriceArgs;
50    type Output = FetchPriceOutput;
51
52    async fn definition(&self, _prompt: String) -> ToolDefinition {
53        ToolDefinition {
54            name: "fetch_price".to_string(),
55            description: r#"
56            Fetch the current price of a Solana token in USDC using Jupiter API.
57
58            input: {
59                token_address: "So11111111111111111111111111111111111111112",
60            },
61
62            "#
63            .to_string(),
64            parameters: parameters_json_schema!(
65                token_address: String,
66            ),
67        }
68    }
69
70    async fn call(&self, args: Self::Args) -> Result<Self::Output, Self::Error> {
71        let token_address = args.token_address;
72        let price = fetch_price(&token_address).await.expect("fetch_price");
73
74        Ok(FetchPriceOutput { price })
75    }
76}
77
78#[derive(Debug, thiserror::Error)]
79#[error("Init error")]
80pub struct InitError;
81
82impl ToolEmbedding for FetchPrice {
83    type InitError = InitError;
84    type Context = ();
85    type State = ();
86
87    fn init(_state: Self::State, _context: Self::Context) -> Result<Self, Self::InitError> {
88        Ok(FetchPrice {})
89    }
90
91    fn embedding_docs(&self) -> Vec<String> {
92        vec!["Fetch the current price of a Solana token in USDC using Jupiter API.".into()]
93    }
94
95    fn context(&self) -> Self::Context {}
96}