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.

Files changed (312) hide show
  1. intentkit/__init__.py +1 -1
  2. intentkit/abstracts/agent.py +4 -5
  3. intentkit/abstracts/engine.py +5 -5
  4. intentkit/abstracts/graph.py +10 -5
  5. intentkit/abstracts/skill.py +6 -144
  6. intentkit/abstracts/twitter.py +4 -5
  7. intentkit/clients/__init__.py +3 -2
  8. intentkit/clients/cdp.py +53 -92
  9. intentkit/clients/twitter.py +56 -57
  10. intentkit/clients/web3.py +1 -3
  11. intentkit/config/config.py +5 -0
  12. intentkit/core/agent.py +16 -388
  13. intentkit/core/asset.py +64 -18
  14. intentkit/core/client.py +1 -1
  15. intentkit/core/credit.py +19 -20
  16. intentkit/core/engine.py +26 -11
  17. intentkit/core/node.py +2 -1
  18. intentkit/core/prompt.py +53 -15
  19. intentkit/core/scheduler.py +9 -9
  20. intentkit/core/statistics.py +6 -7
  21. intentkit/models/agent.py +256 -176
  22. intentkit/models/agent_data.py +62 -36
  23. intentkit/models/agent_schema.json +6 -9
  24. intentkit/models/app_setting.py +6 -6
  25. intentkit/models/chat.py +28 -24
  26. intentkit/models/conversation.py +8 -8
  27. intentkit/models/credit.py +62 -64
  28. intentkit/models/db.py +8 -7
  29. intentkit/models/db_mig.py +2 -2
  30. intentkit/models/llm.csv +15 -12
  31. intentkit/models/llm.py +18 -16
  32. intentkit/models/redis.py +2 -3
  33. intentkit/models/skill.py +62 -66
  34. intentkit/models/skills.csv +30 -26
  35. intentkit/models/user.py +46 -21
  36. intentkit/skills/acolyt/__init__.py +2 -9
  37. intentkit/skills/acolyt/ask.py +3 -4
  38. intentkit/skills/acolyt/base.py +4 -9
  39. intentkit/skills/aixbt/__init__.py +2 -13
  40. intentkit/skills/aixbt/base.py +1 -7
  41. intentkit/skills/aixbt/projects.py +14 -15
  42. intentkit/skills/allora/__init__.py +2 -9
  43. intentkit/skills/allora/base.py +4 -9
  44. intentkit/skills/allora/price.py +3 -4
  45. intentkit/skills/base.py +175 -52
  46. intentkit/skills/basename/__init__.py +4 -8
  47. intentkit/skills/carv/__init__.py +115 -121
  48. intentkit/skills/carv/base.py +184 -185
  49. intentkit/skills/carv/fetch_news.py +3 -3
  50. intentkit/skills/carv/onchain_query.py +4 -4
  51. intentkit/skills/carv/token_info_and_price.py +5 -5
  52. intentkit/skills/casino/__init__.py +4 -15
  53. intentkit/skills/casino/base.py +1 -7
  54. intentkit/skills/casino/deck_draw.py +5 -8
  55. intentkit/skills/casino/deck_shuffle.py +6 -6
  56. intentkit/skills/casino/dice_roll.py +2 -4
  57. intentkit/skills/cdp/__init__.py +3 -10
  58. intentkit/skills/cdp/base.py +1 -7
  59. intentkit/skills/cdp/schema.json +1 -17
  60. intentkit/skills/chainlist/__init__.py +2 -7
  61. intentkit/skills/chainlist/base.py +1 -7
  62. intentkit/skills/chainlist/chain_lookup.py +18 -18
  63. intentkit/skills/common/__init__.py +2 -9
  64. intentkit/skills/common/base.py +1 -7
  65. intentkit/skills/common/current_time.py +1 -2
  66. intentkit/skills/cookiefun/__init__.py +6 -9
  67. intentkit/skills/cookiefun/base.py +2 -7
  68. intentkit/skills/cookiefun/get_account_details.py +7 -7
  69. intentkit/skills/cookiefun/get_account_feed.py +19 -19
  70. intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
  71. intentkit/skills/cookiefun/get_sectors.py +3 -3
  72. intentkit/skills/cookiefun/search_accounts.py +9 -9
  73. intentkit/skills/cryptocompare/__init__.py +7 -24
  74. intentkit/skills/cryptocompare/api.py +2 -3
  75. intentkit/skills/cryptocompare/base.py +10 -24
  76. intentkit/skills/cryptocompare/fetch_news.py +4 -5
  77. intentkit/skills/cryptocompare/fetch_price.py +6 -7
  78. intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
  79. intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
  80. intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
  81. intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
  82. intentkit/skills/cryptopanic/__init__.py +7 -10
  83. intentkit/skills/cryptopanic/base.py +51 -55
  84. intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
  85. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
  86. intentkit/skills/dapplooker/__init__.py +2 -9
  87. intentkit/skills/dapplooker/base.py +4 -9
  88. intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
  89. intentkit/skills/defillama/__init__.py +24 -74
  90. intentkit/skills/defillama/api.py +6 -9
  91. intentkit/skills/defillama/base.py +8 -19
  92. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
  93. intentkit/skills/defillama/coins/fetch_block.py +6 -8
  94. intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
  95. intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
  96. intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
  97. intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
  98. intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
  99. intentkit/skills/defillama/config/chains.py +1 -3
  100. intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
  101. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
  102. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
  103. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
  104. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
  105. intentkit/skills/defillama/tests/api_integration.test.py +1 -1
  106. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
  107. intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
  108. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
  109. intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
  110. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
  111. intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
  112. intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
  113. intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
  114. intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
  115. intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
  116. intentkit/skills/defillama/yields/fetch_pools.py +26 -30
  117. intentkit/skills/dexscreener/__init__.py +97 -102
  118. intentkit/skills/dexscreener/base.py +125 -130
  119. intentkit/skills/dexscreener/get_pair_info.py +4 -5
  120. intentkit/skills/dexscreener/get_token_pairs.py +4 -5
  121. intentkit/skills/dexscreener/get_tokens_info.py +7 -8
  122. intentkit/skills/dexscreener/model/search_token_response.py +80 -82
  123. intentkit/skills/dexscreener/search_token.py +182 -184
  124. intentkit/skills/dexscreener/utils.py +15 -14
  125. intentkit/skills/dune_analytics/__init__.py +7 -9
  126. intentkit/skills/dune_analytics/base.py +48 -52
  127. intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
  128. intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
  129. intentkit/skills/elfa/__init__.py +5 -18
  130. intentkit/skills/elfa/base.py +10 -14
  131. intentkit/skills/elfa/mention.py +19 -21
  132. intentkit/skills/elfa/stats.py +4 -4
  133. intentkit/skills/elfa/tokens.py +12 -12
  134. intentkit/skills/elfa/utils.py +26 -28
  135. intentkit/skills/enso/__init__.py +11 -31
  136. intentkit/skills/enso/base.py +9 -15
  137. intentkit/skills/enso/best_yield.py +5 -7
  138. intentkit/skills/enso/networks.py +3 -9
  139. intentkit/skills/enso/prices.py +2 -4
  140. intentkit/skills/enso/route.py +6 -12
  141. intentkit/skills/enso/tokens.py +4 -16
  142. intentkit/skills/enso/wallet.py +6 -6
  143. intentkit/skills/erc20/__init__.py +5 -11
  144. intentkit/skills/erc721/__init__.py +5 -9
  145. intentkit/skills/firecrawl/__init__.py +5 -18
  146. intentkit/skills/firecrawl/base.py +4 -9
  147. intentkit/skills/firecrawl/clear.py +4 -8
  148. intentkit/skills/firecrawl/crawl.py +19 -19
  149. intentkit/skills/firecrawl/query.py +4 -3
  150. intentkit/skills/firecrawl/scrape.py +17 -22
  151. intentkit/skills/firecrawl/utils.py +50 -42
  152. intentkit/skills/github/__init__.py +2 -7
  153. intentkit/skills/github/base.py +1 -7
  154. intentkit/skills/github/github_search.py +1 -2
  155. intentkit/skills/heurist/__init__.py +8 -27
  156. intentkit/skills/heurist/base.py +4 -9
  157. intentkit/skills/heurist/image_generation_animagine_xl.py +12 -13
  158. intentkit/skills/heurist/image_generation_arthemy_comics.py +12 -13
  159. intentkit/skills/heurist/image_generation_arthemy_real.py +12 -13
  160. intentkit/skills/heurist/image_generation_braindance.py +12 -13
  161. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +12 -13
  162. intentkit/skills/heurist/image_generation_flux_1_dev.py +12 -13
  163. intentkit/skills/heurist/image_generation_sdxl.py +12 -13
  164. intentkit/skills/http/__init__.py +4 -15
  165. intentkit/skills/http/base.py +1 -7
  166. intentkit/skills/http/get.py +21 -16
  167. intentkit/skills/http/post.py +23 -18
  168. intentkit/skills/http/put.py +23 -18
  169. intentkit/skills/lifi/__init__.py +5 -10
  170. intentkit/skills/lifi/base.py +1 -7
  171. intentkit/skills/lifi/token_execute.py +14 -17
  172. intentkit/skills/lifi/token_quote.py +7 -9
  173. intentkit/skills/lifi/utils.py +16 -16
  174. intentkit/skills/moralis/__init__.py +6 -10
  175. intentkit/skills/moralis/api.py +6 -7
  176. intentkit/skills/moralis/base.py +5 -10
  177. intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
  178. intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
  179. intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
  180. intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
  181. intentkit/skills/morpho/__init__.py +5 -9
  182. intentkit/skills/nation/__init__.py +4 -9
  183. intentkit/skills/nation/base.py +5 -10
  184. intentkit/skills/nation/nft_check.py +3 -4
  185. intentkit/skills/onchain.py +23 -0
  186. intentkit/skills/openai/__init__.py +17 -18
  187. intentkit/skills/openai/base.py +10 -14
  188. intentkit/skills/openai/dalle_image_generation.py +3 -8
  189. intentkit/skills/openai/gpt_avatar_generator.py +102 -0
  190. intentkit/skills/openai/gpt_image_generation.py +4 -8
  191. intentkit/skills/openai/gpt_image_mini_generator.py +91 -0
  192. intentkit/skills/openai/gpt_image_to_image.py +4 -8
  193. intentkit/skills/openai/image_to_text.py +3 -7
  194. intentkit/skills/openai/schema.json +32 -0
  195. intentkit/skills/portfolio/__init__.py +11 -35
  196. intentkit/skills/portfolio/base.py +33 -19
  197. intentkit/skills/portfolio/token_balances.py +21 -21
  198. intentkit/skills/portfolio/wallet_approvals.py +17 -18
  199. intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
  200. intentkit/skills/portfolio/wallet_history.py +31 -31
  201. intentkit/skills/portfolio/wallet_net_worth.py +13 -13
  202. intentkit/skills/portfolio/wallet_nfts.py +19 -19
  203. intentkit/skills/portfolio/wallet_profitability.py +18 -18
  204. intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
  205. intentkit/skills/portfolio/wallet_stats.py +3 -3
  206. intentkit/skills/portfolio/wallet_swaps.py +19 -19
  207. intentkit/skills/pyth/__init__.py +4 -10
  208. intentkit/skills/skills.toml +4 -0
  209. intentkit/skills/slack/__init__.py +5 -17
  210. intentkit/skills/slack/base.py +3 -9
  211. intentkit/skills/slack/get_channel.py +8 -8
  212. intentkit/skills/slack/get_message.py +9 -9
  213. intentkit/skills/slack/schedule_message.py +5 -5
  214. intentkit/skills/slack/send_message.py +3 -5
  215. intentkit/skills/supabase/__init__.py +7 -23
  216. intentkit/skills/supabase/base.py +1 -7
  217. intentkit/skills/supabase/delete_data.py +4 -4
  218. intentkit/skills/supabase/fetch_data.py +12 -12
  219. intentkit/skills/supabase/insert_data.py +4 -4
  220. intentkit/skills/supabase/invoke_function.py +6 -6
  221. intentkit/skills/supabase/update_data.py +6 -6
  222. intentkit/skills/supabase/upsert_data.py +4 -4
  223. intentkit/skills/superfluid/__init__.py +5 -9
  224. intentkit/skills/system/__init__.py +7 -24
  225. intentkit/skills/system/add_autonomous_task.py +10 -12
  226. intentkit/skills/system/delete_autonomous_task.py +2 -2
  227. intentkit/skills/system/edit_autonomous_task.py +14 -18
  228. intentkit/skills/system/list_autonomous_tasks.py +3 -5
  229. intentkit/skills/system/read_agent_api_key.py +6 -4
  230. intentkit/skills/system/regenerate_agent_api_key.py +6 -4
  231. intentkit/skills/tavily/__init__.py +3 -12
  232. intentkit/skills/tavily/base.py +4 -9
  233. intentkit/skills/tavily/tavily_extract.py +2 -4
  234. intentkit/skills/tavily/tavily_search.py +4 -6
  235. intentkit/skills/token/__init__.py +5 -10
  236. intentkit/skills/token/base.py +7 -11
  237. intentkit/skills/token/erc20_transfers.py +19 -19
  238. intentkit/skills/token/token_analytics.py +3 -3
  239. intentkit/skills/token/token_price.py +13 -13
  240. intentkit/skills/token/token_search.py +9 -9
  241. intentkit/skills/twitter/__init__.py +11 -35
  242. intentkit/skills/twitter/base.py +22 -34
  243. intentkit/skills/twitter/follow_user.py +2 -6
  244. intentkit/skills/twitter/get_mentions.py +5 -12
  245. intentkit/skills/twitter/get_timeline.py +4 -12
  246. intentkit/skills/twitter/get_user_by_username.py +2 -6
  247. intentkit/skills/twitter/get_user_tweets.py +5 -13
  248. intentkit/skills/twitter/like_tweet.py +2 -6
  249. intentkit/skills/twitter/post_tweet.py +6 -9
  250. intentkit/skills/twitter/reply_tweet.py +6 -9
  251. intentkit/skills/twitter/retweet.py +2 -6
  252. intentkit/skills/twitter/search_tweets.py +4 -12
  253. intentkit/skills/unrealspeech/__init__.py +2 -7
  254. intentkit/skills/unrealspeech/base.py +2 -8
  255. intentkit/skills/unrealspeech/text_to_speech.py +8 -8
  256. intentkit/skills/venice_audio/__init__.py +98 -106
  257. intentkit/skills/venice_audio/base.py +117 -121
  258. intentkit/skills/venice_audio/input.py +41 -41
  259. intentkit/skills/venice_audio/venice_audio.py +7 -11
  260. intentkit/skills/venice_image/__init__.py +147 -154
  261. intentkit/skills/venice_image/api.py +138 -138
  262. intentkit/skills/venice_image/base.py +185 -192
  263. intentkit/skills/venice_image/config.py +33 -35
  264. intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
  265. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
  266. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
  267. intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
  268. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
  269. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
  270. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
  271. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
  272. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
  273. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
  274. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
  275. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
  276. intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
  277. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
  278. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
  279. intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
  280. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
  281. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
  282. intentkit/skills/venice_image/utils.py +77 -78
  283. intentkit/skills/web_scraper/__init__.py +5 -18
  284. intentkit/skills/web_scraper/base.py +21 -7
  285. intentkit/skills/web_scraper/document_indexer.py +7 -6
  286. intentkit/skills/web_scraper/scrape_and_index.py +15 -15
  287. intentkit/skills/web_scraper/utils.py +62 -63
  288. intentkit/skills/web_scraper/website_indexer.py +17 -19
  289. intentkit/skills/weth/__init__.py +5 -11
  290. intentkit/skills/wow/__init__.py +5 -11
  291. intentkit/skills/x402/__init__.py +61 -0
  292. intentkit/skills/x402/ask_agent.py +98 -0
  293. intentkit/skills/x402/base.py +99 -0
  294. intentkit/skills/x402/http_request.py +117 -0
  295. intentkit/skills/x402/schema.json +45 -0
  296. intentkit/skills/x402/x402.webp +0 -0
  297. intentkit/skills/xmtp/__init__.py +4 -15
  298. intentkit/skills/xmtp/base.py +5 -5
  299. intentkit/skills/xmtp/price.py +6 -6
  300. intentkit/skills/xmtp/swap.py +6 -8
  301. intentkit/skills/xmtp/transfer.py +4 -6
  302. intentkit/utils/error.py +2 -2
  303. intentkit/utils/logging.py +2 -4
  304. intentkit/utils/s3.py +8 -9
  305. intentkit/utils/schema.py +100 -0
  306. intentkit/utils/slack_alert.py +7 -8
  307. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +3 -4
  308. intentkit-0.8.17.dist-info/RECORD +466 -0
  309. intentkit/models/generator.py +0 -347
  310. intentkit-0.8.6.dev2.dist-info/RECORD +0 -457
  311. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
  312. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
@@ -3,13 +3,12 @@
3
3
  Uses query ID 4832844 to retrieve a list of KOL buy transactions.
4
4
  """
5
5
 
6
- from typing import Any, Dict, Type
6
+ from typing import Any
7
7
 
8
8
  import httpx
9
9
  from pydantic import BaseModel, Field
10
10
  from tenacity import retry, stop_after_attempt, wait_exponential
11
11
 
12
- from intentkit.abstracts.skill import SkillStoreABC
13
12
  from intentkit.skills.dune_analytics.base import DuneBaseTool
14
13
 
15
14
  BASE_URL = "https://api.dune.com/api/v1/query"
@@ -29,7 +28,7 @@ class KOLBuysInput(BaseModel):
29
28
  class KOLBuyData(BaseModel):
30
29
  """Data model for KOL buy results."""
31
30
 
32
- data: Dict[str, Any] = Field(description="KOL buy data from Dune API")
31
+ data: dict[str, Any] = Field(description="KOL buy data from Dune API")
33
32
  error: str = Field(default="", description="Error message if fetch failed")
34
33
 
35
34
 
@@ -48,15 +47,14 @@ class FetchKOLBuys(DuneBaseTool):
48
47
  "Fetches a list of KOL memecoin buy transactions on Solana from Dune Analytics API using query ID 4832844. "
49
48
  "Supports a configurable limit for the number of results. Handles rate limits with retries."
50
49
  )
51
- args_schema: Type[BaseModel] = KOLBuysInput
52
- skill_store: SkillStoreABC = Field(description="Skill store for data persistence")
50
+ args_schema: type[BaseModel] = KOLBuysInput
53
51
 
54
52
  @retry(
55
53
  stop=stop_after_attempt(3), wait=wait_exponential(multiplier=5, min=5, max=60)
56
54
  )
57
55
  async def fetch_data(
58
56
  self, query_id: int, api_key: str, limit: int = 10
59
- ) -> Dict[str, Any]:
57
+ ) -> dict[str, Any]:
60
58
  """Fetch data for a specific Dune query.
61
59
 
62
60
  Args:
@@ -70,7 +68,7 @@ class FetchKOLBuys(DuneBaseTool):
70
68
  Raises:
71
69
  ToolException: If the API request fails.
72
70
  """
73
- from langchain.tools.base import ToolException
71
+ from langchain_core.tools.base import ToolException
74
72
 
75
73
  url = f"{BASE_URL}/{query_id}/results?limit={limit}"
76
74
  headers = {"X-Dune-API-Key": api_key}
@@ -5,13 +5,12 @@ Supports predefined metrics (e.g., total_users, unique_ai_citizens) or direct qu
5
5
 
6
6
  import difflib
7
7
  import re
8
- from typing import Any, Dict, Type
8
+ from typing import Any
9
9
 
10
10
  import httpx
11
11
  from pydantic import BaseModel, Field
12
12
  from tenacity import retry, stop_after_attempt, wait_exponential
13
13
 
14
- from intentkit.abstracts.skill import SkillStoreABC
15
14
  from intentkit.skills.dune_analytics.base import DuneBaseTool
16
15
 
17
16
  SUPPORTED_QUERIES = {
@@ -63,14 +62,14 @@ class MetricData(BaseModel):
63
62
  """Data model for a single metric result."""
64
63
 
65
64
  metric: str = Field(description="Metric name or query ID")
66
- data: Dict[str, Any] = Field(description="Metric data from Dune API")
65
+ data: dict[str, Any] = Field(description="Metric data from Dune API")
67
66
  error: str = Field(default="", description="Error message if fetch failed")
68
67
 
69
68
 
70
69
  class NationMetricsOutput(BaseModel):
71
70
  """Output schema for Crestal Nation metrics."""
72
71
 
73
- metrics: Dict[str, MetricData] = Field(
72
+ metrics: dict[str, MetricData] = Field(
74
73
  description="Dictionary of metric names or query IDs to their data"
75
74
  )
76
75
  summary: str = Field(description="Summary of fetched metrics")
@@ -85,8 +84,7 @@ class FetchNationMetrics(DuneBaseTool):
85
84
  "Supports predefined metrics, direct query IDs, or all configured metrics if none specified. "
86
85
  "Handles rate limits with retries."
87
86
  )
88
- args_schema: Type[BaseModel] = NationMetricsInput
89
- skill_store: SkillStoreABC = Field(description="Skill store for data persistence")
87
+ args_schema: type[BaseModel] = NationMetricsInput
90
88
 
91
89
  def normalize_metric(self, metric: str) -> str:
92
90
  """Normalize a metric string for matching.
@@ -124,7 +122,7 @@ class FetchNationMetrics(DuneBaseTool):
124
122
  )
125
123
  async def fetch_data(
126
124
  self, query_id: int, api_key: str, limit: int = 1000
127
- ) -> Dict[str, Any]:
125
+ ) -> dict[str, Any]:
128
126
  """Fetch data for a specific Dune query.
129
127
 
130
128
  Args:
@@ -138,7 +136,7 @@ class FetchNationMetrics(DuneBaseTool):
138
136
  Raises:
139
137
  ToolException: If the API request fails.
140
138
  """
141
- from langchain.tools.base import ToolException
139
+ from langchain_core.tools.base import ToolException
142
140
 
143
141
  url = f"{BASE_URL}/{query_id}/results?limit={limit}"
144
142
  headers = {"X-Dune-API-Key": api_key}
@@ -3,7 +3,6 @@
3
3
  import logging
4
4
  from typing import NotRequired, TypedDict
5
5
 
6
- from intentkit.abstracts.skill import SkillStoreABC
7
6
  from intentkit.skills.base import SkillConfig, SkillState
8
7
  from intentkit.skills.elfa.base import ElfaBaseTool
9
8
  from intentkit.skills.elfa.mention import (
@@ -36,7 +35,6 @@ class Config(SkillConfig):
36
35
  async def get_skills(
37
36
  config: "Config",
38
37
  is_private: bool,
39
- store: SkillStoreABC,
40
38
  **_,
41
39
  ) -> list[ElfaBaseTool]:
42
40
  """Get all Elfa skills.
@@ -44,7 +42,6 @@ async def get_skills(
44
42
  Args:
45
43
  config: The configuration for Elfa skills.
46
44
  is_private: Whether to include private skills.
47
- store: The skill store for persisting data.
48
45
 
49
46
  Returns:
50
47
  A list of Elfa skills.
@@ -61,7 +58,7 @@ async def get_skills(
61
58
  # Get each skill using the cached getter
62
59
  result = []
63
60
  for name in available_skills:
64
- skill = get_elfa_skill(name, store)
61
+ skill = get_elfa_skill(name)
65
62
  if skill:
66
63
  result.append(skill)
67
64
  return result
@@ -69,13 +66,11 @@ async def get_skills(
69
66
 
70
67
  def get_elfa_skill(
71
68
  name: str,
72
- store: SkillStoreABC,
73
69
  ) -> ElfaBaseTool:
74
70
  """Get an Elfa skill by name.
75
71
 
76
72
  Args:
77
73
  name: The name of the skill to get
78
- store: The skill store for persisting data
79
74
 
80
75
  Returns:
81
76
  The requested Elfa skill
@@ -83,30 +78,22 @@ def get_elfa_skill(
83
78
 
84
79
  if name == "get_top_mentions":
85
80
  if name not in _cache:
86
- _cache[name] = ElfaGetTopMentions(
87
- skill_store=store,
88
- )
81
+ _cache[name] = ElfaGetTopMentions()
89
82
  return _cache[name]
90
83
 
91
84
  elif name == "search_mentions":
92
85
  if name not in _cache:
93
- _cache[name] = ElfaSearchMentions(
94
- skill_store=store,
95
- )
86
+ _cache[name] = ElfaSearchMentions()
96
87
  return _cache[name]
97
88
 
98
89
  elif name == "get_trending_tokens":
99
90
  if name not in _cache:
100
- _cache[name] = ElfaGetTrendingTokens(
101
- skill_store=store,
102
- )
91
+ _cache[name] = ElfaGetTrendingTokens()
103
92
  return _cache[name]
104
93
 
105
94
  elif name == "get_smart_stats":
106
95
  if name not in _cache:
107
- _cache[name] = ElfaGetSmartStats(
108
- skill_store=store,
109
- )
96
+ _cache[name] = ElfaGetSmartStats()
110
97
  return _cache[name]
111
98
 
112
99
  else:
@@ -1,9 +1,7 @@
1
- from typing import Type
2
-
3
- from langchain.tools.base import ToolException
1
+ from langchain_core.tools.base import ToolException
4
2
  from pydantic import BaseModel, Field
5
3
 
6
- from intentkit.abstracts.skill import SkillStoreABC
4
+ from intentkit.config.config import config
7
5
  from intentkit.skills.base import IntentKitSkill
8
6
 
9
7
  base_url = "https://api.elfa.ai/v2"
@@ -14,24 +12,22 @@ class ElfaBaseTool(IntentKitSkill):
14
12
 
15
13
  name: str = Field(description="The name of the tool")
16
14
  description: str = Field(description="A description of what the tool does")
17
- args_schema: Type[BaseModel]
18
- skill_store: SkillStoreABC = Field(
19
- description="The skill store for persisting data"
20
- )
15
+ args_schema: type[BaseModel]
21
16
 
22
17
  def get_api_key(self) -> str:
23
18
  context = self.get_context()
24
19
  skill_config = context.agent.skill_config(self.category)
25
20
  api_key_provider = skill_config.get("api_key_provider")
26
21
  if api_key_provider == "platform":
27
- return self.skill_store.get_system_config("elfa_api_key")
22
+ if not config.elfa_api_key:
23
+ raise ToolException("Elfa API key is not configured")
24
+ return config.elfa_api_key
28
25
  # for backward compatibility, may only have api_key in skill_config
29
- elif skill_config.get("api_key"):
26
+ if skill_config.get("api_key"):
30
27
  return skill_config.get("api_key")
31
- else:
32
- raise ToolException(
33
- f"Invalid API key provider: {api_key_provider}, or no api_key in config"
34
- )
28
+ raise ToolException(
29
+ f"Invalid API key provider: {api_key_provider}, or no api_key in config"
30
+ )
35
31
 
36
32
  @property
37
33
  def category(self) -> str:
@@ -1,6 +1,6 @@
1
1
  """Mention-related skills for Elfa AI API."""
2
2
 
3
- from typing import Any, Dict, List, Optional, Type
3
+ from typing import Any
4
4
 
5
5
  from pydantic import BaseModel, Field
6
6
 
@@ -12,19 +12,19 @@ class ElfaGetTopMentionsInput(BaseModel):
12
12
  """Input parameters for top mentions."""
13
13
 
14
14
  ticker: str = Field(description="Stock ticker symbol (e.g., ETH, $ETH, BTC, $BTC)")
15
- timeWindow: Optional[str] = Field(
15
+ timeWindow: str | None = Field(
16
16
  "1h", description="Time window (e.g., '1h', '24h', '7d')"
17
17
  )
18
- page: Optional[int] = Field(1, description="Page number for pagination")
19
- pageSize: Optional[int] = Field(10, description="Number of items per page")
18
+ page: int | None = Field(1, description="Page number for pagination")
19
+ pageSize: int | None = Field(10, description="Number of items per page")
20
20
 
21
21
 
22
22
  class ElfaGetTopMentionsOutput(BaseModel):
23
23
  """Output structure for top mentions response."""
24
24
 
25
25
  success: bool
26
- data: Optional[List[MentionData]] = Field(None, description="List of top mentions")
27
- metadata: Optional[Dict[str, Any]] = Field(None, description="Response metadata")
26
+ data: list[MentionData] | None = Field(None, description="List of top mentions")
27
+ metadata: dict[str, Any] | None = Field(None, description="Response metadata")
28
28
 
29
29
 
30
30
  class ElfaGetTopMentions(ElfaBaseTool):
@@ -46,7 +46,7 @@ class ElfaGetTopMentions(ElfaBaseTool):
46
46
  Updated hourly. Returns engagement metrics and account information for market sentiment analysis.
47
47
 
48
48
  Use this to track public opinion, identify trending news, and monitor investor discussions."""
49
- args_schema: Type[BaseModel] = ElfaGetTopMentionsInput
49
+ args_schema: type[BaseModel] = ElfaGetTopMentionsInput
50
50
 
51
51
  async def _arun(
52
52
  self,
@@ -102,30 +102,28 @@ class ElfaGetTopMentions(ElfaBaseTool):
102
102
  class ElfaSearchMentionsInput(BaseModel):
103
103
  """Input parameters for search mentions."""
104
104
 
105
- keywords: Optional[str] = Field(
105
+ keywords: str | None = Field(
106
106
  None,
107
107
  description="Up to 5 keywords to search for, separated by commas. Phrases accepted",
108
108
  )
109
- accountName: Optional[str] = Field(
109
+ accountName: str | None = Field(
110
110
  None,
111
111
  description="Account username to filter by (optional if keywords provided)",
112
112
  )
113
- timeWindow: Optional[str] = Field("7d", description="Time window for search")
114
- limit: Optional[int] = Field(20, description="Number of results to return (max 30)")
115
- searchType: Optional[str] = Field(
116
- "or", description="Type of search ('and' or 'or')"
117
- )
118
- cursor: Optional[str] = Field(None, description="Cursor for pagination")
113
+ timeWindow: str | None = Field("7d", description="Time window for search")
114
+ limit: int | None = Field(20, description="Number of results to return (max 30)")
115
+ searchType: str | None = Field("or", description="Type of search ('and' or 'or')")
116
+ cursor: str | None = Field(None, description="Cursor for pagination")
119
117
 
120
118
 
121
119
  class ElfaSearchMentionsOutput(BaseModel):
122
120
  """Output structure for search mentions response."""
123
121
 
124
122
  success: bool
125
- data: Optional[List[MentionData]] = Field(
123
+ data: list[MentionData] | None = Field(
126
124
  None, description="List of matching mentions"
127
125
  )
128
- metadata: Optional[Dict[str, Any]] = Field(
126
+ metadata: dict[str, Any] | None = Field(
129
127
  None, description="Response metadata with cursor"
130
128
  )
131
129
 
@@ -150,16 +148,16 @@ class ElfaSearchMentions(ElfaBaseTool):
150
148
  Updated every 5 minutes. Access 30 days of recent data or historical archives.
151
149
 
152
150
  Use this for market research, brand monitoring, opinion tracking, and competitive analysis."""
153
- args_schema: Type[BaseModel] = ElfaSearchMentionsInput
151
+ args_schema: type[BaseModel] = ElfaSearchMentionsInput
154
152
 
155
153
  async def _arun(
156
154
  self,
157
- keywords: Optional[str] = None,
158
- accountName: Optional[str] = None,
155
+ keywords: str | None = None,
156
+ accountName: str | None = None,
159
157
  timeWindow: str = "7d",
160
158
  limit: int = 20,
161
159
  searchType: str = "or",
162
- cursor: Optional[str] = None,
160
+ cursor: str | None = None,
163
161
  **kwargs,
164
162
  ) -> ElfaSearchMentionsOutput:
165
163
  """
@@ -1,6 +1,6 @@
1
1
  """Smart stats skill for Elfa AI API."""
2
2
 
3
- from typing import Any, Dict, Optional, Type
3
+ from typing import Any
4
4
 
5
5
  from pydantic import BaseModel, Field
6
6
 
@@ -18,8 +18,8 @@ class ElfaGetSmartStatsOutput(BaseModel):
18
18
  """Output structure for smart stats response."""
19
19
 
20
20
  success: bool
21
- data: Optional[SmartStatsData] = Field(None, description="Smart stats data")
22
- metadata: Optional[Dict[str, Any]] = Field(None, description="Response metadata")
21
+ data: SmartStatsData | None = Field(None, description="Smart stats data")
22
+ metadata: dict[str, Any] | None = Field(None, description="Response metadata")
23
23
 
24
24
 
25
25
  class ElfaGetSmartStats(ElfaBaseTool):
@@ -43,7 +43,7 @@ class ElfaGetSmartStats(ElfaBaseTool):
43
43
  description: str = """Get comprehensive social media metrics for a username including smart following count,
44
44
  engagement scores, and follower analytics. Use this for competitor analysis, influencer identification,
45
45
  and social media performance audits."""
46
- args_schema: Type[BaseModel] = ElfaGetSmartStatsInput
46
+ args_schema: type[BaseModel] = ElfaGetSmartStatsInput
47
47
 
48
48
  async def _arun(self, username: str, **kwargs) -> ElfaGetSmartStatsOutput:
49
49
  """
@@ -1,6 +1,6 @@
1
1
  """Trending tokens skill for Elfa AI API."""
2
2
 
3
- from typing import Any, Dict, List, Optional, Type
3
+ from typing import Any
4
4
 
5
5
  from pydantic import BaseModel, Field
6
6
 
@@ -11,13 +11,13 @@ from .utils import make_elfa_request
11
11
  class ElfaGetTrendingTokensInput(BaseModel):
12
12
  """Input parameters for trending tokens."""
13
13
 
14
- timeWindow: Optional[str] = Field(
14
+ timeWindow: str | None = Field(
15
15
  "7d",
16
16
  description="Time window for trending analysis (e.g., '30m', '1h', '4h', '24h', '7d', '30d')",
17
17
  )
18
- page: Optional[int] = Field(1, description="Page number for pagination")
19
- pageSize: Optional[int] = Field(50, description="Number of items per page")
20
- minMentions: Optional[int] = Field(
18
+ page: int | None = Field(1, description="Page number for pagination")
19
+ pageSize: int | None = Field(50, description="Number of items per page")
20
+ minMentions: int | None = Field(
21
21
  5, description="Minimum number of mentions required"
22
22
  )
23
23
 
@@ -25,20 +25,20 @@ class ElfaGetTrendingTokensInput(BaseModel):
25
25
  class TrendingToken(BaseModel):
26
26
  """Individual trending token data."""
27
27
 
28
- token: Optional[str] = Field(None, description="Token symbol")
29
- current_count: Optional[int] = Field(None, description="Current mention count")
30
- previous_count: Optional[int] = Field(None, description="Previous mention count")
31
- change_percent: Optional[float] = Field(None, description="Change percentage")
28
+ token: str | None = Field(None, description="Token symbol")
29
+ current_count: int | None = Field(None, description="Current mention count")
30
+ previous_count: int | None = Field(None, description="Previous mention count")
31
+ change_percent: float | None = Field(None, description="Change percentage")
32
32
 
33
33
 
34
34
  class ElfaGetTrendingTokensOutput(BaseModel):
35
35
  """Output structure for trending tokens response."""
36
36
 
37
37
  success: bool
38
- data: Optional[List[TrendingToken]] = Field(
38
+ data: list[TrendingToken] | None = Field(
39
39
  None, description="List of trending tokens"
40
40
  )
41
- metadata: Optional[Dict[str, Any]] = Field(None, description="Response metadata")
41
+ metadata: dict[str, Any] | None = Field(None, description="Response metadata")
42
42
 
43
43
 
44
44
  class ElfaGetTrendingTokens(ElfaBaseTool):
@@ -60,7 +60,7 @@ class ElfaGetTrendingTokens(ElfaBaseTool):
60
60
  Updated every 5 minutes. Smart mentions provide sophisticated discussion volume measurement beyond simple keyword counts.
61
61
 
62
62
  Use this to identify tokens gaining traction, gauge market sentiment, and research potential investments."""
63
- args_schema: Type[BaseModel] = ElfaGetTrendingTokensInput
63
+ args_schema: type[BaseModel] = ElfaGetTrendingTokensInput
64
64
 
65
65
  async def _arun(
66
66
  self,
@@ -1,9 +1,9 @@
1
1
  """Utility functions for Elfa skills."""
2
2
 
3
- from typing import Any, Dict, Optional
3
+ from typing import Any
4
4
 
5
5
  import httpx
6
- from langchain.tools.base import ToolException
6
+ from langchain_core.tools.base import ToolException
7
7
  from pydantic import BaseModel, Field
8
8
 
9
9
  from .base import base_url
@@ -14,13 +14,13 @@ class ElfaResponse(BaseModel):
14
14
 
15
15
  success: bool
16
16
  data: Any = None
17
- metadata: Optional[Dict[str, Any]] = None
17
+ metadata: dict[str, Any] | None = None
18
18
 
19
19
 
20
20
  async def make_elfa_request(
21
21
  endpoint: str,
22
22
  api_key: str,
23
- params: Optional[Dict[str, Any]] = None,
23
+ params: dict[str, Any] | None = None,
24
24
  timeout: int = 30,
25
25
  ) -> ElfaResponse:
26
26
  """
@@ -82,32 +82,32 @@ async def make_elfa_request(
82
82
  class RepostBreakdown(BaseModel):
83
83
  """Repost breakdown data."""
84
84
 
85
- smart: Optional[int] = None
86
- ct: Optional[int] = None
85
+ smart: int | None = None
86
+ ct: int | None = None
87
87
 
88
88
 
89
89
  class Account(BaseModel):
90
90
  """Account information."""
91
91
 
92
- username: Optional[str] = None
93
- isVerified: Optional[bool] = None
92
+ username: str | None = None
93
+ isVerified: bool | None = None
94
94
 
95
95
 
96
96
  class MentionData(BaseModel):
97
97
  """Base mention data structure used across multiple endpoints."""
98
98
 
99
- tweetId: Optional[str] = Field(None, description="Tweet ID")
100
- link: Optional[str] = Field(None, description="Link to the tweet")
101
- likeCount: Optional[int] = Field(None, description="Number of likes")
102
- repostCount: Optional[int] = Field(None, description="Number of reposts")
103
- viewCount: Optional[int] = Field(None, description="Number of views")
104
- quoteCount: Optional[int] = Field(None, description="Number of quotes")
105
- replyCount: Optional[int] = Field(None, description="Number of replies")
106
- bookmarkCount: Optional[int] = Field(None, description="Number of bookmarks")
107
- mentionedAt: Optional[str] = Field(None, description="When mentioned")
108
- type: Optional[str] = Field(None, description="Post type")
109
- account: Optional[Account] = Field(None, description="Account information")
110
- repostBreakdown: Optional[RepostBreakdown] = Field(
99
+ tweetId: str | None = Field(None, description="Tweet ID")
100
+ link: str | None = Field(None, description="Link to the tweet")
101
+ likeCount: int | None = Field(None, description="Number of likes")
102
+ repostCount: int | None = Field(None, description="Number of reposts")
103
+ viewCount: int | None = Field(None, description="Number of views")
104
+ quoteCount: int | None = Field(None, description="Number of quotes")
105
+ replyCount: int | None = Field(None, description="Number of replies")
106
+ bookmarkCount: int | None = Field(None, description="Number of bookmarks")
107
+ mentionedAt: str | None = Field(None, description="When mentioned")
108
+ type: str | None = Field(None, description="Post type")
109
+ account: Account | None = Field(None, description="Account information")
110
+ repostBreakdown: RepostBreakdown | None = Field(
111
111
  None, description="Repost breakdown"
112
112
  )
113
113
 
@@ -115,15 +115,13 @@ class MentionData(BaseModel):
115
115
  class SmartStatsData(BaseModel):
116
116
  """Smart stats data structure."""
117
117
 
118
- smartFollowingCount: Optional[int] = Field(
119
- None, description="Smart following count"
120
- )
121
- averageEngagement: Optional[float] = Field(None, description="Average engagement")
122
- averageReach: Optional[float] = Field(None, description="Average reach")
123
- smartFollowerCount: Optional[int] = Field(None, description="Smart follower count")
124
- followerCount: Optional[int] = Field(None, description="Total follower count")
118
+ smartFollowingCount: int | None = Field(None, description="Smart following count")
119
+ averageEngagement: float | None = Field(None, description="Average engagement")
120
+ averageReach: float | None = Field(None, description="Average reach")
121
+ smartFollowerCount: int | None = Field(None, description="Smart follower count")
122
+ followerCount: int | None = Field(None, description="Total follower count")
125
123
 
126
124
 
127
- def clean_params(params: Dict[str, Any]) -> Dict[str, Any]:
125
+ def clean_params(params: dict[str, Any]) -> dict[str, Any]:
128
126
  """Remove None values from parameters dict."""
129
127
  return {k: v for k, v in params.items() if v is not None}
@@ -1,9 +1,8 @@
1
1
  """Enso skills."""
2
2
 
3
3
  import logging
4
- from typing import List, NotRequired, TypedDict
4
+ from typing import NotRequired, TypedDict
5
5
 
6
- from intentkit.abstracts.skill import SkillStoreABC
7
6
  from intentkit.skills.base import SkillConfig, SkillState
8
7
  from intentkit.skills.enso.base import EnsoBaseTool
9
8
  from intentkit.skills.enso.best_yield import EnsoGetBestYield
@@ -36,13 +35,12 @@ class Config(SkillConfig):
36
35
 
37
36
  states: SkillStates
38
37
  api_token: NotRequired[str]
39
- main_tokens: NotRequired[List[str]]
38
+ main_tokens: NotRequired[list[str]]
40
39
 
41
40
 
42
41
  async def get_skills(
43
42
  config: Config,
44
43
  is_private: bool,
45
- store: SkillStoreABC,
46
44
  **_,
47
45
  ) -> list[EnsoBaseTool]:
48
46
  """Get all Enso skills."""
@@ -58,7 +56,7 @@ async def get_skills(
58
56
  # Get each skill using the cached getter
59
57
  result = []
60
58
  for name in available_skills:
61
- skill = get_enso_skill(name, store)
59
+ skill = get_enso_skill(name)
62
60
  if skill:
63
61
  result.append(skill)
64
62
  return result
@@ -66,49 +64,31 @@ async def get_skills(
66
64
 
67
65
  def get_enso_skill(
68
66
  name: str,
69
- skill_store: SkillStoreABC,
70
67
  ) -> EnsoBaseTool:
71
68
  """Get an Enso skill by name.
72
69
 
73
70
  Args:
74
71
  name: The name of the skill to get
75
- skill_store: The skill store for persisting data
76
72
 
77
73
  Returns:
78
74
  The requested Enso skill
79
75
  """
80
76
  if name == "get_networks":
81
- return EnsoGetNetworks(
82
- skill_store=skill_store,
83
- )
77
+ return EnsoGetNetworks()
84
78
  if name == "get_tokens":
85
- return EnsoGetTokens(
86
- skill_store=skill_store,
87
- )
79
+ return EnsoGetTokens()
88
80
  if name == "get_prices":
89
- return EnsoGetPrices(
90
- skill_store=skill_store,
91
- )
81
+ return EnsoGetPrices()
92
82
  if name == "get_wallet_approvals":
93
- return EnsoGetWalletApprovals(
94
- skill_store=skill_store,
95
- )
83
+ return EnsoGetWalletApprovals()
96
84
  if name == "get_wallet_balances":
97
- return EnsoGetWalletBalances(
98
- skill_store=skill_store,
99
- )
85
+ return EnsoGetWalletBalances()
100
86
  if name == "wallet_approve":
101
- return EnsoWalletApprove(
102
- skill_store=skill_store,
103
- )
87
+ return EnsoWalletApprove()
104
88
  if name == "route_shortcut":
105
- return EnsoRouteShortcut(
106
- skill_store=skill_store,
107
- )
89
+ return EnsoRouteShortcut()
108
90
  if name == "get_best_yield":
109
- return EnsoGetBestYield(
110
- skill_store=skill_store,
111
- )
91
+ return EnsoGetBestYield()
112
92
  else:
113
93
  logger.warning(f"Unknown Enso skill: {name}")
114
94
  return None