intentkit 0.6.13.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 (385) 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 +14 -7
  5. intentkit/abstracts/skill.py +6 -144
  6. intentkit/abstracts/twitter.py +4 -5
  7. intentkit/clients/__init__.py +5 -2
  8. intentkit/clients/cdp.py +101 -141
  9. intentkit/clients/twitter.py +83 -62
  10. intentkit/clients/web3.py +29 -0
  11. intentkit/config/config.py +8 -5
  12. intentkit/core/agent.py +472 -195
  13. intentkit/core/asset.py +253 -0
  14. intentkit/core/chat.py +51 -0
  15. intentkit/core/client.py +1 -1
  16. intentkit/core/credit.py +460 -130
  17. intentkit/core/engine.py +262 -233
  18. intentkit/core/node.py +15 -16
  19. intentkit/core/prompt.py +62 -28
  20. intentkit/core/scheduler.py +92 -0
  21. intentkit/core/statistics.py +168 -0
  22. intentkit/models/agent.py +1096 -949
  23. intentkit/models/agent_data.py +68 -38
  24. intentkit/models/agent_public.json +98 -0
  25. intentkit/models/agent_schema.json +54 -439
  26. intentkit/models/app_setting.py +96 -33
  27. intentkit/models/chat.py +74 -27
  28. intentkit/models/conversation.py +8 -8
  29. intentkit/models/credit.py +362 -74
  30. intentkit/models/db.py +26 -8
  31. intentkit/models/db_mig.py +2 -2
  32. intentkit/models/llm.csv +28 -0
  33. intentkit/models/llm.py +185 -350
  34. intentkit/models/redis.py +6 -4
  35. intentkit/models/skill.py +186 -72
  36. intentkit/models/skills.csv +174 -0
  37. intentkit/models/user.py +82 -24
  38. intentkit/skills/acolyt/__init__.py +2 -9
  39. intentkit/skills/acolyt/ask.py +3 -4
  40. intentkit/skills/acolyt/base.py +4 -9
  41. intentkit/skills/acolyt/schema.json +4 -3
  42. intentkit/skills/aixbt/__init__.py +2 -13
  43. intentkit/skills/aixbt/base.py +1 -7
  44. intentkit/skills/aixbt/projects.py +14 -15
  45. intentkit/skills/aixbt/schema.json +4 -4
  46. intentkit/skills/allora/__init__.py +2 -9
  47. intentkit/skills/allora/base.py +4 -9
  48. intentkit/skills/allora/price.py +3 -4
  49. intentkit/skills/allora/schema.json +3 -2
  50. intentkit/skills/base.py +248 -85
  51. intentkit/skills/basename/__init__.py +51 -0
  52. intentkit/skills/basename/base.py +11 -0
  53. intentkit/skills/basename/basename.svg +11 -0
  54. intentkit/skills/basename/schema.json +58 -0
  55. intentkit/skills/carv/__init__.py +115 -121
  56. intentkit/skills/carv/base.py +184 -185
  57. intentkit/skills/carv/fetch_news.py +3 -3
  58. intentkit/skills/carv/onchain_query.py +4 -4
  59. intentkit/skills/carv/schema.json +134 -137
  60. intentkit/skills/carv/token_info_and_price.py +5 -5
  61. intentkit/skills/casino/README.md +254 -0
  62. intentkit/skills/casino/__init__.py +86 -0
  63. intentkit/skills/casino/base.py +17 -0
  64. intentkit/skills/casino/casino.png +0 -0
  65. intentkit/skills/casino/deck_draw.py +127 -0
  66. intentkit/skills/casino/deck_shuffle.py +118 -0
  67. intentkit/skills/casino/dice_roll.py +100 -0
  68. intentkit/skills/casino/schema.json +77 -0
  69. intentkit/skills/casino/utils.py +107 -0
  70. intentkit/skills/cdp/__init__.py +22 -84
  71. intentkit/skills/cdp/base.py +1 -7
  72. intentkit/skills/cdp/schema.json +11 -314
  73. intentkit/skills/chainlist/__init__.py +2 -7
  74. intentkit/skills/chainlist/base.py +1 -7
  75. intentkit/skills/chainlist/chain_lookup.py +18 -18
  76. intentkit/skills/chainlist/schema.json +3 -5
  77. intentkit/skills/common/__init__.py +2 -9
  78. intentkit/skills/common/base.py +1 -7
  79. intentkit/skills/common/current_time.py +1 -2
  80. intentkit/skills/common/schema.json +2 -2
  81. intentkit/skills/cookiefun/__init__.py +6 -9
  82. intentkit/skills/cookiefun/base.py +2 -7
  83. intentkit/skills/cookiefun/get_account_details.py +7 -7
  84. intentkit/skills/cookiefun/get_account_feed.py +19 -19
  85. intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
  86. intentkit/skills/cookiefun/get_sectors.py +3 -3
  87. intentkit/skills/cookiefun/schema.json +1 -3
  88. intentkit/skills/cookiefun/search_accounts.py +9 -9
  89. intentkit/skills/cryptocompare/__init__.py +7 -24
  90. intentkit/skills/cryptocompare/api.py +2 -3
  91. intentkit/skills/cryptocompare/base.py +11 -25
  92. intentkit/skills/cryptocompare/fetch_news.py +4 -5
  93. intentkit/skills/cryptocompare/fetch_price.py +6 -7
  94. intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
  95. intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
  96. intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
  97. intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
  98. intentkit/skills/cryptocompare/schema.json +3 -3
  99. intentkit/skills/cryptopanic/__init__.py +7 -10
  100. intentkit/skills/cryptopanic/base.py +51 -55
  101. intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
  102. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
  103. intentkit/skills/cryptopanic/schema.json +105 -103
  104. intentkit/skills/dapplooker/__init__.py +2 -9
  105. intentkit/skills/dapplooker/base.py +4 -9
  106. intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
  107. intentkit/skills/dapplooker/schema.json +3 -5
  108. intentkit/skills/defillama/__init__.py +24 -74
  109. intentkit/skills/defillama/api.py +6 -9
  110. intentkit/skills/defillama/base.py +11 -21
  111. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
  112. intentkit/skills/defillama/coins/fetch_block.py +6 -8
  113. intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
  114. intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
  115. intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
  116. intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
  117. intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
  118. intentkit/skills/defillama/config/chains.py +1 -3
  119. intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
  120. intentkit/skills/defillama/schema.json +5 -1
  121. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
  122. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
  123. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
  124. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
  125. intentkit/skills/defillama/tests/api_integration.test.py +1 -1
  126. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
  127. intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
  128. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
  129. intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
  130. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
  131. intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
  132. intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
  133. intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
  134. intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
  135. intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
  136. intentkit/skills/defillama/yields/fetch_pools.py +26 -30
  137. intentkit/skills/dexscreener/README.md +154 -0
  138. intentkit/skills/dexscreener/__init__.py +97 -93
  139. intentkit/skills/dexscreener/base.py +125 -133
  140. intentkit/skills/dexscreener/get_pair_info.py +158 -0
  141. intentkit/skills/dexscreener/get_token_pairs.py +165 -0
  142. intentkit/skills/dexscreener/get_tokens_info.py +212 -0
  143. intentkit/skills/dexscreener/model/search_token_response.py +80 -82
  144. intentkit/skills/dexscreener/schema.json +91 -48
  145. intentkit/skills/dexscreener/search_token.py +182 -321
  146. intentkit/skills/dexscreener/utils.py +420 -0
  147. intentkit/skills/dune_analytics/__init__.py +7 -9
  148. intentkit/skills/dune_analytics/base.py +48 -52
  149. intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
  150. intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
  151. intentkit/skills/dune_analytics/schema.json +104 -99
  152. intentkit/skills/elfa/__init__.py +5 -18
  153. intentkit/skills/elfa/base.py +10 -14
  154. intentkit/skills/elfa/mention.py +19 -21
  155. intentkit/skills/elfa/schema.json +3 -2
  156. intentkit/skills/elfa/stats.py +4 -4
  157. intentkit/skills/elfa/tokens.py +12 -12
  158. intentkit/skills/elfa/utils.py +26 -28
  159. intentkit/skills/enso/__init__.py +11 -31
  160. intentkit/skills/enso/base.py +50 -35
  161. intentkit/skills/enso/best_yield.py +16 -24
  162. intentkit/skills/enso/networks.py +6 -11
  163. intentkit/skills/enso/prices.py +11 -13
  164. intentkit/skills/enso/route.py +34 -38
  165. intentkit/skills/enso/schema.json +3 -2
  166. intentkit/skills/enso/tokens.py +29 -38
  167. intentkit/skills/enso/wallet.py +76 -191
  168. intentkit/skills/erc20/__init__.py +50 -0
  169. intentkit/skills/erc20/base.py +11 -0
  170. intentkit/skills/erc20/erc20.svg +5 -0
  171. intentkit/skills/erc20/schema.json +74 -0
  172. intentkit/skills/erc721/__init__.py +53 -0
  173. intentkit/skills/erc721/base.py +11 -0
  174. intentkit/skills/erc721/erc721.svg +5 -0
  175. intentkit/skills/erc721/schema.json +90 -0
  176. intentkit/skills/firecrawl/README.md +11 -5
  177. intentkit/skills/firecrawl/__init__.py +5 -18
  178. intentkit/skills/firecrawl/base.py +4 -11
  179. intentkit/skills/firecrawl/clear.py +4 -8
  180. intentkit/skills/firecrawl/crawl.py +19 -19
  181. intentkit/skills/firecrawl/query.py +4 -3
  182. intentkit/skills/firecrawl/schema.json +6 -8
  183. intentkit/skills/firecrawl/scrape.py +150 -40
  184. intentkit/skills/firecrawl/utils.py +50 -42
  185. intentkit/skills/github/__init__.py +2 -7
  186. intentkit/skills/github/base.py +1 -7
  187. intentkit/skills/github/github_search.py +1 -2
  188. intentkit/skills/github/schema.json +3 -4
  189. intentkit/skills/heurist/__init__.py +8 -27
  190. intentkit/skills/heurist/base.py +4 -9
  191. intentkit/skills/heurist/image_generation_animagine_xl.py +12 -13
  192. intentkit/skills/heurist/image_generation_arthemy_comics.py +12 -13
  193. intentkit/skills/heurist/image_generation_arthemy_real.py +12 -13
  194. intentkit/skills/heurist/image_generation_braindance.py +12 -13
  195. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +12 -13
  196. intentkit/skills/heurist/image_generation_flux_1_dev.py +12 -13
  197. intentkit/skills/heurist/image_generation_sdxl.py +12 -13
  198. intentkit/skills/heurist/schema.json +2 -2
  199. intentkit/skills/http/__init__.py +4 -15
  200. intentkit/skills/http/base.py +1 -7
  201. intentkit/skills/http/get.py +21 -16
  202. intentkit/skills/http/post.py +23 -18
  203. intentkit/skills/http/put.py +23 -18
  204. intentkit/skills/http/schema.json +4 -5
  205. intentkit/skills/lifi/__init__.py +8 -13
  206. intentkit/skills/lifi/base.py +1 -7
  207. intentkit/skills/lifi/schema.json +17 -8
  208. intentkit/skills/lifi/token_execute.py +36 -30
  209. intentkit/skills/lifi/token_quote.py +8 -10
  210. intentkit/skills/lifi/utils.py +104 -51
  211. intentkit/skills/moralis/__init__.py +6 -10
  212. intentkit/skills/moralis/api.py +6 -7
  213. intentkit/skills/moralis/base.py +5 -10
  214. intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
  215. intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
  216. intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
  217. intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
  218. intentkit/skills/moralis/schema.json +7 -2
  219. intentkit/skills/morpho/__init__.py +52 -0
  220. intentkit/skills/morpho/base.py +11 -0
  221. intentkit/skills/morpho/morpho.svg +12 -0
  222. intentkit/skills/morpho/schema.json +73 -0
  223. intentkit/skills/nation/__init__.py +4 -9
  224. intentkit/skills/nation/base.py +5 -10
  225. intentkit/skills/nation/nft_check.py +3 -4
  226. intentkit/skills/nation/schema.json +4 -3
  227. intentkit/skills/onchain.py +23 -0
  228. intentkit/skills/openai/__init__.py +17 -18
  229. intentkit/skills/openai/base.py +10 -14
  230. intentkit/skills/openai/dalle_image_generation.py +3 -8
  231. intentkit/skills/openai/gpt_avatar_generator.py +102 -0
  232. intentkit/skills/openai/gpt_image_generation.py +4 -8
  233. intentkit/skills/openai/gpt_image_mini_generator.py +91 -0
  234. intentkit/skills/openai/gpt_image_to_image.py +4 -8
  235. intentkit/skills/openai/image_to_text.py +3 -7
  236. intentkit/skills/openai/schema.json +34 -3
  237. intentkit/skills/portfolio/__init__.py +11 -35
  238. intentkit/skills/portfolio/base.py +33 -19
  239. intentkit/skills/portfolio/schema.json +3 -5
  240. intentkit/skills/portfolio/token_balances.py +21 -21
  241. intentkit/skills/portfolio/wallet_approvals.py +17 -18
  242. intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
  243. intentkit/skills/portfolio/wallet_history.py +31 -31
  244. intentkit/skills/portfolio/wallet_net_worth.py +13 -13
  245. intentkit/skills/portfolio/wallet_nfts.py +19 -19
  246. intentkit/skills/portfolio/wallet_profitability.py +18 -18
  247. intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
  248. intentkit/skills/portfolio/wallet_stats.py +3 -3
  249. intentkit/skills/portfolio/wallet_swaps.py +19 -19
  250. intentkit/skills/pyth/__init__.py +50 -0
  251. intentkit/skills/pyth/base.py +11 -0
  252. intentkit/skills/pyth/pyth.svg +6 -0
  253. intentkit/skills/pyth/schema.json +75 -0
  254. intentkit/skills/skills.toml +40 -0
  255. intentkit/skills/slack/__init__.py +5 -17
  256. intentkit/skills/slack/base.py +3 -9
  257. intentkit/skills/slack/get_channel.py +8 -8
  258. intentkit/skills/slack/get_message.py +9 -9
  259. intentkit/skills/slack/schedule_message.py +5 -5
  260. intentkit/skills/slack/schema.json +2 -2
  261. intentkit/skills/slack/send_message.py +3 -5
  262. intentkit/skills/supabase/__init__.py +7 -23
  263. intentkit/skills/supabase/base.py +9 -13
  264. intentkit/skills/supabase/delete_data.py +5 -6
  265. intentkit/skills/supabase/fetch_data.py +13 -14
  266. intentkit/skills/supabase/insert_data.py +5 -6
  267. intentkit/skills/supabase/invoke_function.py +7 -8
  268. intentkit/skills/supabase/schema.json +2 -3
  269. intentkit/skills/supabase/update_data.py +7 -8
  270. intentkit/skills/supabase/upsert_data.py +5 -6
  271. intentkit/skills/superfluid/__init__.py +53 -0
  272. intentkit/skills/superfluid/base.py +11 -0
  273. intentkit/skills/superfluid/schema.json +89 -0
  274. intentkit/skills/superfluid/superfluid.svg +6 -0
  275. intentkit/skills/system/__init__.py +7 -24
  276. intentkit/skills/system/add_autonomous_task.py +10 -12
  277. intentkit/skills/system/delete_autonomous_task.py +2 -2
  278. intentkit/skills/system/edit_autonomous_task.py +14 -18
  279. intentkit/skills/system/list_autonomous_tasks.py +3 -5
  280. intentkit/skills/system/read_agent_api_key.py +6 -4
  281. intentkit/skills/system/regenerate_agent_api_key.py +6 -4
  282. intentkit/skills/system/schema.json +6 -8
  283. intentkit/skills/tavily/__init__.py +3 -12
  284. intentkit/skills/tavily/base.py +4 -9
  285. intentkit/skills/tavily/schema.json +3 -5
  286. intentkit/skills/tavily/tavily_extract.py +2 -4
  287. intentkit/skills/tavily/tavily_search.py +4 -6
  288. intentkit/skills/token/__init__.py +5 -10
  289. intentkit/skills/token/base.py +7 -11
  290. intentkit/skills/token/erc20_transfers.py +19 -19
  291. intentkit/skills/token/schema.json +3 -6
  292. intentkit/skills/token/token_analytics.py +3 -3
  293. intentkit/skills/token/token_price.py +13 -13
  294. intentkit/skills/token/token_search.py +9 -9
  295. intentkit/skills/twitter/__init__.py +11 -35
  296. intentkit/skills/twitter/base.py +23 -35
  297. intentkit/skills/twitter/follow_user.py +3 -7
  298. intentkit/skills/twitter/get_mentions.py +6 -13
  299. intentkit/skills/twitter/get_timeline.py +5 -13
  300. intentkit/skills/twitter/get_user_by_username.py +3 -7
  301. intentkit/skills/twitter/get_user_tweets.py +6 -14
  302. intentkit/skills/twitter/like_tweet.py +3 -7
  303. intentkit/skills/twitter/post_tweet.py +23 -12
  304. intentkit/skills/twitter/reply_tweet.py +21 -12
  305. intentkit/skills/twitter/retweet.py +3 -7
  306. intentkit/skills/twitter/schema.json +1 -0
  307. intentkit/skills/twitter/search_tweets.py +5 -13
  308. intentkit/skills/unrealspeech/__init__.py +2 -7
  309. intentkit/skills/unrealspeech/base.py +2 -8
  310. intentkit/skills/unrealspeech/schema.json +2 -5
  311. intentkit/skills/unrealspeech/text_to_speech.py +8 -8
  312. intentkit/skills/venice_audio/__init__.py +98 -106
  313. intentkit/skills/venice_audio/base.py +117 -121
  314. intentkit/skills/venice_audio/input.py +41 -41
  315. intentkit/skills/venice_audio/schema.json +151 -152
  316. intentkit/skills/venice_audio/venice_audio.py +38 -21
  317. intentkit/skills/venice_image/__init__.py +147 -154
  318. intentkit/skills/venice_image/api.py +138 -138
  319. intentkit/skills/venice_image/base.py +185 -192
  320. intentkit/skills/venice_image/config.py +33 -35
  321. intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
  322. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
  323. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
  324. intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
  325. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
  326. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
  327. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
  328. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
  329. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
  330. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
  331. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
  332. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
  333. intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
  334. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
  335. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
  336. intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
  337. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
  338. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
  339. intentkit/skills/venice_image/schema.json +267 -267
  340. intentkit/skills/venice_image/utils.py +77 -78
  341. intentkit/skills/web_scraper/__init__.py +5 -18
  342. intentkit/skills/web_scraper/base.py +21 -7
  343. intentkit/skills/web_scraper/document_indexer.py +7 -6
  344. intentkit/skills/web_scraper/schema.json +2 -6
  345. intentkit/skills/web_scraper/scrape_and_index.py +15 -15
  346. intentkit/skills/web_scraper/utils.py +62 -63
  347. intentkit/skills/web_scraper/website_indexer.py +17 -19
  348. intentkit/skills/weth/__init__.py +49 -0
  349. intentkit/skills/weth/base.py +11 -0
  350. intentkit/skills/weth/schema.json +58 -0
  351. intentkit/skills/weth/weth.svg +6 -0
  352. intentkit/skills/wow/__init__.py +51 -0
  353. intentkit/skills/wow/base.py +11 -0
  354. intentkit/skills/wow/schema.json +89 -0
  355. intentkit/skills/wow/wow.svg +7 -0
  356. intentkit/skills/x402/__init__.py +61 -0
  357. intentkit/skills/x402/ask_agent.py +98 -0
  358. intentkit/skills/x402/base.py +99 -0
  359. intentkit/skills/x402/http_request.py +117 -0
  360. intentkit/skills/x402/schema.json +45 -0
  361. intentkit/skills/x402/x402.webp +0 -0
  362. intentkit/skills/xmtp/__init__.py +4 -15
  363. intentkit/skills/xmtp/base.py +61 -2
  364. intentkit/skills/xmtp/price.py +18 -13
  365. intentkit/skills/xmtp/schema.json +69 -71
  366. intentkit/skills/xmtp/swap.py +22 -25
  367. intentkit/skills/xmtp/transfer.py +71 -32
  368. intentkit/utils/chain.py +3 -3
  369. intentkit/utils/error.py +14 -1
  370. intentkit/utils/logging.py +2 -4
  371. intentkit/utils/s3.py +59 -7
  372. intentkit/utils/schema.py +100 -0
  373. intentkit/utils/slack_alert.py +7 -8
  374. {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +14 -16
  375. intentkit-0.8.17.dist-info/RECORD +466 -0
  376. intentkit/abstracts/exception.py +0 -9
  377. intentkit/core/skill.py +0 -200
  378. intentkit/models/generator.py +0 -347
  379. intentkit/skills/cdp/get_balance.py +0 -110
  380. intentkit/skills/cdp/swap.py +0 -121
  381. intentkit/skills/moralis/tests/__init__.py +0 -0
  382. intentkit/skills/moralis/tests/test_wallet.py +0 -511
  383. intentkit-0.6.13.dev2.dist-info/RECORD +0 -409
  384. {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
  385. {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
@@ -1,11 +1,11 @@
1
1
  """Base class for token-related skills."""
2
2
 
3
3
  import logging
4
- from typing import Any, Dict
4
+ from typing import Any
5
5
 
6
6
  import aiohttp
7
7
 
8
- from intentkit.abstracts.skill import SkillStoreABC
8
+ from intentkit.config.config import config
9
9
  from intentkit.skills.base import IntentKitSkill
10
10
  from intentkit.skills.token.constants import MORALIS_API_BASE_URL
11
11
 
@@ -19,10 +19,6 @@ class TokenBaseTool(IntentKitSkill):
19
19
  including making HTTP requests to the Moralis API.
20
20
  """
21
21
 
22
- def __init__(self, skill_store: SkillStoreABC = None):
23
- """Initialize the token tool with a skill store."""
24
- super().__init__(skill_store=skill_store)
25
-
26
22
  @property
27
23
  def category(self) -> str:
28
24
  return "token"
@@ -37,9 +33,9 @@ class TokenBaseTool(IntentKitSkill):
37
33
  skill_config = context.agent.skill_config(self.category)
38
34
  if skill_config.get("api_key_provider") == "agent_owner":
39
35
  return skill_config.get("api_key")
40
- return self.skill_store.get_system_config("moralis_api_key")
36
+ return config.moralis_api_key
41
37
 
42
- def _prepare_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
38
+ def _prepare_params(self, params: dict[str, Any]) -> dict[str, Any]:
43
39
  """Convert boolean values to lowercase strings for API compatibility.
44
40
 
45
41
  Args:
@@ -64,9 +60,9 @@ class TokenBaseTool(IntentKitSkill):
64
60
  method: str,
65
61
  endpoint: str,
66
62
  api_key: str,
67
- params: Dict[str, Any] = None,
68
- data: Dict[str, Any] = None,
69
- ) -> Dict[str, Any]:
63
+ params: dict[str, Any] = None,
64
+ data: dict[str, Any] = None,
65
+ ) -> dict[str, Any]:
70
66
  """Make a request to the Moralis API.
71
67
 
72
68
  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
 
@@ -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:
@@ -5,11 +5,8 @@
5
5
  "type": "object",
6
6
  "x-icon": "https://ai.service.crestal.dev/skills/portfolio/moralis.png",
7
7
  "x-tags": [
8
- "Blockchain",
9
- "Web3",
10
- "Crypto",
11
- "Token",
12
- "DeFi"
8
+ "Analytics",
9
+ "Crypto"
13
10
  ],
14
11
  "properties": {
15
12
  "enabled": {
@@ -138,4 +135,4 @@
138
135
  }
139
136
  },
140
137
  "additionalProperties": true
141
- }
138
+ }
@@ -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,12 +1,11 @@
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.exception import RateLimitExceeded
8
- from intentkit.abstracts.skill import SkillStoreABC
6
+ from intentkit.config.config import config
9
7
  from intentkit.skills.base import IntentKitSkill
8
+ from intentkit.utils.error import RateLimitExceeded
10
9
 
11
10
 
12
11
  class TwitterBaseTool(IntentKitSkill):
@@ -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,24 +33,21 @@ 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:
39
+ context = self.get_context()
40
40
  try:
41
- context = self.get_context()
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,15 +37,14 @@ 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]:
43
+ context = self.get_context()
44
44
  try:
45
- context = self.get_context()
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,32 +33,27 @@ 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):
39
+ context = self.get_context()
40
40
  try:
41
41
  # Ensure max_results is an integer
42
42
  max_results = 10
43
43
 
44
- context = self.get_context()
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