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
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, List, Optional, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, Field
5
5
 
@@ -19,35 +19,35 @@ class ERC20TransfersInput(BaseModel):
19
19
  description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
20
20
  default=DEFAULT_CHAIN,
21
21
  )
22
- contract_addresses: Optional[List[str]] = Field(
22
+ contract_addresses: list[str] | None = Field(
23
23
  description="List of contract addresses of transfers to filter by.",
24
24
  default=None,
25
25
  )
26
- from_block: Optional[int] = Field(
26
+ from_block: int | None = Field(
27
27
  description="The minimum block number from which to get the transactions.",
28
28
  default=None,
29
29
  )
30
- to_block: Optional[int] = Field(
30
+ to_block: int | None = Field(
31
31
  description="The maximum block number from which to get the transactions.",
32
32
  default=None,
33
33
  )
34
- from_date: Optional[str] = Field(
34
+ from_date: str | None = Field(
35
35
  description="The start date from which to get the transactions (any format accepted by momentjs).",
36
36
  default=None,
37
37
  )
38
- to_date: Optional[str] = Field(
38
+ to_date: str | None = Field(
39
39
  description="Get the transactions up to this date (any format accepted by momentjs).",
40
40
  default=None,
41
41
  )
42
- limit: Optional[int] = Field(
42
+ limit: int | None = Field(
43
43
  description="The desired page size of the result.",
44
44
  default=DEFAULT_LIMIT,
45
45
  )
46
- order: Optional[str] = Field(
46
+ order: str | None = Field(
47
47
  description="The order of the result, in ascending (ASC) or descending (DESC).",
48
48
  default=DEFAULT_ORDER,
49
49
  )
50
- cursor: Optional[str] = Field(
50
+ cursor: str | None = Field(
51
51
  description="The cursor returned in the previous response (for pagination).",
52
52
  default=None,
53
53
  )
@@ -65,22 +65,22 @@ class ERC20Transfers(TokenBaseTool):
65
65
  "Get ERC20 token transactions for a wallet address, ordered by block number. "
66
66
  "Returns transaction details, token information, and wallet interactions."
67
67
  )
68
- args_schema: Type[BaseModel] = ERC20TransfersInput
68
+ args_schema: type[BaseModel] = ERC20TransfersInput
69
69
 
70
70
  async def _arun(
71
71
  self,
72
72
  address: str,
73
73
  chain: str = DEFAULT_CHAIN,
74
- contract_addresses: Optional[List[str]] = None,
75
- from_block: Optional[int] = None,
76
- to_block: Optional[int] = None,
77
- from_date: Optional[str] = None,
78
- to_date: Optional[str] = None,
79
- limit: Optional[int] = DEFAULT_LIMIT,
80
- order: Optional[str] = DEFAULT_ORDER,
81
- cursor: Optional[str] = None,
74
+ contract_addresses: list[str] | None = None,
75
+ from_block: int | None = None,
76
+ to_block: int | None = None,
77
+ from_date: str | None = None,
78
+ to_date: str | None = None,
79
+ limit: int | None = DEFAULT_LIMIT,
80
+ order: str | None = DEFAULT_ORDER,
81
+ cursor: str | None = None,
82
82
  **kwargs,
83
- ) -> Dict[str, Any]:
83
+ ) -> dict[str, Any]:
84
84
  """Fetch ERC20 token transfers for a wallet from Moralis.
85
85
 
86
86
  Args:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, Field
5
5
 
@@ -31,14 +31,14 @@ class TokenAnalytics(TokenBaseTool):
31
31
  "Get analytics for a token by token address. "
32
32
  "Returns trading volumes, number of buyers/sellers, and liquidity information over various time periods."
33
33
  )
34
- args_schema: Type[BaseModel] = TokenAnalyticsInput
34
+ args_schema: type[BaseModel] = TokenAnalyticsInput
35
35
 
36
36
  async def _arun(
37
37
  self,
38
38
  address: str,
39
39
  chain: str = DEFAULT_CHAIN,
40
40
  **kwargs,
41
- ) -> Dict[str, Any]:
41
+ ) -> dict[str, Any]:
42
42
  """Fetch token analytics from Moralis.
43
43
 
44
44
  Args:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, Optional, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, Field
5
5
 
@@ -19,23 +19,23 @@ class TokenPriceInput(BaseModel):
19
19
  description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
20
20
  default=DEFAULT_CHAIN,
21
21
  )
22
- include: Optional[str] = Field(
22
+ include: str | None = Field(
23
23
  description="If the result should contain the 24hr percent change (use 'percent_change').",
24
24
  default=None,
25
25
  )
26
- exchange: Optional[str] = Field(
26
+ exchange: str | None = Field(
27
27
  description="The factory name or address of the token exchange.",
28
28
  default=None,
29
29
  )
30
- to_block: Optional[int] = Field(
30
+ to_block: int | None = Field(
31
31
  description="The block number from which the token price should be checked.",
32
32
  default=None,
33
33
  )
34
- max_token_inactivity: Optional[int] = Field(
34
+ max_token_inactivity: int | None = Field(
35
35
  description="Exclude tokens inactive for more than the given amount of days.",
36
36
  default=None,
37
37
  )
38
- min_pair_side_liquidity_usd: Optional[int] = Field(
38
+ min_pair_side_liquidity_usd: int | None = Field(
39
39
  description="Exclude tokens with liquidity less than the specified amount in USD.",
40
40
  default=None,
41
41
  )
@@ -53,19 +53,19 @@ class TokenPrice(TokenBaseTool):
53
53
  "Get the token price denominated in the blockchain's native token and USD for a given token contract address. "
54
54
  "Returns price, token information and exchange data."
55
55
  )
56
- args_schema: Type[BaseModel] = TokenPriceInput
56
+ args_schema: type[BaseModel] = TokenPriceInput
57
57
 
58
58
  async def _arun(
59
59
  self,
60
60
  address: str,
61
61
  chain: str = DEFAULT_CHAIN,
62
- include: Optional[str] = None,
63
- exchange: Optional[str] = None,
64
- to_block: Optional[int] = None,
65
- max_token_inactivity: Optional[int] = None,
66
- min_pair_side_liquidity_usd: Optional[int] = None,
62
+ include: str | None = None,
63
+ exchange: str | None = None,
64
+ to_block: int | None = None,
65
+ max_token_inactivity: int | None = None,
66
+ min_pair_side_liquidity_usd: int | None = None,
67
67
  **kwargs,
68
- ) -> Dict[str, Any]:
68
+ ) -> dict[str, Any]:
69
69
  """Fetch token price from Moralis.
70
70
 
71
71
  Args:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, List, Optional, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, Field
5
5
 
@@ -14,15 +14,15 @@ class TokenSearchInput(BaseModel):
14
14
  query: str = Field(
15
15
  description="Search query - can be token address, token name or token symbol."
16
16
  )
17
- chains: Optional[List[str]] = Field(
17
+ chains: list[str] | None = Field(
18
18
  description="The chain(s) to query (e.g., 'eth', 'bsc', 'polygon').",
19
19
  default=None,
20
20
  )
21
- limit: Optional[int] = Field(
21
+ limit: int | None = Field(
22
22
  description="The desired page size of the result.",
23
23
  default=None,
24
24
  )
25
- is_verified_contract: Optional[bool] = Field(
25
+ is_verified_contract: bool | None = Field(
26
26
  description="Whether the contract is verified.",
27
27
  default=None,
28
28
  )
@@ -44,16 +44,16 @@ class TokenSearch(TokenBaseTool):
44
44
  "Returns token information including price, market cap, and security information. "
45
45
  "NOTE: This is a premium endpoint that requires a Moralis Business plan."
46
46
  )
47
- args_schema: Type[BaseModel] = TokenSearchInput
47
+ args_schema: type[BaseModel] = TokenSearchInput
48
48
 
49
49
  async def _arun(
50
50
  self,
51
51
  query: str,
52
- chains: Optional[List[str]] = None,
53
- limit: Optional[int] = None,
54
- is_verified_contract: Optional[bool] = None,
52
+ chains: list[str] | None = None,
53
+ limit: int | None = None,
54
+ is_verified_contract: bool | None = None,
55
55
  **kwargs,
56
- ) -> Dict[str, Any]:
56
+ ) -> dict[str, Any]:
57
57
  """Search for tokens using Moralis.
58
58
 
59
59
  Args:
@@ -3,7 +3,6 @@
3
3
  import logging
4
4
  from typing import TypedDict
5
5
 
6
- from intentkit.abstracts.skill import SkillStoreABC
7
6
  from intentkit.clients import TwitterClientConfig
8
7
  from intentkit.skills.base import SkillConfig, SkillState
9
8
  from intentkit.skills.twitter.base import TwitterBaseTool
@@ -46,7 +45,6 @@ class Config(SkillConfig, TwitterClientConfig):
46
45
  async def get_skills(
47
46
  config: "Config",
48
47
  is_private: bool,
49
- store: SkillStoreABC,
50
48
  **_,
51
49
  ) -> list[TwitterBaseTool]:
52
50
  """Get all Twitter skills."""
@@ -62,7 +60,7 @@ async def get_skills(
62
60
  # Get each skill using the cached getter
63
61
  result = []
64
62
  for name in available_skills:
65
- skill = get_twitter_skill(name, store)
63
+ skill = get_twitter_skill(name)
66
64
  if skill:
67
65
  result.append(skill)
68
66
  return result
@@ -70,76 +68,54 @@ async def get_skills(
70
68
 
71
69
  def get_twitter_skill(
72
70
  name: str,
73
- store: SkillStoreABC,
74
71
  ) -> TwitterBaseTool:
75
72
  """Get a Twitter skill by name.
76
73
 
77
74
  Args:
78
75
  name: The name of the skill to get
79
- store: The skill store for persisting data
80
76
 
81
77
  Returns:
82
78
  The requested Twitter skill
83
79
  """
84
80
  if name == "get_mentions":
85
81
  if name not in _cache:
86
- _cache[name] = TwitterGetMentions(
87
- skill_store=store,
88
- )
82
+ _cache[name] = TwitterGetMentions()
89
83
  return _cache[name]
90
84
  elif name == "post_tweet":
91
85
  if name not in _cache:
92
- _cache[name] = TwitterPostTweet(
93
- skill_store=store,
94
- )
86
+ _cache[name] = TwitterPostTweet()
95
87
  return _cache[name]
96
88
  elif name == "reply_tweet":
97
89
  if name not in _cache:
98
- _cache[name] = TwitterReplyTweet(
99
- skill_store=store,
100
- )
90
+ _cache[name] = TwitterReplyTweet()
101
91
  return _cache[name]
102
92
  elif name == "get_timeline":
103
93
  if name not in _cache:
104
- _cache[name] = TwitterGetTimeline(
105
- skill_store=store,
106
- )
94
+ _cache[name] = TwitterGetTimeline()
107
95
  return _cache[name]
108
96
  elif name == "follow_user":
109
97
  if name not in _cache:
110
- _cache[name] = TwitterFollowUser(
111
- skill_store=store,
112
- )
98
+ _cache[name] = TwitterFollowUser()
113
99
  return _cache[name]
114
100
  elif name == "like_tweet":
115
101
  if name not in _cache:
116
- _cache[name] = TwitterLikeTweet(
117
- skill_store=store,
118
- )
102
+ _cache[name] = TwitterLikeTweet()
119
103
  return _cache[name]
120
104
  elif name == "retweet":
121
105
  if name not in _cache:
122
- _cache[name] = TwitterRetweet(
123
- skill_store=store,
124
- )
106
+ _cache[name] = TwitterRetweet()
125
107
  return _cache[name]
126
108
  elif name == "search_tweets":
127
109
  if name not in _cache:
128
- _cache[name] = TwitterSearchTweets(
129
- skill_store=store,
130
- )
110
+ _cache[name] = TwitterSearchTweets()
131
111
  return _cache[name]
132
112
  elif name == "get_user_by_username":
133
113
  if name not in _cache:
134
- _cache[name] = TwitterGetUserByUsername(
135
- skill_store=store,
136
- )
114
+ _cache[name] = TwitterGetUserByUsername()
137
115
  return _cache[name]
138
116
  elif name == "get_user_tweets":
139
117
  if name not in _cache:
140
- _cache[name] = TwitterGetUserTweets(
141
- skill_store=store,
142
- )
118
+ _cache[name] = TwitterGetUserTweets()
143
119
  return _cache[name]
144
120
  else:
145
121
  logger.warning(f"Unknown Twitter skill: {name}")
@@ -1,10 +1,9 @@
1
- from datetime import datetime, timedelta, timezone
2
- from typing import Type
1
+ from datetime import UTC, datetime, timedelta
3
2
 
4
- from langchain.tools.base import ToolException
3
+ from langchain_core.tools.base import ToolException
5
4
  from pydantic import BaseModel, Field
6
5
 
7
- from intentkit.abstracts.skill import SkillStoreABC
6
+ from intentkit.config.config import config
8
7
  from intentkit.skills.base import IntentKitSkill
9
8
  from intentkit.utils.error import RateLimitExceeded
10
9
 
@@ -14,10 +13,7 @@ class TwitterBaseTool(IntentKitSkill):
14
13
 
15
14
  name: str = Field(description="The name of the tool")
16
15
  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
- )
16
+ args_schema: type[BaseModel]
21
17
 
22
18
  def get_api_key(self) -> dict:
23
19
  context = self.get_context()
@@ -25,20 +21,21 @@ class TwitterBaseTool(IntentKitSkill):
25
21
  api_key_provider = skill_config.get("api_key_provider")
26
22
  if api_key_provider == "platform":
27
23
  # Return platform keys (these need to be added to config.py)
28
- return {
29
- "consumer_key": self.skill_store.get_system_config(
30
- "twitter_consumer_key"
31
- ),
32
- "consumer_secret": self.skill_store.get_system_config(
33
- "twitter_consumer_secret"
34
- ),
35
- "access_token": self.skill_store.get_system_config(
36
- "twitter_access_token"
37
- ),
38
- "access_token_secret": self.skill_store.get_system_config(
39
- "twitter_access_token_secret"
24
+ platform_keys = {
25
+ "consumer_key": getattr(config, "twitter_consumer_key", None),
26
+ "consumer_secret": getattr(config, "twitter_consumer_secret", None),
27
+ "access_token": getattr(config, "twitter_access_token", None),
28
+ "access_token_secret": getattr(
29
+ config, "twitter_access_token_secret", None
40
30
  ),
41
31
  }
32
+ missing = [key for key, value in platform_keys.items() if not value]
33
+ if missing:
34
+ raise ToolException(
35
+ "Twitter platform API keys are not configured: "
36
+ + ", ".join(missing)
37
+ )
38
+ return platform_keys
42
39
  # for backward compatibility or agent_owner provider
43
40
  elif api_key_provider == "agent_owner":
44
41
  required_keys = [
@@ -63,24 +60,19 @@ class TwitterBaseTool(IntentKitSkill):
63
60
  def category(self) -> str:
64
61
  return "twitter"
65
62
 
66
- async def check_rate_limit(
67
- self, agent_id: str, max_requests: int = 1, interval: int = 15
68
- ) -> None:
63
+ async def check_rate_limit(self, max_requests: int = 1, interval: int = 15) -> None:
69
64
  """Check if the rate limit has been exceeded.
70
65
 
71
66
  Args:
72
- agent_id: The ID of the agent.
73
67
  max_requests: Maximum number of requests allowed within the rate limit window.
74
68
  interval: Time interval in minutes for the rate limit window.
75
69
 
76
70
  Raises:
77
71
  RateLimitExceeded: If the rate limit has been exceeded.
78
72
  """
79
- rate_limit = await self.skill_store.get_agent_skill_data(
80
- agent_id, self.name, "rate_limit"
81
- )
73
+ rate_limit = await self.get_agent_skill_data("rate_limit")
82
74
 
83
- current_time = datetime.now(tz=timezone.utc)
75
+ current_time = datetime.now(tz=UTC)
84
76
 
85
77
  if (
86
78
  rate_limit
@@ -92,9 +84,7 @@ class TwitterBaseTool(IntentKitSkill):
92
84
  raise RateLimitExceeded("Rate limit exceeded")
93
85
 
94
86
  rate_limit["count"] += 1
95
- await self.skill_store.save_agent_skill_data(
96
- agent_id, self.name, "rate_limit", rate_limit
97
- )
87
+ await self.save_agent_skill_data("rate_limit", rate_limit)
98
88
 
99
89
  return
100
90
 
@@ -103,7 +93,5 @@ class TwitterBaseTool(IntentKitSkill):
103
93
  "count": 1,
104
94
  "reset_time": (current_time + timedelta(minutes=interval)).isoformat(),
105
95
  }
106
- await self.skill_store.save_agent_skill_data(
107
- agent_id, self.name, "rate_limit", new_rate_limit
108
- )
96
+ await self.save_agent_skill_data("rate_limit", new_rate_limit)
109
97
  return
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import Type
3
2
 
4
3
  from langchain_core.tools import ToolException
5
4
  from pydantic import BaseModel, Field
@@ -34,7 +33,7 @@ class TwitterFollowUser(TwitterBaseTool):
34
33
 
35
34
  name: str = NAME
36
35
  description: str = PROMPT
37
- args_schema: Type[BaseModel] = TwitterFollowUserInput
36
+ args_schema: type[BaseModel] = TwitterFollowUserInput
38
37
 
39
38
  async def _arun(self, user_id: str, **kwargs) -> bool:
40
39
  context = self.get_context()
@@ -42,16 +41,13 @@ class TwitterFollowUser(TwitterBaseTool):
42
41
  skill_config = context.agent.skill_config(self.category)
43
42
  twitter = get_twitter_client(
44
43
  agent_id=context.agent_id,
45
- skill_store=self.skill_store,
46
44
  config=skill_config,
47
45
  )
48
46
  client = await twitter.get_client()
49
47
 
50
48
  # Check rate limit only when not using OAuth
51
49
  if not twitter.use_key:
52
- await self.check_rate_limit(
53
- context.agent_id, max_requests=5, interval=15
54
- )
50
+ await self.check_rate_limit(max_requests=5, interval=15)
55
51
 
56
52
  # Follow the user using tweepy client
57
53
  response = await client.follow_user(
@@ -1,6 +1,5 @@
1
1
  import logging
2
- from datetime import datetime, timedelta, timezone
3
- from typing import Type
2
+ from datetime import UTC, datetime, timedelta
4
3
 
5
4
  from langchain_core.tools import ToolException
6
5
  from pydantic import BaseModel
@@ -38,7 +37,7 @@ class TwitterGetMentions(TwitterBaseTool):
38
37
 
39
38
  name: str = NAME
40
39
  description: str = PROMPT
41
- args_schema: Type[BaseModel] = TwitterGetMentionsInput
40
+ args_schema: type[BaseModel] = TwitterGetMentionsInput
42
41
 
43
42
  async def _arun(self, **kwargs) -> list[Tweet]:
44
43
  context = self.get_context()
@@ -46,7 +45,6 @@ class TwitterGetMentions(TwitterBaseTool):
46
45
  skill_config = context.agent.skill_config(self.category)
47
46
  twitter = get_twitter_client(
48
47
  agent_id=context.agent_id,
49
- skill_store=self.skill_store,
50
48
  config=skill_config,
51
49
  )
52
50
  client = await twitter.get_client()
@@ -56,15 +54,12 @@ class TwitterGetMentions(TwitterBaseTool):
56
54
  # Check rate limit only when not using OAuth
57
55
  if not twitter.use_key:
58
56
  await self.check_rate_limit(
59
- context.agent_id,
60
57
  max_requests=1,
61
58
  interval=15,
62
59
  )
63
60
 
64
61
  # get since id from store
65
- last = await self.skill_store.get_agent_skill_data(
66
- context.agent_id, self.name, "last"
67
- )
62
+ last = await self.get_agent_skill_data("last")
68
63
  last = last or {}
69
64
  max_results = 10
70
65
  since_id = last.get("since_id")
@@ -72,7 +67,7 @@ class TwitterGetMentions(TwitterBaseTool):
72
67
  max_results = 30
73
68
 
74
69
  # Always get mentions for the last day
75
- start_time = datetime.now(tz=timezone.utc) - timedelta(days=1)
70
+ start_time = datetime.now(tz=UTC) - timedelta(days=1)
76
71
 
77
72
  user_id = twitter.self_id
78
73
  if not user_id:
@@ -113,9 +108,7 @@ class TwitterGetMentions(TwitterBaseTool):
113
108
  # Update since_id in store
114
109
  if mentions.get("meta") and mentions["meta"].get("newest_id"):
115
110
  last["since_id"] = mentions["meta"].get("newest_id")
116
- await self.skill_store.save_agent_skill_data(
117
- context.agent_id, self.name, "last", last
118
- )
111
+ await self.save_agent_skill_data("last", last)
119
112
 
120
113
  return mentions
121
114
 
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import Type
3
2
 
4
3
  from pydantic import BaseModel
5
4
 
@@ -34,7 +33,7 @@ class TwitterGetTimeline(TwitterBaseTool):
34
33
 
35
34
  name: str = NAME
36
35
  description: str = PROMPT
37
- args_schema: Type[BaseModel] = TwitterGetTimelineInput
36
+ args_schema: type[BaseModel] = TwitterGetTimelineInput
38
37
 
39
38
  async def _arun(self, **kwargs):
40
39
  context = self.get_context()
@@ -45,21 +44,16 @@ class TwitterGetTimeline(TwitterBaseTool):
45
44
  skill_config = context.agent.skill_config(self.category)
46
45
  twitter = get_twitter_client(
47
46
  agent_id=context.agent_id,
48
- skill_store=self.skill_store,
49
47
  config=skill_config,
50
48
  )
51
49
  client = await twitter.get_client()
52
50
 
53
51
  # Check rate limit only when not using OAuth
54
52
  if not twitter.use_key:
55
- await self.check_rate_limit(
56
- context.agent_id, max_requests=1, interval=15
57
- )
53
+ await self.check_rate_limit(max_requests=1, interval=15)
58
54
 
59
55
  # get since id from store
60
- last = await self.skill_store.get_agent_skill_data(
61
- context.agent_id, self.name, "last"
62
- )
56
+ last = await self.get_agent_skill_data("last")
63
57
  last = last or {}
64
58
  since_id = last.get("since_id")
65
59
 
@@ -101,9 +95,7 @@ class TwitterGetTimeline(TwitterBaseTool):
101
95
  # Update the since_id in store for the next request
102
96
  if timeline.get("meta") and timeline["meta"].get("newest_id"):
103
97
  last["since_id"] = timeline["meta"]["newest_id"]
104
- await self.skill_store.save_agent_skill_data(
105
- context.agent_id, self.name, "last", last
106
- )
98
+ await self.save_agent_skill_data("last", last)
107
99
 
108
100
  return timeline
109
101
 
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import Type
3
2
 
4
3
  from pydantic import BaseModel, Field
5
4
 
@@ -35,7 +34,7 @@ class TwitterGetUserByUsername(TwitterBaseTool):
35
34
 
36
35
  name: str = NAME
37
36
  description: str = PROMPT
38
- args_schema: Type[BaseModel] = TwitterGetUserByUsernameInput
37
+ args_schema: type[BaseModel] = TwitterGetUserByUsernameInput
39
38
 
40
39
  async def _arun(self, username: str, **kwargs):
41
40
  context = self.get_context()
@@ -43,16 +42,13 @@ class TwitterGetUserByUsername(TwitterBaseTool):
43
42
  skill_config = context.agent.skill_config(self.category)
44
43
  twitter = get_twitter_client(
45
44
  agent_id=context.agent_id,
46
- skill_store=self.skill_store,
47
45
  config=skill_config,
48
46
  )
49
47
  client = await twitter.get_client()
50
48
 
51
49
  # Check rate limit only when not using OAuth
52
50
  if not twitter.use_key:
53
- await self.check_rate_limit(
54
- context.agent_id, max_requests=5, interval=60 * 24
55
- )
51
+ await self.check_rate_limit(max_requests=5, interval=60 * 24)
56
52
 
57
53
  user_data = await client.get_user(
58
54
  username=username,
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import List, Optional, Type
3
2
 
4
3
  from pydantic import BaseModel, Field
5
4
 
@@ -21,7 +20,7 @@ class TwitterGetUserTweetsInput(BaseModel):
21
20
  """Input for TwitterGetUserTweets tool."""
22
21
 
23
22
  user_id: str = Field(description="The Twitter user ID to fetch tweets from")
24
- exclude: Optional[List[str]] = Field(
23
+ exclude: list[str] | None = Field(
25
24
  default=["replies", "retweets"],
26
25
  description="Types of tweets to exclude (e.g., 'replies', 'retweets')",
27
26
  )
@@ -41,7 +40,7 @@ class TwitterGetUserTweets(TwitterBaseTool):
41
40
 
42
41
  name: str = NAME
43
42
  description: str = PROMPT
44
- args_schema: Type[BaseModel] = TwitterGetUserTweetsInput
43
+ args_schema: type[BaseModel] = TwitterGetUserTweetsInput
45
44
 
46
45
  async def _arun(self, **kwargs):
47
46
  context = self.get_context()
@@ -59,21 +58,16 @@ class TwitterGetUserTweets(TwitterBaseTool):
59
58
  skill_config = context.agent.skill_config(self.category)
60
59
  twitter = get_twitter_client(
61
60
  agent_id=context.agent_id,
62
- skill_store=self.skill_store,
63
61
  config=skill_config,
64
62
  )
65
63
  client = await twitter.get_client()
66
64
 
67
65
  # Check rate limit only when not using OAuth
68
66
  if not twitter.use_key:
69
- await self.check_rate_limit(
70
- context.agent_id, max_requests=1, interval=15
71
- )
67
+ await self.check_rate_limit(max_requests=1, interval=15)
72
68
 
73
69
  # get since id from store
74
- last = await self.skill_store.get_agent_skill_data(
75
- context.agent_id, self.name, user_id
76
- )
70
+ last = await self.get_agent_skill_data(user_id)
77
71
  last = last or {}
78
72
  since_id = last.get("since_id")
79
73
 
@@ -112,9 +106,7 @@ class TwitterGetUserTweets(TwitterBaseTool):
112
106
  # Update the since_id in store for the next request
113
107
  if tweets.get("meta") and tweets["meta"].get("newest_id"):
114
108
  last["since_id"] = tweets["meta"]["newest_id"]
115
- await self.skill_store.save_agent_skill_data(
116
- context.agent_id, self.name, user_id, last
117
- )
109
+ await self.save_agent_skill_data(user_id, last)
118
110
 
119
111
  return tweets
120
112