intentkit 0.8.6.dev2__py3-none-any.whl → 0.8.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of intentkit might be problematic. Click here for more details.
- intentkit/__init__.py +1 -1
- intentkit/abstracts/agent.py +4 -5
- intentkit/abstracts/engine.py +5 -5
- intentkit/abstracts/graph.py +10 -5
- intentkit/abstracts/skill.py +6 -144
- intentkit/abstracts/twitter.py +4 -5
- intentkit/clients/__init__.py +3 -2
- intentkit/clients/cdp.py +53 -92
- intentkit/clients/twitter.py +56 -57
- intentkit/clients/web3.py +1 -3
- intentkit/config/config.py +5 -0
- intentkit/core/agent.py +16 -388
- intentkit/core/asset.py +64 -18
- intentkit/core/client.py +1 -1
- intentkit/core/credit.py +19 -20
- intentkit/core/engine.py +26 -11
- intentkit/core/node.py +2 -1
- intentkit/core/prompt.py +53 -15
- intentkit/core/scheduler.py +9 -9
- intentkit/core/statistics.py +6 -7
- intentkit/models/agent.py +256 -176
- intentkit/models/agent_data.py +62 -36
- intentkit/models/agent_schema.json +6 -9
- intentkit/models/app_setting.py +6 -6
- intentkit/models/chat.py +28 -24
- intentkit/models/conversation.py +8 -8
- intentkit/models/credit.py +62 -64
- intentkit/models/db.py +8 -7
- intentkit/models/db_mig.py +2 -2
- intentkit/models/llm.csv +15 -12
- intentkit/models/llm.py +18 -16
- intentkit/models/redis.py +2 -3
- intentkit/models/skill.py +62 -66
- intentkit/models/skills.csv +30 -26
- intentkit/models/user.py +46 -21
- intentkit/skills/acolyt/__init__.py +2 -9
- intentkit/skills/acolyt/ask.py +3 -4
- intentkit/skills/acolyt/base.py +4 -9
- intentkit/skills/aixbt/__init__.py +2 -13
- intentkit/skills/aixbt/base.py +1 -7
- intentkit/skills/aixbt/projects.py +14 -15
- intentkit/skills/allora/__init__.py +2 -9
- intentkit/skills/allora/base.py +4 -9
- intentkit/skills/allora/price.py +3 -4
- intentkit/skills/base.py +175 -52
- intentkit/skills/basename/__init__.py +4 -8
- intentkit/skills/carv/__init__.py +115 -121
- intentkit/skills/carv/base.py +184 -185
- intentkit/skills/carv/fetch_news.py +3 -3
- intentkit/skills/carv/onchain_query.py +4 -4
- intentkit/skills/carv/token_info_and_price.py +5 -5
- intentkit/skills/casino/__init__.py +4 -15
- intentkit/skills/casino/base.py +1 -7
- intentkit/skills/casino/deck_draw.py +5 -8
- intentkit/skills/casino/deck_shuffle.py +6 -6
- intentkit/skills/casino/dice_roll.py +2 -4
- intentkit/skills/cdp/__init__.py +3 -10
- intentkit/skills/cdp/base.py +1 -7
- intentkit/skills/cdp/schema.json +1 -17
- intentkit/skills/chainlist/__init__.py +2 -7
- intentkit/skills/chainlist/base.py +1 -7
- intentkit/skills/chainlist/chain_lookup.py +18 -18
- intentkit/skills/common/__init__.py +2 -9
- intentkit/skills/common/base.py +1 -7
- intentkit/skills/common/current_time.py +1 -2
- intentkit/skills/cookiefun/__init__.py +6 -9
- intentkit/skills/cookiefun/base.py +2 -7
- intentkit/skills/cookiefun/get_account_details.py +7 -7
- intentkit/skills/cookiefun/get_account_feed.py +19 -19
- intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
- intentkit/skills/cookiefun/get_sectors.py +3 -3
- intentkit/skills/cookiefun/search_accounts.py +9 -9
- intentkit/skills/cryptocompare/__init__.py +7 -24
- intentkit/skills/cryptocompare/api.py +2 -3
- intentkit/skills/cryptocompare/base.py +10 -24
- intentkit/skills/cryptocompare/fetch_news.py +4 -5
- intentkit/skills/cryptocompare/fetch_price.py +6 -7
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
- intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
- intentkit/skills/cryptopanic/__init__.py +7 -10
- intentkit/skills/cryptopanic/base.py +51 -55
- intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
- intentkit/skills/dapplooker/__init__.py +2 -9
- intentkit/skills/dapplooker/base.py +4 -9
- intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
- intentkit/skills/defillama/__init__.py +24 -74
- intentkit/skills/defillama/api.py +6 -9
- intentkit/skills/defillama/base.py +8 -19
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_block.py +6 -8
- intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
- intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
- intentkit/skills/defillama/config/chains.py +1 -3
- intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
- intentkit/skills/defillama/tests/api_integration.test.py +1 -1
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
- intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
- intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
- intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
- intentkit/skills/defillama/yields/fetch_pools.py +26 -30
- intentkit/skills/dexscreener/__init__.py +97 -102
- intentkit/skills/dexscreener/base.py +125 -130
- intentkit/skills/dexscreener/get_pair_info.py +4 -5
- intentkit/skills/dexscreener/get_token_pairs.py +4 -5
- intentkit/skills/dexscreener/get_tokens_info.py +7 -8
- intentkit/skills/dexscreener/model/search_token_response.py +80 -82
- intentkit/skills/dexscreener/search_token.py +182 -184
- intentkit/skills/dexscreener/utils.py +15 -14
- intentkit/skills/dune_analytics/__init__.py +7 -9
- intentkit/skills/dune_analytics/base.py +48 -52
- intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
- intentkit/skills/elfa/__init__.py +5 -18
- intentkit/skills/elfa/base.py +10 -14
- intentkit/skills/elfa/mention.py +19 -21
- intentkit/skills/elfa/stats.py +4 -4
- intentkit/skills/elfa/tokens.py +12 -12
- intentkit/skills/elfa/utils.py +26 -28
- intentkit/skills/enso/__init__.py +11 -31
- intentkit/skills/enso/base.py +9 -15
- intentkit/skills/enso/best_yield.py +5 -7
- intentkit/skills/enso/networks.py +3 -9
- intentkit/skills/enso/prices.py +2 -4
- intentkit/skills/enso/route.py +6 -12
- intentkit/skills/enso/tokens.py +4 -16
- intentkit/skills/enso/wallet.py +6 -6
- intentkit/skills/erc20/__init__.py +5 -11
- intentkit/skills/erc721/__init__.py +5 -9
- intentkit/skills/firecrawl/__init__.py +5 -18
- intentkit/skills/firecrawl/base.py +4 -9
- intentkit/skills/firecrawl/clear.py +4 -8
- intentkit/skills/firecrawl/crawl.py +19 -19
- intentkit/skills/firecrawl/query.py +4 -3
- intentkit/skills/firecrawl/scrape.py +17 -22
- intentkit/skills/firecrawl/utils.py +50 -42
- intentkit/skills/github/__init__.py +2 -7
- intentkit/skills/github/base.py +1 -7
- intentkit/skills/github/github_search.py +1 -2
- intentkit/skills/heurist/__init__.py +8 -27
- intentkit/skills/heurist/base.py +4 -9
- intentkit/skills/heurist/image_generation_animagine_xl.py +12 -13
- intentkit/skills/heurist/image_generation_arthemy_comics.py +12 -13
- intentkit/skills/heurist/image_generation_arthemy_real.py +12 -13
- intentkit/skills/heurist/image_generation_braindance.py +12 -13
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +12 -13
- intentkit/skills/heurist/image_generation_flux_1_dev.py +12 -13
- intentkit/skills/heurist/image_generation_sdxl.py +12 -13
- intentkit/skills/http/__init__.py +4 -15
- intentkit/skills/http/base.py +1 -7
- intentkit/skills/http/get.py +21 -16
- intentkit/skills/http/post.py +23 -18
- intentkit/skills/http/put.py +23 -18
- intentkit/skills/lifi/__init__.py +5 -10
- intentkit/skills/lifi/base.py +1 -7
- intentkit/skills/lifi/token_execute.py +14 -17
- intentkit/skills/lifi/token_quote.py +7 -9
- intentkit/skills/lifi/utils.py +16 -16
- intentkit/skills/moralis/__init__.py +6 -10
- intentkit/skills/moralis/api.py +6 -7
- intentkit/skills/moralis/base.py +5 -10
- intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
- intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
- intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
- intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
- intentkit/skills/morpho/__init__.py +5 -9
- intentkit/skills/nation/__init__.py +4 -9
- intentkit/skills/nation/base.py +5 -10
- intentkit/skills/nation/nft_check.py +3 -4
- intentkit/skills/onchain.py +23 -0
- intentkit/skills/openai/__init__.py +17 -18
- intentkit/skills/openai/base.py +10 -14
- intentkit/skills/openai/dalle_image_generation.py +3 -8
- intentkit/skills/openai/gpt_avatar_generator.py +102 -0
- intentkit/skills/openai/gpt_image_generation.py +4 -8
- intentkit/skills/openai/gpt_image_mini_generator.py +91 -0
- intentkit/skills/openai/gpt_image_to_image.py +4 -8
- intentkit/skills/openai/image_to_text.py +3 -7
- intentkit/skills/openai/schema.json +32 -0
- intentkit/skills/portfolio/__init__.py +11 -35
- intentkit/skills/portfolio/base.py +33 -19
- intentkit/skills/portfolio/token_balances.py +21 -21
- intentkit/skills/portfolio/wallet_approvals.py +17 -18
- intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
- intentkit/skills/portfolio/wallet_history.py +31 -31
- intentkit/skills/portfolio/wallet_net_worth.py +13 -13
- intentkit/skills/portfolio/wallet_nfts.py +19 -19
- intentkit/skills/portfolio/wallet_profitability.py +18 -18
- intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
- intentkit/skills/portfolio/wallet_stats.py +3 -3
- intentkit/skills/portfolio/wallet_swaps.py +19 -19
- intentkit/skills/pyth/__init__.py +4 -10
- intentkit/skills/skills.toml +4 -0
- intentkit/skills/slack/__init__.py +5 -17
- intentkit/skills/slack/base.py +3 -9
- intentkit/skills/slack/get_channel.py +8 -8
- intentkit/skills/slack/get_message.py +9 -9
- intentkit/skills/slack/schedule_message.py +5 -5
- intentkit/skills/slack/send_message.py +3 -5
- intentkit/skills/supabase/__init__.py +7 -23
- intentkit/skills/supabase/base.py +1 -7
- intentkit/skills/supabase/delete_data.py +4 -4
- intentkit/skills/supabase/fetch_data.py +12 -12
- intentkit/skills/supabase/insert_data.py +4 -4
- intentkit/skills/supabase/invoke_function.py +6 -6
- intentkit/skills/supabase/update_data.py +6 -6
- intentkit/skills/supabase/upsert_data.py +4 -4
- intentkit/skills/superfluid/__init__.py +5 -9
- intentkit/skills/system/__init__.py +7 -24
- intentkit/skills/system/add_autonomous_task.py +10 -12
- intentkit/skills/system/delete_autonomous_task.py +2 -2
- intentkit/skills/system/edit_autonomous_task.py +14 -18
- intentkit/skills/system/list_autonomous_tasks.py +3 -5
- intentkit/skills/system/read_agent_api_key.py +6 -4
- intentkit/skills/system/regenerate_agent_api_key.py +6 -4
- intentkit/skills/tavily/__init__.py +3 -12
- intentkit/skills/tavily/base.py +4 -9
- intentkit/skills/tavily/tavily_extract.py +2 -4
- intentkit/skills/tavily/tavily_search.py +4 -6
- intentkit/skills/token/__init__.py +5 -10
- intentkit/skills/token/base.py +7 -11
- intentkit/skills/token/erc20_transfers.py +19 -19
- intentkit/skills/token/token_analytics.py +3 -3
- intentkit/skills/token/token_price.py +13 -13
- intentkit/skills/token/token_search.py +9 -9
- intentkit/skills/twitter/__init__.py +11 -35
- intentkit/skills/twitter/base.py +22 -34
- intentkit/skills/twitter/follow_user.py +2 -6
- intentkit/skills/twitter/get_mentions.py +5 -12
- intentkit/skills/twitter/get_timeline.py +4 -12
- intentkit/skills/twitter/get_user_by_username.py +2 -6
- intentkit/skills/twitter/get_user_tweets.py +5 -13
- intentkit/skills/twitter/like_tweet.py +2 -6
- intentkit/skills/twitter/post_tweet.py +6 -9
- intentkit/skills/twitter/reply_tweet.py +6 -9
- intentkit/skills/twitter/retweet.py +2 -6
- intentkit/skills/twitter/search_tweets.py +4 -12
- intentkit/skills/unrealspeech/__init__.py +2 -7
- intentkit/skills/unrealspeech/base.py +2 -8
- intentkit/skills/unrealspeech/text_to_speech.py +8 -8
- intentkit/skills/venice_audio/__init__.py +98 -106
- intentkit/skills/venice_audio/base.py +117 -121
- intentkit/skills/venice_audio/input.py +41 -41
- intentkit/skills/venice_audio/venice_audio.py +7 -11
- intentkit/skills/venice_image/__init__.py +147 -154
- intentkit/skills/venice_image/api.py +138 -138
- intentkit/skills/venice_image/base.py +185 -192
- intentkit/skills/venice_image/config.py +33 -35
- intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
- intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
- intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
- intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
- intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
- intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
- intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
- intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
- intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
- intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
- intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
- intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
- intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
- intentkit/skills/venice_image/utils.py +77 -78
- intentkit/skills/web_scraper/__init__.py +5 -18
- intentkit/skills/web_scraper/base.py +21 -7
- intentkit/skills/web_scraper/document_indexer.py +7 -6
- intentkit/skills/web_scraper/scrape_and_index.py +15 -15
- intentkit/skills/web_scraper/utils.py +62 -63
- intentkit/skills/web_scraper/website_indexer.py +17 -19
- intentkit/skills/weth/__init__.py +5 -11
- intentkit/skills/wow/__init__.py +5 -11
- intentkit/skills/x402/__init__.py +61 -0
- intentkit/skills/x402/ask_agent.py +98 -0
- intentkit/skills/x402/base.py +99 -0
- intentkit/skills/x402/http_request.py +117 -0
- intentkit/skills/x402/schema.json +45 -0
- intentkit/skills/x402/x402.webp +0 -0
- intentkit/skills/xmtp/__init__.py +4 -15
- intentkit/skills/xmtp/base.py +5 -5
- intentkit/skills/xmtp/price.py +6 -6
- intentkit/skills/xmtp/swap.py +6 -8
- intentkit/skills/xmtp/transfer.py +4 -6
- intentkit/utils/error.py +2 -2
- intentkit/utils/logging.py +2 -4
- intentkit/utils/s3.py +8 -9
- intentkit/utils/schema.py +100 -0
- intentkit/utils/slack_alert.py +7 -8
- {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +3 -4
- intentkit-0.8.17.dist-info/RECORD +466 -0
- intentkit/models/generator.py +0 -347
- intentkit-0.8.6.dev2.dist-info/RECORD +0 -457
- {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
- {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,130 +1,125 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import logging
|
|
3
|
-
from typing import Any
|
|
4
|
-
|
|
5
|
-
import httpx
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
from intentkit.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"""
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
"
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
logger.
|
|
89
|
-
f"DexScreener API
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
"status_code": status_code, # Include if available
|
|
127
|
-
"details": str(e),
|
|
128
|
-
"url": url,
|
|
129
|
-
}
|
|
130
|
-
return None, error_details # Return unexpected error
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from intentkit.skills.base import IntentKitSkill
|
|
8
|
+
from intentkit.skills.dexscreener.utils import DEXSCREENER_BASE_URL
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
# ApiResult still represents (success_data, error_data)
|
|
13
|
+
ApiResult = tuple[dict[str, Any] | None, dict[str, Any] | None]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class DexScreenerBaseTool(IntentKitSkill):
|
|
17
|
+
"""
|
|
18
|
+
Generic base class for tools interacting with the Dex Screener API.
|
|
19
|
+
Handles shared logic like API calls and error reporting via return values.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
base_url: str = DEXSCREENER_BASE_URL
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def category(self) -> str:
|
|
26
|
+
return "dexscreener"
|
|
27
|
+
|
|
28
|
+
async def _get(
|
|
29
|
+
self,
|
|
30
|
+
path: str,
|
|
31
|
+
params: dict[str, Any] | None = None,
|
|
32
|
+
) -> ApiResult:
|
|
33
|
+
"""
|
|
34
|
+
Makes an asynchronous GET request to the DexScreener API.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
path: The API endpoint path (e.g., "/dex/search").
|
|
38
|
+
params: Optional dictionary of query parameters.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
A tuple (data, error_details):
|
|
42
|
+
- (dict, None): On HTTP 2xx success with valid JSON response.
|
|
43
|
+
- (None, dict): On any error (API error, connection error,
|
|
44
|
+
JSON parsing error, unexpected error). The dict
|
|
45
|
+
contains details including an 'error_type'.
|
|
46
|
+
"""
|
|
47
|
+
if not path.startswith("/"):
|
|
48
|
+
path = "/" + path
|
|
49
|
+
|
|
50
|
+
url = f"{self.base_url}{path}"
|
|
51
|
+
headers = {"Accept": "application/json"}
|
|
52
|
+
method = "GET"
|
|
53
|
+
|
|
54
|
+
logger.debug(f"Calling DexScreener API: {method} {url} with params: {params}")
|
|
55
|
+
response = None # Define response outside try block for access in except
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
async with httpx.AsyncClient() as client:
|
|
59
|
+
response = await client.request(
|
|
60
|
+
method, url, params=params, headers=headers
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Attempt to parse JSON response text
|
|
64
|
+
try:
|
|
65
|
+
response_data = response.json()
|
|
66
|
+
except json.JSONDecodeError as json_err:
|
|
67
|
+
logger.error(
|
|
68
|
+
f"Failed to parse JSON response from {url}. Status: {response.status_code}. Response text: {response.text}",
|
|
69
|
+
exc_info=True,
|
|
70
|
+
)
|
|
71
|
+
error_details = {
|
|
72
|
+
"error": "Failed to parse DexScreener API response",
|
|
73
|
+
"error_type": "parsing_error",
|
|
74
|
+
"status_code": response.status_code,
|
|
75
|
+
"details": response.text, # Raw text causing the error
|
|
76
|
+
"original_exception": str(json_err),
|
|
77
|
+
"url": url,
|
|
78
|
+
}
|
|
79
|
+
return None, error_details # Return parsing error
|
|
80
|
+
|
|
81
|
+
# Check HTTP status *after* attempting JSON parse
|
|
82
|
+
if response.is_success: # 2xx
|
|
83
|
+
logger.debug(
|
|
84
|
+
f"DexScreener API success response status: {response.status_code}"
|
|
85
|
+
)
|
|
86
|
+
return response_data, None # Success
|
|
87
|
+
else: # 4xx/5xx
|
|
88
|
+
logger.warning(
|
|
89
|
+
f"DexScreener API returned error status: {response.status_code} - {response.text}"
|
|
90
|
+
)
|
|
91
|
+
error_details = {
|
|
92
|
+
"error": "DexScreener API request failed",
|
|
93
|
+
"error_type": "api_error",
|
|
94
|
+
"status_code": response.status_code,
|
|
95
|
+
"response_body": response_data, # Parsed error body if available
|
|
96
|
+
"url": url,
|
|
97
|
+
}
|
|
98
|
+
return None, error_details # Return API error
|
|
99
|
+
|
|
100
|
+
except httpx.RequestError as req_err:
|
|
101
|
+
logger.error(
|
|
102
|
+
f"Request error connecting to DexScreener API: {req_err}", exc_info=True
|
|
103
|
+
)
|
|
104
|
+
error_details = {
|
|
105
|
+
"error": "Failed to connect to DexScreener API",
|
|
106
|
+
"error_type": "connection_error",
|
|
107
|
+
"details": str(req_err),
|
|
108
|
+
"url": url,
|
|
109
|
+
}
|
|
110
|
+
return None, error_details # Return connection error
|
|
111
|
+
|
|
112
|
+
except Exception as e:
|
|
113
|
+
# Catch any other unexpected errors during the process
|
|
114
|
+
logger.exception(
|
|
115
|
+
f"An unexpected error occurred during DexScreener API GET call: {e}"
|
|
116
|
+
)
|
|
117
|
+
status_code = response.status_code if response else None
|
|
118
|
+
error_details = {
|
|
119
|
+
"error": "An unexpected error occurred during API call",
|
|
120
|
+
"error_type": "unexpected_error",
|
|
121
|
+
"status_code": status_code, # Include if available
|
|
122
|
+
"details": str(e),
|
|
123
|
+
"url": url,
|
|
124
|
+
}
|
|
125
|
+
return None, error_details # Return unexpected error
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
@@ -39,7 +39,7 @@ class GetPairInfo(DexScreenerBaseTool):
|
|
|
39
39
|
"market cap, FDV, transaction counts, and social links. "
|
|
40
40
|
"Use this tool when you have a specific pair address and need detailed trading metrics."
|
|
41
41
|
)
|
|
42
|
-
args_schema:
|
|
42
|
+
args_schema: type[BaseModel] = GetPairInfoInput
|
|
43
43
|
|
|
44
44
|
async def _arun(
|
|
45
45
|
self,
|
|
@@ -50,10 +50,9 @@ class GetPairInfo(DexScreenerBaseTool):
|
|
|
50
50
|
"""Implementation to get specific pair information."""
|
|
51
51
|
|
|
52
52
|
# Apply rate limiting
|
|
53
|
-
await self.
|
|
54
|
-
user_id=f"{self.category}{self.name}",
|
|
53
|
+
await self.global_rate_limit_by_skill(
|
|
55
54
|
limit=RATE_LIMITS["pairs"],
|
|
56
|
-
|
|
55
|
+
seconds=60,
|
|
57
56
|
)
|
|
58
57
|
|
|
59
58
|
logger.info(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field, ValidationError
|
|
5
5
|
|
|
@@ -44,7 +44,7 @@ class GetTokenPairs(DexScreenerBaseTool):
|
|
|
44
44
|
"DEX information, liquidity, volume, and pricing data for each pair. "
|
|
45
45
|
"Use this tool to analyze all available trading venues and liquidity sources for a specific token."
|
|
46
46
|
)
|
|
47
|
-
args_schema:
|
|
47
|
+
args_schema: type[BaseModel] = GetTokenPairsInput
|
|
48
48
|
|
|
49
49
|
async def _arun(
|
|
50
50
|
self,
|
|
@@ -55,10 +55,9 @@ class GetTokenPairs(DexScreenerBaseTool):
|
|
|
55
55
|
"""Implementation to get all pairs for a specific token."""
|
|
56
56
|
|
|
57
57
|
# Apply rate limiting
|
|
58
|
-
await self.
|
|
59
|
-
user_id=f"{self.category}{self.name}",
|
|
58
|
+
await self.global_rate_limit_by_skill(
|
|
60
59
|
limit=RATE_LIMITS["token_pairs"],
|
|
61
|
-
|
|
60
|
+
seconds=60,
|
|
62
61
|
)
|
|
63
62
|
|
|
64
63
|
logger.info(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field, ValidationError, field_validator
|
|
5
5
|
|
|
@@ -29,14 +29,14 @@ class GetTokensInfoInput(BaseModel):
|
|
|
29
29
|
chain_id: str = Field(
|
|
30
30
|
description="The blockchain chain ID (e.g., 'ethereum', 'solana', 'bsc', 'polygon', 'arbitrum', 'base', 'avalanche')"
|
|
31
31
|
)
|
|
32
|
-
token_addresses:
|
|
32
|
+
token_addresses: list[str] = Field(
|
|
33
33
|
description=f"List of token contract addresses to retrieve info for (maximum {MAX_TOKENS_BATCH} addresses). "
|
|
34
34
|
"Each address should be in the format '0x1234...abcd' for Ethereum-based chains."
|
|
35
35
|
)
|
|
36
36
|
|
|
37
37
|
@field_validator("token_addresses")
|
|
38
38
|
@classmethod
|
|
39
|
-
def validate_token_addresses(cls, v:
|
|
39
|
+
def validate_token_addresses(cls, v: list[str]) -> list[str]:
|
|
40
40
|
if not v:
|
|
41
41
|
raise ValueError("At least one token address is required")
|
|
42
42
|
if len(v) > MAX_TOKENS_BATCH:
|
|
@@ -64,21 +64,20 @@ class GetTokensInfo(DexScreenerBaseTool):
|
|
|
64
64
|
"This is more efficient than making individual calls when you need info for multiple tokens. "
|
|
65
65
|
"Use this tool for portfolio analysis or comparing multiple tokens at once."
|
|
66
66
|
)
|
|
67
|
-
args_schema:
|
|
67
|
+
args_schema: type[BaseModel] = GetTokensInfoInput
|
|
68
68
|
|
|
69
69
|
async def _arun(
|
|
70
70
|
self,
|
|
71
71
|
chain_id: str,
|
|
72
|
-
token_addresses:
|
|
72
|
+
token_addresses: list[str],
|
|
73
73
|
**kwargs: Any,
|
|
74
74
|
) -> str:
|
|
75
75
|
"""Implementation to get information for multiple tokens."""
|
|
76
76
|
|
|
77
77
|
# Apply rate limiting
|
|
78
|
-
await self.
|
|
79
|
-
user_id=f"{self.category}{self.name}",
|
|
78
|
+
await self.global_rate_limit_by_skill(
|
|
80
79
|
limit=RATE_LIMITS["tokens"],
|
|
81
|
-
|
|
80
|
+
seconds=60,
|
|
82
81
|
)
|
|
83
82
|
|
|
84
83
|
logger.info(
|
|
@@ -1,82 +1,80 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
schemaVersion: Optional[str] = None
|
|
82
|
-
pairs: Optional[List[Optional[PairModel]]] = None
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TokenModel(BaseModel):
|
|
5
|
+
address: str | None = None
|
|
6
|
+
name: str | None = None
|
|
7
|
+
symbol: str | None = None
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TxnsDetailsModel(BaseModel):
|
|
11
|
+
buys: int | None = None
|
|
12
|
+
sells: int | None = None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TxnsModel(BaseModel):
|
|
16
|
+
m5: TxnsDetailsModel | None = None
|
|
17
|
+
h1: TxnsDetailsModel | None = None
|
|
18
|
+
h6: TxnsDetailsModel | None = None
|
|
19
|
+
h24: TxnsDetailsModel | None = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class VolumeModel(BaseModel):
|
|
23
|
+
h24: float | None = None
|
|
24
|
+
h6: float | None = None
|
|
25
|
+
h1: float | None = None
|
|
26
|
+
m5: float | None = None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class PriceChangeModel(BaseModel):
|
|
30
|
+
m5: float | None = None
|
|
31
|
+
h1: float | None = None
|
|
32
|
+
h6: float | None = None
|
|
33
|
+
h24: float | None = None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class LiquidityModel(BaseModel):
|
|
37
|
+
usd: float | None = None
|
|
38
|
+
base: float | None = None
|
|
39
|
+
quote: float | None = None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class WebsiteModel(BaseModel):
|
|
43
|
+
label: str | None = None
|
|
44
|
+
url: str | None = None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class SocialModel(BaseModel):
|
|
48
|
+
type: str | None = None
|
|
49
|
+
url: str | None = None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class InfoModel(BaseModel):
|
|
53
|
+
imageUrl: str | None = None
|
|
54
|
+
websites: list[WebsiteModel | None] | None = None
|
|
55
|
+
socials: list[SocialModel | None] | None = None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class PairModel(BaseModel):
|
|
59
|
+
chainId: str | None = None
|
|
60
|
+
dexId: str | None = None
|
|
61
|
+
url: str | None = None
|
|
62
|
+
pairAddress: str | None = None
|
|
63
|
+
labels: list[str | None] | None = None
|
|
64
|
+
baseToken: TokenModel | None = None
|
|
65
|
+
quoteToken: TokenModel | None = None
|
|
66
|
+
priceNative: str | None = None
|
|
67
|
+
priceUsd: str | None = None
|
|
68
|
+
txns: TxnsModel | None = None
|
|
69
|
+
volume: VolumeModel | None = None
|
|
70
|
+
priceChange: PriceChangeModel | None = None
|
|
71
|
+
liquidity: LiquidityModel | None = None
|
|
72
|
+
fdv: float | None = None
|
|
73
|
+
marketCap: float | None = None
|
|
74
|
+
pairCreatedAt: int | None = None
|
|
75
|
+
info: InfoModel | None = None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class SearchTokenResponseModel(BaseModel):
|
|
79
|
+
schemaVersion: str | None = None
|
|
80
|
+
pairs: list[PairModel | None] | None = None
|