intentkit 0.8.11__py3-none-any.whl → 0.8.12__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/graph.py +4 -0
- intentkit/abstracts/skill.py +2 -140
- intentkit/clients/twitter.py +35 -28
- intentkit/core/agent.py +2 -374
- intentkit/core/asset.py +63 -16
- intentkit/core/engine.py +16 -7
- intentkit/core/scheduler.py +8 -8
- intentkit/models/agent.py +109 -94
- intentkit/models/agent_schema.json +6 -9
- intentkit/models/llm.csv +15 -12
- intentkit/models/skill.py +38 -40
- intentkit/skills/acolyt/__init__.py +2 -9
- intentkit/skills/acolyt/base.py +2 -5
- intentkit/skills/aixbt/__init__.py +2 -13
- intentkit/skills/aixbt/base.py +0 -4
- intentkit/skills/aixbt/projects.py +1 -2
- intentkit/skills/allora/__init__.py +2 -9
- intentkit/skills/allora/base.py +2 -5
- intentkit/skills/base.py +168 -27
- intentkit/skills/basename/__init__.py +1 -3
- intentkit/skills/carv/__init__.py +116 -121
- intentkit/skills/carv/base.py +184 -185
- intentkit/skills/casino/__init__.py +4 -15
- intentkit/skills/casino/base.py +0 -4
- intentkit/skills/casino/deck_draw.py +4 -6
- intentkit/skills/casino/deck_shuffle.py +5 -4
- intentkit/skills/casino/dice_roll.py +1 -2
- intentkit/skills/cdp/__init__.py +0 -5
- intentkit/skills/cdp/base.py +0 -4
- intentkit/skills/cdp/schema.json +1 -17
- intentkit/skills/chainlist/__init__.py +2 -7
- intentkit/skills/chainlist/base.py +0 -4
- intentkit/skills/common/__init__.py +2 -9
- intentkit/skills/common/base.py +0 -4
- intentkit/skills/cookiefun/__init__.py +6 -9
- intentkit/skills/cookiefun/base.py +0 -4
- intentkit/skills/cryptocompare/__init__.py +7 -24
- intentkit/skills/cryptocompare/base.py +4 -18
- intentkit/skills/cryptocompare/fetch_news.py +1 -1
- intentkit/skills/cryptocompare/fetch_price.py +1 -1
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +1 -1
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +1 -1
- intentkit/skills/cryptocompare/fetch_top_volume.py +1 -1
- intentkit/skills/cryptocompare/fetch_trading_signals.py +1 -1
- intentkit/skills/cryptopanic/__init__.py +3 -6
- intentkit/skills/cryptopanic/base.py +53 -55
- intentkit/skills/cryptopanic/fetch_crypto_news.py +0 -2
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +1 -3
- intentkit/skills/dapplooker/__init__.py +2 -9
- intentkit/skills/dapplooker/base.py +2 -5
- intentkit/skills/defillama/__init__.py +24 -74
- intentkit/skills/defillama/base.py +3 -13
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +2 -2
- intentkit/skills/defillama/coins/fetch_block.py +2 -2
- intentkit/skills/defillama/coins/fetch_current_prices.py +2 -2
- intentkit/skills/defillama/coins/fetch_first_price.py +2 -2
- intentkit/skills/defillama/coins/fetch_historical_prices.py +2 -2
- intentkit/skills/defillama/coins/fetch_price_chart.py +2 -2
- intentkit/skills/defillama/coins/fetch_price_percentage.py +2 -2
- intentkit/skills/defillama/fees/fetch_fees_overview.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +2 -2
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +2 -2
- intentkit/skills/defillama/tvl/fetch_chains.py +2 -2
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +2 -2
- intentkit/skills/defillama/tvl/fetch_protocol.py +2 -2
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +2 -2
- intentkit/skills/defillama/tvl/fetch_protocols.py +2 -2
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +2 -2
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +2 -2
- intentkit/skills/defillama/volumes/fetch_options_overview.py +2 -2
- intentkit/skills/defillama/yields/fetch_pool_chart.py +2 -2
- intentkit/skills/defillama/yields/fetch_pools.py +2 -2
- intentkit/skills/dexscreener/__init__.py +97 -102
- intentkit/skills/dexscreener/base.py +125 -130
- intentkit/skills/dexscreener/get_pair_info.py +2 -3
- intentkit/skills/dexscreener/get_token_pairs.py +2 -3
- intentkit/skills/dexscreener/get_tokens_info.py +2 -3
- intentkit/skills/dexscreener/search_token.py +2 -4
- intentkit/skills/dune_analytics/__init__.py +4 -6
- intentkit/skills/dune_analytics/base.py +50 -52
- intentkit/skills/dune_analytics/fetch_kol_buys.py +0 -2
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +0 -2
- intentkit/skills/elfa/__init__.py +5 -18
- intentkit/skills/elfa/base.py +8 -10
- intentkit/skills/enso/__init__.py +9 -29
- intentkit/skills/enso/base.py +3 -6
- intentkit/skills/enso/networks.py +1 -6
- intentkit/skills/enso/route.py +4 -8
- intentkit/skills/enso/tokens.py +2 -12
- intentkit/skills/erc20/__init__.py +1 -5
- intentkit/skills/erc721/__init__.py +1 -3
- intentkit/skills/firecrawl/__init__.py +5 -18
- intentkit/skills/firecrawl/base.py +2 -5
- intentkit/skills/firecrawl/clear.py +3 -6
- intentkit/skills/firecrawl/crawl.py +10 -9
- intentkit/skills/firecrawl/query.py +3 -1
- intentkit/skills/firecrawl/scrape.py +10 -14
- intentkit/skills/firecrawl/utils.py +39 -31
- intentkit/skills/github/__init__.py +2 -7
- intentkit/skills/github/base.py +0 -4
- intentkit/skills/heurist/__init__.py +8 -27
- intentkit/skills/heurist/base.py +2 -5
- intentkit/skills/heurist/image_generation_animagine_xl.py +5 -5
- intentkit/skills/heurist/image_generation_arthemy_comics.py +5 -5
- intentkit/skills/heurist/image_generation_arthemy_real.py +5 -5
- intentkit/skills/heurist/image_generation_braindance.py +5 -5
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +5 -5
- intentkit/skills/heurist/image_generation_flux_1_dev.py +5 -5
- intentkit/skills/heurist/image_generation_sdxl.py +5 -5
- intentkit/skills/http/__init__.py +4 -15
- intentkit/skills/http/base.py +0 -4
- intentkit/skills/lifi/__init__.py +1 -6
- intentkit/skills/lifi/base.py +0 -4
- intentkit/skills/lifi/token_execute.py +1 -4
- intentkit/skills/lifi/token_quote.py +1 -3
- intentkit/skills/moralis/__init__.py +3 -7
- intentkit/skills/moralis/base.py +2 -5
- intentkit/skills/morpho/__init__.py +1 -3
- intentkit/skills/nation/__init__.py +2 -7
- intentkit/skills/nation/base.py +4 -7
- intentkit/skills/openai/__init__.py +5 -18
- intentkit/skills/openai/base.py +8 -10
- intentkit/skills/openai/dalle_image_generation.py +2 -5
- intentkit/skills/openai/gpt_image_generation.py +2 -5
- intentkit/skills/openai/gpt_image_to_image.py +2 -5
- intentkit/skills/openai/image_to_text.py +2 -5
- intentkit/skills/portfolio/__init__.py +11 -35
- intentkit/skills/portfolio/base.py +2 -5
- intentkit/skills/pyth/__init__.py +1 -5
- intentkit/skills/slack/__init__.py +5 -17
- intentkit/skills/slack/base.py +0 -4
- intentkit/skills/supabase/__init__.py +7 -23
- intentkit/skills/supabase/base.py +0 -4
- intentkit/skills/superfluid/__init__.py +1 -3
- intentkit/skills/system/__init__.py +7 -24
- intentkit/skills/system/add_autonomous_task.py +2 -2
- intentkit/skills/system/delete_autonomous_task.py +2 -2
- intentkit/skills/system/edit_autonomous_task.py +2 -4
- intentkit/skills/system/list_autonomous_tasks.py +2 -2
- 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 +2 -5
- intentkit/skills/tavily/tavily_extract.py +1 -2
- intentkit/skills/tavily/tavily_search.py +3 -3
- intentkit/skills/token/__init__.py +5 -10
- intentkit/skills/token/base.py +2 -6
- intentkit/skills/twitter/__init__.py +11 -35
- intentkit/skills/twitter/base.py +18 -29
- intentkit/skills/twitter/follow_user.py +1 -4
- intentkit/skills/twitter/get_mentions.py +2 -8
- intentkit/skills/twitter/get_timeline.py +3 -10
- intentkit/skills/twitter/get_user_by_username.py +1 -4
- intentkit/skills/twitter/get_user_tweets.py +3 -10
- intentkit/skills/twitter/like_tweet.py +1 -4
- intentkit/skills/twitter/post_tweet.py +3 -5
- intentkit/skills/twitter/reply_tweet.py +3 -5
- intentkit/skills/twitter/retweet.py +1 -4
- intentkit/skills/twitter/search_tweets.py +3 -10
- intentkit/skills/unrealspeech/__init__.py +2 -7
- intentkit/skills/unrealspeech/base.py +0 -4
- intentkit/skills/venice_audio/__init__.py +99 -106
- intentkit/skills/venice_audio/base.py +118 -121
- intentkit/skills/venice_audio/venice_audio.py +1 -5
- intentkit/skills/venice_image/__init__.py +147 -154
- intentkit/skills/venice_image/base.py +185 -192
- intentkit/skills/web_scraper/__init__.py +5 -18
- intentkit/skills/web_scraper/base.py +20 -4
- intentkit/skills/web_scraper/document_indexer.py +6 -4
- intentkit/skills/web_scraper/scrape_and_index.py +11 -10
- intentkit/skills/web_scraper/utils.py +38 -38
- intentkit/skills/web_scraper/website_indexer.py +7 -8
- intentkit/skills/weth/__init__.py +1 -5
- intentkit/skills/wow/__init__.py +1 -5
- intentkit/skills/xmtp/__init__.py +4 -15
- {intentkit-0.8.11.dist-info → intentkit-0.8.12.dist-info}/METADATA +1 -1
- {intentkit-0.8.11.dist-info → intentkit-0.8.12.dist-info}/RECORD +183 -183
- {intentkit-0.8.11.dist-info → intentkit-0.8.12.dist-info}/WHEEL +0 -0
- {intentkit-0.8.11.dist-info → intentkit-0.8.12.dist-info}/licenses/LICENSE +0 -0
|
@@ -69,9 +69,9 @@ class DefiLlamaFetchStablecoinCharts(DefiLlamaBaseTool):
|
|
|
69
69
|
|
|
70
70
|
Example:
|
|
71
71
|
charts_tool = DefiLlamaFetchStablecoinCharts(
|
|
72
|
-
|
|
72
|
+
,
|
|
73
73
|
agent_id="agent_123",
|
|
74
|
-
|
|
74
|
+
agent=agent
|
|
75
75
|
)
|
|
76
76
|
# Get all chains data
|
|
77
77
|
result = await charts_tool._arun(stablecoin_id="1")
|
|
@@ -42,9 +42,9 @@ class DefiLlamaFetchStablecoinPrices(DefiLlamaBaseTool):
|
|
|
42
42
|
|
|
43
43
|
Example:
|
|
44
44
|
prices_tool = DefiLlamaFetchStablecoinPrices(
|
|
45
|
-
|
|
45
|
+
,
|
|
46
46
|
agent_id="agent_123",
|
|
47
|
-
|
|
47
|
+
agent=agent
|
|
48
48
|
)
|
|
49
49
|
result = await prices_tool._arun()
|
|
50
50
|
"""
|
|
@@ -87,9 +87,9 @@ class DefiLlamaFetchStablecoins(DefiLlamaBaseTool):
|
|
|
87
87
|
|
|
88
88
|
Example:
|
|
89
89
|
stablecoins_tool = DefiLlamaFetchStablecoins(
|
|
90
|
-
|
|
90
|
+
,
|
|
91
91
|
agent_id="agent_123",
|
|
92
|
-
|
|
92
|
+
agent=agent
|
|
93
93
|
)
|
|
94
94
|
result = await stablecoins_tool._arun()
|
|
95
95
|
"""
|
|
@@ -48,9 +48,9 @@ class DefiLlamaFetchChainHistoricalTvl(DefiLlamaBaseTool):
|
|
|
48
48
|
|
|
49
49
|
Example:
|
|
50
50
|
tvl_tool = DefiLlamaFetchChainHistoricalTvl(
|
|
51
|
-
|
|
51
|
+
,
|
|
52
52
|
agent_id="agent_123",
|
|
53
|
-
|
|
53
|
+
agent=agent
|
|
54
54
|
)
|
|
55
55
|
result = await tvl_tool._arun(chain="ethereum")
|
|
56
56
|
"""
|
|
@@ -144,9 +144,9 @@ class DefiLlamaFetchProtocol(DefiLlamaBaseTool):
|
|
|
144
144
|
|
|
145
145
|
Example:
|
|
146
146
|
protocol_tool = DefiLlamaFetchProtocol(
|
|
147
|
-
|
|
147
|
+
,
|
|
148
148
|
agent_id="agent_123",
|
|
149
|
-
|
|
149
|
+
agent=agent
|
|
150
150
|
)
|
|
151
151
|
result = await protocol_tool._arun(protocol="aave")
|
|
152
152
|
"""
|
|
@@ -38,9 +38,9 @@ class DefiLlamaFetchProtocolCurrentTvl(DefiLlamaBaseTool):
|
|
|
38
38
|
|
|
39
39
|
Example:
|
|
40
40
|
tvl_tool = DefiLlamaFetchProtocolCurrentTvl(
|
|
41
|
-
|
|
41
|
+
,
|
|
42
42
|
agent_id="agent_123",
|
|
43
|
-
|
|
43
|
+
agent=agent
|
|
44
44
|
)
|
|
45
45
|
result = await tvl_tool._arun(protocol="aave")
|
|
46
46
|
"""
|
|
@@ -128,9 +128,9 @@ class DefiLlamaFetchProtocols(DefiLlamaBaseTool):
|
|
|
128
128
|
|
|
129
129
|
Example:
|
|
130
130
|
protocols_tool = DefiLlamaFetchProtocols(
|
|
131
|
-
|
|
131
|
+
,
|
|
132
132
|
agent_id="agent_123",
|
|
133
|
-
|
|
133
|
+
agent=agent
|
|
134
134
|
)
|
|
135
135
|
result = await protocols_tool._arun()
|
|
136
136
|
"""
|
|
@@ -118,9 +118,9 @@ class DefiLlamaFetchDexOverview(DefiLlamaBaseTool):
|
|
|
118
118
|
|
|
119
119
|
Example:
|
|
120
120
|
overview_tool = DefiLlamaFetchDexOverview(
|
|
121
|
-
|
|
121
|
+
,
|
|
122
122
|
agent_id="agent_123",
|
|
123
|
-
|
|
123
|
+
agent=agent
|
|
124
124
|
)
|
|
125
125
|
result = await overview_tool._arun()
|
|
126
126
|
"""
|
|
@@ -78,9 +78,9 @@ class DefiLlamaFetchDexSummary(DefiLlamaBaseTool):
|
|
|
78
78
|
|
|
79
79
|
Example:
|
|
80
80
|
summary_tool = DefiLlamaFetchDexSummary(
|
|
81
|
-
|
|
81
|
+
,
|
|
82
82
|
agent_id="agent_123",
|
|
83
|
-
|
|
83
|
+
agent=agent
|
|
84
84
|
)
|
|
85
85
|
result = await summary_tool._arun(protocol="uniswap")
|
|
86
86
|
"""
|
|
@@ -86,9 +86,9 @@ class DefiLlamaFetchOptionsOverview(DefiLlamaBaseTool):
|
|
|
86
86
|
|
|
87
87
|
Example:
|
|
88
88
|
overview_tool = DefiLlamaFetchOptionsOverview(
|
|
89
|
-
|
|
89
|
+
,
|
|
90
90
|
agent_id="agent_123",
|
|
91
|
-
|
|
91
|
+
agent=agent
|
|
92
92
|
)
|
|
93
93
|
result = await overview_tool._arun()
|
|
94
94
|
"""
|
|
@@ -54,9 +54,9 @@ class DefiLlamaFetchPoolChart(DefiLlamaBaseTool):
|
|
|
54
54
|
|
|
55
55
|
Example:
|
|
56
56
|
chart_tool = DefiLlamaFetchPoolChart(
|
|
57
|
-
|
|
57
|
+
,
|
|
58
58
|
agent_id="agent_123",
|
|
59
|
-
|
|
59
|
+
agent=agent
|
|
60
60
|
)
|
|
61
61
|
result = await chart_tool._arun(
|
|
62
62
|
pool_id="747c1d2a-c668-4682-b9f9-296708a3dd90"
|
|
@@ -1,102 +1,97 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from typing import Optional, TypedDict
|
|
3
|
-
|
|
4
|
-
from intentkit.
|
|
5
|
-
from intentkit.skills.base import
|
|
6
|
-
from intentkit.skills.dexscreener.
|
|
7
|
-
from intentkit.skills.dexscreener.
|
|
8
|
-
from intentkit.skills.dexscreener.
|
|
9
|
-
from intentkit.skills.dexscreener.
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
logger.warning(f"Unknown Dexscreener skill: {name}")
|
|
99
|
-
return None
|
|
100
|
-
|
|
101
|
-
_cache[name] = skill_class(skill_store=store)
|
|
102
|
-
return _cache[name]
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Optional, TypedDict
|
|
3
|
+
|
|
4
|
+
from intentkit.skills.base import SkillConfig, SkillState
|
|
5
|
+
from intentkit.skills.dexscreener.base import DexScreenerBaseTool
|
|
6
|
+
from intentkit.skills.dexscreener.get_pair_info import GetPairInfo
|
|
7
|
+
from intentkit.skills.dexscreener.get_token_pairs import GetTokenPairs
|
|
8
|
+
from intentkit.skills.dexscreener.get_tokens_info import GetTokensInfo
|
|
9
|
+
from intentkit.skills.dexscreener.search_token import SearchToken
|
|
10
|
+
|
|
11
|
+
# Cache skills at the system level, because they are stateless
|
|
12
|
+
_cache: dict[str, DexScreenerBaseTool] = {}
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SkillStates(TypedDict):
|
|
18
|
+
search_token: SkillState
|
|
19
|
+
get_pair_info: SkillState
|
|
20
|
+
get_token_pairs: SkillState
|
|
21
|
+
get_tokens_info: SkillState
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
_SKILL_NAME_TO_CLASS_MAP: dict[str, type[DexScreenerBaseTool]] = {
|
|
25
|
+
"search_token": SearchToken,
|
|
26
|
+
"get_pair_info": GetPairInfo,
|
|
27
|
+
"get_token_pairs": GetTokenPairs,
|
|
28
|
+
"get_tokens_info": GetTokensInfo,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Config(SkillConfig):
|
|
33
|
+
"""Configuration for DexScreener skills."""
|
|
34
|
+
|
|
35
|
+
enabled: bool
|
|
36
|
+
states: SkillStates
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
async def get_skills(
|
|
40
|
+
config: "Config",
|
|
41
|
+
is_private: bool,
|
|
42
|
+
**_,
|
|
43
|
+
) -> list[DexScreenerBaseTool]:
|
|
44
|
+
"""Get all DexScreener skills.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
config: The configuration for DexScreener skills.
|
|
48
|
+
is_private: Whether to include private skills.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
A list of DexScreener skills.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
available_skills = []
|
|
55
|
+
|
|
56
|
+
# Include skills based on their state
|
|
57
|
+
for skill_name, state in config["states"].items():
|
|
58
|
+
if state == "disabled":
|
|
59
|
+
continue
|
|
60
|
+
elif state == "public" or (state == "private" and is_private):
|
|
61
|
+
available_skills.append(skill_name)
|
|
62
|
+
|
|
63
|
+
logger.debug(f"Available Skills {available_skills}")
|
|
64
|
+
logger.debug(f"Hardcoded Skills {_SKILL_NAME_TO_CLASS_MAP}")
|
|
65
|
+
|
|
66
|
+
# Get each skill using the cached getter
|
|
67
|
+
result = []
|
|
68
|
+
for name in available_skills:
|
|
69
|
+
skill = get_dexscreener_skills(name)
|
|
70
|
+
if skill:
|
|
71
|
+
result.append(skill)
|
|
72
|
+
return result
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def get_dexscreener_skills(
|
|
76
|
+
name: str,
|
|
77
|
+
) -> Optional[DexScreenerBaseTool]:
|
|
78
|
+
"""Get a DexScreener skill by name.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
name: The name of the skill to get
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
The requested DexScreener skill
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
# Return from cache immediately if already exists
|
|
88
|
+
if name in _cache:
|
|
89
|
+
return _cache[name]
|
|
90
|
+
|
|
91
|
+
skill_class = _SKILL_NAME_TO_CLASS_MAP.get(name)
|
|
92
|
+
if not skill_class:
|
|
93
|
+
logger.warning(f"Unknown Dexscreener skill: {name}")
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
_cache[name] = skill_class()
|
|
97
|
+
return _cache[name]
|
|
@@ -1,130 +1,125 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import logging
|
|
3
|
-
from typing import Any, Dict, Optional, Tuple
|
|
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, Dict, Optional, Tuple
|
|
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[Optional[Dict[str, Any]], Optional[Dict[str, Any]]]
|
|
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: Optional[Dict[str, Any]] = 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
|