intentkit 0.7.5.dev3__py3-none-any.whl → 0.8.34.dev7__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.
Files changed (393) hide show
  1. intentkit/MANIFEST.in +14 -0
  2. intentkit/README.md +88 -0
  3. intentkit/__init__.py +6 -4
  4. intentkit/abstracts/agent.py +4 -5
  5. intentkit/abstracts/engine.py +5 -5
  6. intentkit/abstracts/graph.py +15 -8
  7. intentkit/abstracts/skill.py +6 -144
  8. intentkit/abstracts/twitter.py +4 -5
  9. intentkit/clients/__init__.py +9 -2
  10. intentkit/clients/cdp.py +129 -153
  11. intentkit/{utils → clients}/s3.py +109 -34
  12. intentkit/clients/twitter.py +83 -62
  13. intentkit/clients/web3.py +4 -7
  14. intentkit/config/config.py +123 -90
  15. intentkit/core/account_checking.py +802 -0
  16. intentkit/core/agent.py +313 -498
  17. intentkit/core/asset.py +267 -0
  18. intentkit/core/chat.py +5 -3
  19. intentkit/core/client.py +1 -1
  20. intentkit/core/credit.py +49 -41
  21. intentkit/core/draft.py +201 -0
  22. intentkit/core/draft_chat.py +118 -0
  23. intentkit/core/engine.py +378 -287
  24. intentkit/core/manager/__init__.py +25 -0
  25. intentkit/core/manager/engine.py +220 -0
  26. intentkit/core/manager/service.py +172 -0
  27. intentkit/core/manager/skills.py +178 -0
  28. intentkit/core/middleware.py +231 -0
  29. intentkit/core/prompt.py +74 -114
  30. intentkit/core/scheduler.py +143 -0
  31. intentkit/core/statistics.py +168 -0
  32. intentkit/models/agent.py +931 -518
  33. intentkit/models/agent_data.py +165 -106
  34. intentkit/models/agent_schema.json +38 -251
  35. intentkit/models/app_setting.py +15 -13
  36. intentkit/models/chat.py +86 -140
  37. intentkit/models/credit.py +182 -162
  38. intentkit/models/db.py +42 -23
  39. intentkit/models/db_mig.py +120 -3
  40. intentkit/models/draft.py +222 -0
  41. intentkit/models/llm.csv +31 -0
  42. intentkit/models/llm.py +262 -370
  43. intentkit/models/redis.py +6 -4
  44. intentkit/models/skill.py +222 -101
  45. intentkit/models/skills.csv +173 -0
  46. intentkit/models/team.py +189 -0
  47. intentkit/models/user.py +103 -31
  48. intentkit/skills/acolyt/__init__.py +2 -9
  49. intentkit/skills/acolyt/ask.py +3 -4
  50. intentkit/skills/acolyt/base.py +4 -9
  51. intentkit/skills/acolyt/schema.json +4 -3
  52. intentkit/skills/aixbt/__init__.py +2 -13
  53. intentkit/skills/aixbt/base.py +1 -7
  54. intentkit/skills/aixbt/projects.py +14 -15
  55. intentkit/skills/aixbt/schema.json +4 -4
  56. intentkit/skills/allora/__init__.py +2 -9
  57. intentkit/skills/allora/base.py +4 -9
  58. intentkit/skills/allora/price.py +3 -4
  59. intentkit/skills/allora/schema.json +3 -2
  60. intentkit/skills/base.py +241 -41
  61. intentkit/skills/basename/__init__.py +51 -0
  62. intentkit/skills/basename/base.py +11 -0
  63. intentkit/skills/basename/basename.svg +11 -0
  64. intentkit/skills/basename/schema.json +58 -0
  65. intentkit/skills/carv/__init__.py +115 -121
  66. intentkit/skills/carv/base.py +184 -185
  67. intentkit/skills/carv/fetch_news.py +3 -3
  68. intentkit/skills/carv/onchain_query.py +4 -4
  69. intentkit/skills/carv/schema.json +134 -137
  70. intentkit/skills/carv/token_info_and_price.py +6 -6
  71. intentkit/skills/casino/__init__.py +4 -15
  72. intentkit/skills/casino/base.py +1 -7
  73. intentkit/skills/casino/deck_draw.py +5 -8
  74. intentkit/skills/casino/deck_shuffle.py +6 -6
  75. intentkit/skills/casino/dice_roll.py +2 -4
  76. intentkit/skills/casino/schema.json +0 -1
  77. intentkit/skills/cdp/__init__.py +22 -84
  78. intentkit/skills/cdp/base.py +1 -7
  79. intentkit/skills/cdp/schema.json +11 -314
  80. intentkit/skills/chainlist/__init__.py +2 -7
  81. intentkit/skills/chainlist/base.py +1 -7
  82. intentkit/skills/chainlist/chain_lookup.py +18 -18
  83. intentkit/skills/chainlist/schema.json +3 -5
  84. intentkit/skills/common/__init__.py +2 -9
  85. intentkit/skills/common/base.py +1 -7
  86. intentkit/skills/common/current_time.py +1 -2
  87. intentkit/skills/common/schema.json +2 -2
  88. intentkit/skills/cookiefun/__init__.py +6 -9
  89. intentkit/skills/cookiefun/base.py +2 -7
  90. intentkit/skills/cookiefun/get_account_details.py +7 -7
  91. intentkit/skills/cookiefun/get_account_feed.py +19 -19
  92. intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
  93. intentkit/skills/cookiefun/get_sectors.py +3 -3
  94. intentkit/skills/cookiefun/schema.json +1 -3
  95. intentkit/skills/cookiefun/search_accounts.py +9 -9
  96. intentkit/skills/cryptocompare/__init__.py +7 -24
  97. intentkit/skills/cryptocompare/api.py +2 -3
  98. intentkit/skills/cryptocompare/base.py +10 -24
  99. intentkit/skills/cryptocompare/fetch_news.py +4 -5
  100. intentkit/skills/cryptocompare/fetch_price.py +6 -7
  101. intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
  102. intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
  103. intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
  104. intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
  105. intentkit/skills/cryptocompare/schema.json +3 -3
  106. intentkit/skills/cryptopanic/__init__.py +7 -10
  107. intentkit/skills/cryptopanic/base.py +51 -55
  108. intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
  109. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
  110. intentkit/skills/cryptopanic/schema.json +105 -103
  111. intentkit/skills/dapplooker/__init__.py +2 -9
  112. intentkit/skills/dapplooker/base.py +4 -9
  113. intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
  114. intentkit/skills/dapplooker/schema.json +3 -5
  115. intentkit/skills/defillama/__init__.py +24 -74
  116. intentkit/skills/defillama/api.py +6 -9
  117. intentkit/skills/defillama/base.py +8 -19
  118. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
  119. intentkit/skills/defillama/coins/fetch_block.py +6 -8
  120. intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
  121. intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
  122. intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
  123. intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
  124. intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
  125. intentkit/skills/defillama/config/chains.py +1 -3
  126. intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
  127. intentkit/skills/defillama/schema.json +5 -1
  128. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
  129. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
  130. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
  131. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
  132. intentkit/skills/defillama/tests/api_integration.test.py +1 -1
  133. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
  134. intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
  135. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
  136. intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
  137. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
  138. intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
  139. intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
  140. intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
  141. intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
  142. intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
  143. intentkit/skills/defillama/yields/fetch_pools.py +26 -30
  144. intentkit/skills/dexscreener/__init__.py +97 -102
  145. intentkit/skills/dexscreener/base.py +125 -130
  146. intentkit/skills/dexscreener/get_pair_info.py +4 -5
  147. intentkit/skills/dexscreener/get_token_pairs.py +4 -5
  148. intentkit/skills/dexscreener/get_tokens_info.py +7 -8
  149. intentkit/skills/dexscreener/model/search_token_response.py +80 -82
  150. intentkit/skills/dexscreener/schema.json +91 -93
  151. intentkit/skills/dexscreener/search_token.py +182 -184
  152. intentkit/skills/dexscreener/utils.py +15 -14
  153. intentkit/skills/dune_analytics/__init__.py +7 -9
  154. intentkit/skills/dune_analytics/base.py +48 -52
  155. intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
  156. intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
  157. intentkit/skills/dune_analytics/schema.json +104 -99
  158. intentkit/skills/elfa/__init__.py +5 -18
  159. intentkit/skills/elfa/base.py +10 -14
  160. intentkit/skills/elfa/mention.py +19 -21
  161. intentkit/skills/elfa/schema.json +3 -2
  162. intentkit/skills/elfa/stats.py +4 -4
  163. intentkit/skills/elfa/tokens.py +12 -12
  164. intentkit/skills/elfa/utils.py +26 -28
  165. intentkit/skills/enso/__init__.py +11 -31
  166. intentkit/skills/enso/base.py +54 -35
  167. intentkit/skills/enso/best_yield.py +16 -24
  168. intentkit/skills/enso/networks.py +6 -11
  169. intentkit/skills/enso/prices.py +11 -13
  170. intentkit/skills/enso/route.py +34 -38
  171. intentkit/skills/enso/schema.json +3 -2
  172. intentkit/skills/enso/tokens.py +29 -38
  173. intentkit/skills/enso/wallet.py +76 -191
  174. intentkit/skills/erc20/__init__.py +50 -0
  175. intentkit/skills/erc20/base.py +11 -0
  176. intentkit/skills/erc20/erc20.svg +5 -0
  177. intentkit/skills/erc20/schema.json +74 -0
  178. intentkit/skills/erc721/__init__.py +53 -0
  179. intentkit/skills/erc721/base.py +11 -0
  180. intentkit/skills/erc721/erc721.svg +5 -0
  181. intentkit/skills/erc721/schema.json +90 -0
  182. intentkit/skills/firecrawl/__init__.py +5 -18
  183. intentkit/skills/firecrawl/base.py +4 -9
  184. intentkit/skills/firecrawl/clear.py +4 -8
  185. intentkit/skills/firecrawl/crawl.py +19 -19
  186. intentkit/skills/firecrawl/query.py +4 -3
  187. intentkit/skills/firecrawl/schema.json +2 -6
  188. intentkit/skills/firecrawl/scrape.py +17 -22
  189. intentkit/skills/firecrawl/utils.py +50 -42
  190. intentkit/skills/github/__init__.py +2 -7
  191. intentkit/skills/github/base.py +1 -7
  192. intentkit/skills/github/github_search.py +1 -2
  193. intentkit/skills/github/schema.json +3 -4
  194. intentkit/skills/heurist/__init__.py +8 -27
  195. intentkit/skills/heurist/base.py +4 -9
  196. intentkit/skills/heurist/image_generation_animagine_xl.py +13 -15
  197. intentkit/skills/heurist/image_generation_arthemy_comics.py +13 -15
  198. intentkit/skills/heurist/image_generation_arthemy_real.py +13 -15
  199. intentkit/skills/heurist/image_generation_braindance.py +13 -15
  200. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +13 -15
  201. intentkit/skills/heurist/image_generation_flux_1_dev.py +13 -15
  202. intentkit/skills/heurist/image_generation_sdxl.py +13 -15
  203. intentkit/skills/heurist/schema.json +2 -2
  204. intentkit/skills/http/__init__.py +4 -15
  205. intentkit/skills/http/base.py +1 -7
  206. intentkit/skills/http/get.py +21 -16
  207. intentkit/skills/http/post.py +23 -18
  208. intentkit/skills/http/put.py +23 -18
  209. intentkit/skills/http/schema.json +4 -5
  210. intentkit/skills/lifi/__init__.py +8 -13
  211. intentkit/skills/lifi/base.py +3 -9
  212. intentkit/skills/lifi/schema.json +17 -8
  213. intentkit/skills/lifi/token_execute.py +150 -60
  214. intentkit/skills/lifi/token_quote.py +8 -10
  215. intentkit/skills/lifi/utils.py +104 -51
  216. intentkit/skills/moralis/__init__.py +6 -10
  217. intentkit/skills/moralis/api.py +6 -7
  218. intentkit/skills/moralis/base.py +5 -10
  219. intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
  220. intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
  221. intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
  222. intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
  223. intentkit/skills/moralis/schema.json +7 -2
  224. intentkit/skills/morpho/__init__.py +52 -0
  225. intentkit/skills/morpho/base.py +11 -0
  226. intentkit/skills/morpho/morpho.svg +12 -0
  227. intentkit/skills/morpho/schema.json +73 -0
  228. intentkit/skills/nation/__init__.py +4 -9
  229. intentkit/skills/nation/base.py +5 -10
  230. intentkit/skills/nation/nft_check.py +3 -4
  231. intentkit/skills/nation/schema.json +4 -3
  232. intentkit/skills/onchain.py +30 -0
  233. intentkit/skills/openai/__init__.py +17 -18
  234. intentkit/skills/openai/base.py +10 -14
  235. intentkit/skills/openai/dalle_image_generation.py +4 -9
  236. intentkit/skills/openai/gpt_avatar_generator.py +102 -0
  237. intentkit/skills/openai/gpt_image_generation.py +5 -9
  238. intentkit/skills/openai/gpt_image_mini_generator.py +92 -0
  239. intentkit/skills/openai/gpt_image_to_image.py +5 -9
  240. intentkit/skills/openai/image_to_text.py +3 -7
  241. intentkit/skills/openai/schema.json +34 -3
  242. intentkit/skills/portfolio/__init__.py +11 -35
  243. intentkit/skills/portfolio/base.py +33 -19
  244. intentkit/skills/portfolio/schema.json +3 -5
  245. intentkit/skills/portfolio/token_balances.py +21 -21
  246. intentkit/skills/portfolio/wallet_approvals.py +17 -18
  247. intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
  248. intentkit/skills/portfolio/wallet_history.py +31 -31
  249. intentkit/skills/portfolio/wallet_net_worth.py +13 -13
  250. intentkit/skills/portfolio/wallet_nfts.py +19 -19
  251. intentkit/skills/portfolio/wallet_profitability.py +18 -18
  252. intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
  253. intentkit/skills/portfolio/wallet_stats.py +3 -3
  254. intentkit/skills/portfolio/wallet_swaps.py +19 -19
  255. intentkit/skills/pyth/__init__.py +50 -0
  256. intentkit/skills/pyth/base.py +11 -0
  257. intentkit/skills/pyth/pyth.svg +6 -0
  258. intentkit/skills/pyth/schema.json +75 -0
  259. intentkit/skills/skills.toml +36 -0
  260. intentkit/skills/slack/__init__.py +5 -17
  261. intentkit/skills/slack/base.py +3 -9
  262. intentkit/skills/slack/get_channel.py +8 -8
  263. intentkit/skills/slack/get_message.py +9 -9
  264. intentkit/skills/slack/schedule_message.py +5 -5
  265. intentkit/skills/slack/schema.json +2 -2
  266. intentkit/skills/slack/send_message.py +3 -5
  267. intentkit/skills/supabase/__init__.py +7 -23
  268. intentkit/skills/supabase/base.py +1 -7
  269. intentkit/skills/supabase/delete_data.py +4 -4
  270. intentkit/skills/supabase/fetch_data.py +12 -12
  271. intentkit/skills/supabase/insert_data.py +4 -4
  272. intentkit/skills/supabase/invoke_function.py +6 -6
  273. intentkit/skills/supabase/schema.json +2 -3
  274. intentkit/skills/supabase/update_data.py +6 -6
  275. intentkit/skills/supabase/upsert_data.py +4 -4
  276. intentkit/skills/superfluid/__init__.py +53 -0
  277. intentkit/skills/superfluid/base.py +11 -0
  278. intentkit/skills/superfluid/schema.json +89 -0
  279. intentkit/skills/superfluid/superfluid.svg +6 -0
  280. intentkit/skills/system/__init__.py +7 -24
  281. intentkit/skills/system/add_autonomous_task.py +10 -12
  282. intentkit/skills/system/delete_autonomous_task.py +2 -2
  283. intentkit/skills/system/edit_autonomous_task.py +14 -18
  284. intentkit/skills/system/list_autonomous_tasks.py +3 -5
  285. intentkit/skills/system/read_agent_api_key.py +6 -4
  286. intentkit/skills/system/regenerate_agent_api_key.py +6 -4
  287. intentkit/skills/system/schema.json +6 -8
  288. intentkit/skills/tavily/__init__.py +3 -12
  289. intentkit/skills/tavily/base.py +4 -9
  290. intentkit/skills/tavily/schema.json +3 -5
  291. intentkit/skills/tavily/tavily_extract.py +2 -4
  292. intentkit/skills/tavily/tavily_search.py +4 -6
  293. intentkit/skills/token/__init__.py +5 -10
  294. intentkit/skills/token/base.py +7 -11
  295. intentkit/skills/token/erc20_transfers.py +19 -19
  296. intentkit/skills/token/schema.json +3 -6
  297. intentkit/skills/token/token_analytics.py +3 -3
  298. intentkit/skills/token/token_price.py +13 -13
  299. intentkit/skills/token/token_search.py +9 -9
  300. intentkit/skills/twitter/__init__.py +11 -35
  301. intentkit/skills/twitter/base.py +22 -34
  302. intentkit/skills/twitter/follow_user.py +2 -6
  303. intentkit/skills/twitter/get_mentions.py +5 -12
  304. intentkit/skills/twitter/get_timeline.py +4 -12
  305. intentkit/skills/twitter/get_user_by_username.py +2 -6
  306. intentkit/skills/twitter/get_user_tweets.py +5 -13
  307. intentkit/skills/twitter/like_tweet.py +2 -6
  308. intentkit/skills/twitter/post_tweet.py +6 -9
  309. intentkit/skills/twitter/reply_tweet.py +6 -9
  310. intentkit/skills/twitter/retweet.py +2 -6
  311. intentkit/skills/twitter/schema.json +1 -0
  312. intentkit/skills/twitter/search_tweets.py +4 -12
  313. intentkit/skills/unrealspeech/__init__.py +2 -7
  314. intentkit/skills/unrealspeech/base.py +2 -8
  315. intentkit/skills/unrealspeech/schema.json +2 -5
  316. intentkit/skills/unrealspeech/text_to_speech.py +8 -8
  317. intentkit/skills/venice_audio/__init__.py +98 -106
  318. intentkit/skills/venice_audio/base.py +117 -121
  319. intentkit/skills/venice_audio/input.py +41 -41
  320. intentkit/skills/venice_audio/schema.json +151 -152
  321. intentkit/skills/venice_audio/venice_audio.py +38 -21
  322. intentkit/skills/venice_image/__init__.py +147 -154
  323. intentkit/skills/venice_image/api.py +138 -138
  324. intentkit/skills/venice_image/base.py +185 -192
  325. intentkit/skills/venice_image/config.py +33 -35
  326. intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
  327. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
  328. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
  329. intentkit/skills/venice_image/image_generation/image_generation_base.py +11 -10
  330. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
  331. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
  332. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
  333. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
  334. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
  335. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
  336. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
  337. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
  338. intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
  339. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
  340. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
  341. intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
  342. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
  343. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
  344. intentkit/skills/venice_image/schema.json +267 -267
  345. intentkit/skills/venice_image/utils.py +77 -78
  346. intentkit/skills/web_scraper/__init__.py +5 -18
  347. intentkit/skills/web_scraper/base.py +21 -7
  348. intentkit/skills/web_scraper/document_indexer.py +7 -6
  349. intentkit/skills/web_scraper/schema.json +2 -6
  350. intentkit/skills/web_scraper/scrape_and_index.py +15 -15
  351. intentkit/skills/web_scraper/utils.py +62 -63
  352. intentkit/skills/web_scraper/website_indexer.py +17 -19
  353. intentkit/skills/weth/__init__.py +49 -0
  354. intentkit/skills/weth/base.py +11 -0
  355. intentkit/skills/weth/schema.json +58 -0
  356. intentkit/skills/weth/weth.svg +6 -0
  357. intentkit/skills/wow/__init__.py +51 -0
  358. intentkit/skills/wow/base.py +11 -0
  359. intentkit/skills/wow/schema.json +89 -0
  360. intentkit/skills/wow/wow.svg +7 -0
  361. intentkit/skills/x402/__init__.py +58 -0
  362. intentkit/skills/x402/base.py +99 -0
  363. intentkit/skills/x402/http_request.py +117 -0
  364. intentkit/skills/x402/schema.json +40 -0
  365. intentkit/skills/x402/x402.webp +0 -0
  366. intentkit/skills/xmtp/__init__.py +4 -15
  367. intentkit/skills/xmtp/base.py +5 -5
  368. intentkit/skills/xmtp/price.py +7 -6
  369. intentkit/skills/xmtp/schema.json +69 -71
  370. intentkit/skills/xmtp/swap.py +6 -8
  371. intentkit/skills/xmtp/transfer.py +4 -6
  372. intentkit/utils/__init__.py +4 -0
  373. intentkit/utils/chain.py +198 -96
  374. intentkit/utils/ens.py +135 -0
  375. intentkit/utils/error.py +5 -2
  376. intentkit/utils/logging.py +9 -11
  377. intentkit/utils/schema.py +100 -0
  378. intentkit/utils/slack_alert.py +8 -8
  379. intentkit/utils/tx.py +16 -8
  380. intentkit/uv.lock +3377 -0
  381. {intentkit-0.7.5.dev3.dist-info → intentkit-0.8.34.dev7.dist-info}/METADATA +13 -15
  382. intentkit-0.8.34.dev7.dist-info/RECORD +478 -0
  383. intentkit-0.8.34.dev7.dist-info/licenses/LICENSE +21 -0
  384. intentkit/core/node.py +0 -215
  385. intentkit/models/conversation.py +0 -286
  386. intentkit/models/generator.py +0 -347
  387. intentkit/skills/cdp/get_balance.py +0 -110
  388. intentkit/skills/cdp/swap.py +0 -121
  389. intentkit/skills/moralis/tests/__init__.py +0 -0
  390. intentkit/skills/moralis/tests/test_wallet.py +0 -511
  391. intentkit-0.7.5.dev3.dist-info/RECORD +0 -424
  392. {intentkit-0.7.5.dev3.dist-info/licenses → intentkit}/LICENSE +0 -0
  393. {intentkit-0.7.5.dev3.dist-info → intentkit-0.8.34.dev7.dist-info}/WHEEL +0 -0
intentkit/skills/base.py CHANGED
@@ -1,7 +1,19 @@
1
1
  import logging
2
- from typing import Any, Callable, Dict, Literal, NotRequired, Optional, TypedDict, Union
2
+ from collections.abc import Callable, Sequence
3
+ from typing import (
4
+ Any,
5
+ Literal,
6
+ NotRequired,
7
+ TypedDict,
8
+ )
3
9
 
4
- from langchain_core.tools import BaseTool
10
+ from coinbase_agentkit import (
11
+ Action,
12
+ AgentKit,
13
+ AgentKitConfig,
14
+ CdpEvmWalletProvider,
15
+ )
16
+ from langchain_core.tools import BaseTool, StructuredTool
5
17
  from langchain_core.tools.base import ToolException
6
18
  from langgraph.runtime import get_runtime
7
19
  from pydantic import (
@@ -9,13 +21,18 @@ from pydantic import (
9
21
  )
10
22
  from pydantic.v1 import ValidationError as ValidationErrorV1
11
23
  from redis.exceptions import RedisError
12
- from web3 import Web3
13
24
 
14
25
  from intentkit.abstracts.graph import AgentContext
15
- from intentkit.abstracts.skill import SkillStoreABC
16
- from intentkit.clients.web3 import get_web3_client
26
+ from intentkit.clients import get_wallet_provider
27
+ from intentkit.models.agent import Agent
17
28
  from intentkit.models.redis import get_redis
18
- from intentkit.utils.error import RateLimitExceeded
29
+ from intentkit.models.skill import (
30
+ AgentSkillData,
31
+ AgentSkillDataCreate,
32
+ ChatSkillData,
33
+ ChatSkillDataCreate,
34
+ )
35
+ from intentkit.utils.error import IntentKitAPIError, RateLimitExceeded
19
36
 
20
37
  SkillState = Literal["disabled", "public", "private"]
21
38
  SkillOwnerState = Literal["disabled", "private"]
@@ -26,9 +43,9 @@ class SkillConfig(TypedDict):
26
43
  """Abstract base class for skill configuration."""
27
44
 
28
45
  enabled: bool
29
- states: Dict[str, SkillState | SkillOwnerState]
46
+ states: dict[str, SkillState | SkillOwnerState]
30
47
  api_key_provider: NotRequired[APIKeyProviderValue]
31
- __extra__: NotRequired[Dict[str, Any]]
48
+ __extra__: NotRequired[dict[str, Any]]
32
49
 
33
50
 
34
51
  class IntentKitSkill(BaseTool):
@@ -36,17 +53,16 @@ class IntentKitSkill(BaseTool):
36
53
  Will have predefined abilities.
37
54
  """
38
55
 
39
- skill_store: SkillStoreABC
40
56
  # overwrite the value of BaseTool
41
- handle_tool_error: Optional[Union[bool, str, Callable[[ToolException], str]]] = (
57
+ handle_tool_error: bool | str | Callable[[ToolException], str] | None = (
42
58
  lambda e: f"tool error: {e}"
43
59
  )
44
60
  """Handle the content of the ToolException thrown."""
45
61
 
46
62
  # overwrite the value of BaseTool
47
- handle_validation_error: Optional[
48
- Union[bool, str, Callable[[Union[ValidationError, ValidationErrorV1]], str]]
49
- ] = lambda e: f"validation error: {e}"
63
+ handle_validation_error: (
64
+ bool | str | Callable[[ValidationError | ValidationErrorV1], str] | None
65
+ ) = lambda e: f"validation error: {e}"
50
66
  """Handle the content of the ValidationError thrown."""
51
67
 
52
68
  # Logger for the class
@@ -57,15 +73,12 @@ class IntentKitSkill(BaseTool):
57
73
  """Get the category of the skill."""
58
74
  raise NotImplementedError
59
75
 
60
- async def user_rate_limit(
61
- self, user_id: str, limit: int, minutes: int, key: str
62
- ) -> None:
76
+ async def user_rate_limit(self, limit: int, seconds: int, key: str) -> None:
63
77
  """Check if a user has exceeded the rate limit for this skill.
64
78
 
65
79
  Args:
66
- user_id: The ID of the user to check
67
80
  limit: Maximum number of requests allowed
68
- minutes: Time window in minutes
81
+ seconds: Time window in seconds
69
82
  key: The key to use for rate limiting (e.g., skill name or category)
70
83
 
71
84
  Raises:
@@ -74,25 +87,48 @@ class IntentKitSkill(BaseTool):
74
87
  Returns:
75
88
  None: Always returns None if no exception is raised
76
89
  """
77
- if not user_id:
78
- return None # No rate limiting for users without ID
90
+ try:
91
+ context = self.get_context()
92
+ except ValueError:
93
+ self.logger.info(
94
+ "AgentContext not available, skipping rate limit for %s",
95
+ key,
96
+ )
97
+ return None
98
+
99
+ user_identifier = context.user_id or context.agent_id
100
+ if not user_identifier:
101
+ return None # No rate limiting when no identifier is available
102
+
103
+ try:
104
+ max_requests = int(limit)
105
+ window_seconds = int(seconds)
106
+ except (TypeError, ValueError):
107
+ self.logger.info(
108
+ "Invalid user rate limit parameters for %s: limit=%r, seconds=%r",
109
+ key,
110
+ limit,
111
+ seconds,
112
+ )
113
+ return None
114
+
115
+ if window_seconds <= 0 or max_requests <= 0:
116
+ return None
79
117
 
80
118
  try:
81
119
  redis = get_redis()
82
120
  # Create a unique key for this rate limit and user
83
- rate_limit_key = f"rate_limit:{key}:{user_id}"
121
+ rate_limit_key = f"rate_limit:{key}:{user_identifier}"
84
122
 
85
123
  # Get the current count
86
124
  count = await redis.incr(rate_limit_key)
87
125
 
88
126
  # Set expiration if this is the first request
89
127
  if count == 1:
90
- await redis.expire(
91
- rate_limit_key, minutes * 60
92
- ) # Convert minutes to seconds
128
+ await redis.expire(rate_limit_key, window_seconds)
93
129
 
94
130
  # Check if user has exceeded the limit
95
- if count > limit:
131
+ if count > max_requests:
96
132
  raise RateLimitExceeded(f"Rate limit exceeded for {key}")
97
133
 
98
134
  return None
@@ -108,40 +144,97 @@ class IntentKitSkill(BaseTool):
108
144
  )
109
145
  return None
110
146
 
111
- async def user_rate_limit_by_skill(
112
- self, user_id: str, limit: int, minutes: int
113
- ) -> None:
147
+ async def user_rate_limit_by_skill(self, limit: int, seconds: int) -> None:
114
148
  """Check if a user has exceeded the rate limit for this specific skill.
115
149
 
116
150
  This uses the skill name as the rate limit key.
117
151
 
118
152
  Args:
119
- user_id: The ID of the user to check
120
153
  limit: Maximum number of requests allowed
121
- minutes: Time window in minutes
154
+ seconds: Time window in seconds
122
155
 
123
156
  Raises:
124
157
  RateLimitExceeded: If the user has exceeded the rate limit
125
158
  """
126
- return await self.user_rate_limit(user_id, limit, minutes, self.name)
159
+ return await self.user_rate_limit(limit, seconds, self.name)
127
160
 
128
- async def user_rate_limit_by_category(
129
- self, user_id: str, limit: int, minutes: int
130
- ) -> None:
161
+ async def user_rate_limit_by_category(self, limit: int, seconds: int) -> None:
131
162
  """Check if a user has exceeded the rate limit for this skill category.
132
163
 
133
164
  This uses the skill category as the rate limit key, which means the limit
134
165
  is shared across all skills in the same category.
135
166
 
136
167
  Args:
137
- user_id: The ID of the user to check
138
168
  limit: Maximum number of requests allowed
139
- minutes: Time window in minutes
169
+ seconds: Time window in seconds
140
170
 
141
171
  Raises:
142
172
  RateLimitExceeded: If the user has exceeded the rate limit
143
173
  """
144
- return await self.user_rate_limit(user_id, limit, minutes, self.category)
174
+ return await self.user_rate_limit(limit, seconds, self.category)
175
+
176
+ async def global_rate_limit(self, limit: int, seconds: int, key: str) -> None:
177
+ """Check if a global rate limit has been exceeded for a given key.
178
+
179
+ Args:
180
+ limit: Maximum number of requests allowed
181
+ seconds: Time window in seconds
182
+ key: The key to use for rate limiting (e.g., skill name or category)
183
+
184
+ Raises:
185
+ RateLimitExceeded: If the global limit has been exceeded
186
+
187
+ Returns:
188
+ None: Always returns None if no exception is raised
189
+ """
190
+ try:
191
+ max_requests = int(limit)
192
+ window_seconds = int(seconds)
193
+ except (TypeError, ValueError):
194
+ self.logger.info(
195
+ "Invalid global rate limit parameters for %s: limit=%r, seconds=%r",
196
+ key,
197
+ limit,
198
+ seconds,
199
+ )
200
+ return None
201
+
202
+ if window_seconds <= 0 or max_requests <= 0:
203
+ return None
204
+
205
+ try:
206
+ redis = get_redis()
207
+ rate_limit_key = f"rate_limit:{key}"
208
+
209
+ count = await redis.incr(rate_limit_key)
210
+
211
+ if count == 1:
212
+ await redis.expire(rate_limit_key, window_seconds)
213
+
214
+ if count > max_requests:
215
+ raise RateLimitExceeded(f"Global rate limit exceeded for {key}")
216
+
217
+ return None
218
+
219
+ except RuntimeError:
220
+ self.logger.info(
221
+ "Redis not initialized, skipping global rate limit for %s",
222
+ key,
223
+ )
224
+ return None
225
+ except RedisError as e:
226
+ self.logger.info(
227
+ f"Redis error in global rate limiting: {e}, skipping rate limit for {key}"
228
+ )
229
+ return None
230
+
231
+ async def global_rate_limit_by_skill(self, limit: int, seconds: int) -> None:
232
+ """Apply a global rate limit scoped to this specific skill."""
233
+ return await self.global_rate_limit(limit, seconds, self.name)
234
+
235
+ async def global_rate_limit_by_category(self, limit: int, seconds: int) -> None:
236
+ """Apply a global rate limit scoped to this skill category."""
237
+ return await self.global_rate_limit(limit, seconds, self.category)
145
238
 
146
239
  def _run(self, *args: Any, **kwargs: Any) -> Any:
147
240
  raise NotImplementedError(
@@ -155,10 +248,117 @@ class IntentKitSkill(BaseTool):
155
248
  raise ValueError("No AgentContext found")
156
249
  return runtime.context
157
250
 
158
- def web3_client(self) -> Web3:
159
- """Get a Web3 client for the skill."""
251
+ async def get_agent_skill_data(
252
+ self,
253
+ key: str,
254
+ ) -> dict[str, Any] | None:
255
+ """Retrieve persisted data for this skill scoped to the active agent."""
256
+ return await self.get_agent_skill_data_raw(self.name, key)
257
+
258
+ async def get_agent_skill_data_raw(
259
+ self,
260
+ skill_name: str,
261
+ key: str,
262
+ ) -> dict[str, Any] | None:
263
+ """Retrieve persisted data for a specific skill scoped to the active agent."""
264
+ context = self.get_context()
265
+ return await AgentSkillData.get(context.agent_id, skill_name, key)
266
+
267
+ async def save_agent_skill_data(self, key: str, data: dict[str, Any]) -> None:
268
+ """Persist data for this skill scoped to the active agent."""
269
+ await self.save_agent_skill_data_raw(self.name, key, data)
270
+
271
+ async def save_agent_skill_data_raw(
272
+ self,
273
+ skill_name: str,
274
+ key: str,
275
+ data: dict[str, Any],
276
+ ) -> None:
277
+ """Persist data for a specific skill scoped to the active agent."""
160
278
  context = self.get_context()
279
+ skill_data = AgentSkillDataCreate(
280
+ agent_id=context.agent_id,
281
+ skill=skill_name,
282
+ key=key,
283
+ data=data,
284
+ )
285
+ await skill_data.save()
286
+
287
+ async def delete_agent_skill_data(self, key: str) -> None:
288
+ """Remove persisted data for this skill scoped to the active agent."""
289
+ context = self.get_context()
290
+ await AgentSkillData.delete(context.agent_id, self.name, key)
291
+
292
+ async def get_thread_skill_data(
293
+ self,
294
+ key: str,
295
+ ) -> dict[str, Any] | None:
296
+ """Retrieve persisted data for this skill scoped to the active chat."""
297
+ context = self.get_context()
298
+ return await ChatSkillData.get(context.chat_id, self.name, key)
299
+
300
+ async def save_thread_skill_data(self, key: str, data: dict[str, Any]) -> None:
301
+ """Persist data for this skill scoped to the active chat."""
302
+ context = self.get_context()
303
+ skill_data = ChatSkillDataCreate(
304
+ chat_id=context.chat_id,
305
+ agent_id=context.agent_id,
306
+ skill=self.name,
307
+ key=key,
308
+ data=data,
309
+ )
310
+ await skill_data.save()
311
+
312
+
313
+ async def get_agentkit_actions(
314
+ agent_id: str,
315
+ provider_factories: Sequence[Callable[[], object]],
316
+ *,
317
+ agent: Agent | None = None,
318
+ ) -> list[Action]:
319
+ """Build an AgentKit instance and return its actions."""
320
+
321
+ if agent is None:
322
+ try:
323
+ context = IntentKitSkill.get_context()
324
+ except ValueError as exc: # pragma: no cover - defensive guard
325
+ raise IntentKitAPIError(
326
+ 500,
327
+ "AgentContextMissing",
328
+ "Agent context is required to initialize AgentKit actions.",
329
+ ) from exc
161
330
  agent = context.agent
162
- network_id = agent.network_id
163
331
 
164
- return get_web3_client(network_id, self.skill_store)
332
+ if agent.id != agent_id:
333
+ raise IntentKitAPIError(
334
+ 400,
335
+ "AgentMismatch",
336
+ "The requested agent does not match the active context agent.",
337
+ )
338
+
339
+ wallet_provider: CdpEvmWalletProvider = await get_wallet_provider(agent)
340
+
341
+ agent_kit = AgentKit(
342
+ AgentKitConfig(
343
+ wallet_provider=wallet_provider,
344
+ action_providers=[factory() for factory in provider_factories],
345
+ )
346
+ )
347
+ return agent_kit.get_actions()
348
+
349
+
350
+ def action_to_structured_tool(action: Action) -> StructuredTool:
351
+ """Convert an AgentKit action to a LangChain StructuredTool."""
352
+
353
+ def _tool_fn(**kwargs: object) -> str:
354
+ return action.invoke(kwargs)
355
+
356
+ tool = StructuredTool(
357
+ name=action.name,
358
+ description=action.description,
359
+ func=_tool_fn,
360
+ args_schema=action.args_schema,
361
+ )
362
+ tool.handle_tool_error = lambda e: f"tool error: {e}"
363
+ tool.handle_validation_error = lambda e: f"validation error: {e}"
364
+ return tool
@@ -0,0 +1,51 @@
1
+ """Basename AgentKit skills."""
2
+
3
+ from typing import TypedDict
4
+
5
+ from coinbase_agentkit import basename_action_provider
6
+
7
+ from intentkit.models.agent import Agent
8
+ from intentkit.skills.base import (
9
+ SkillConfig,
10
+ SkillState,
11
+ action_to_structured_tool,
12
+ get_agentkit_actions,
13
+ )
14
+ from intentkit.skills.basename.base import BasenameBaseTool
15
+
16
+
17
+ class SkillStates(TypedDict):
18
+ BasenameActionProvider_register_basename: SkillState
19
+
20
+
21
+ class Config(SkillConfig):
22
+ """Configuration for Basename skills."""
23
+
24
+ states: SkillStates
25
+
26
+
27
+ async def get_skills(
28
+ config: "Config",
29
+ is_private: bool,
30
+ agent_id: str,
31
+ agent: Agent | None = None,
32
+ **_,
33
+ ) -> list[BasenameBaseTool]:
34
+ """Get all Basename skills."""
35
+
36
+ available_skills: list[str] = []
37
+ for skill_name, state in config["states"].items():
38
+ if state == "disabled":
39
+ continue
40
+ if state == "public" or (state == "private" and is_private):
41
+ available_skills.append(skill_name)
42
+
43
+ actions = await get_agentkit_actions(
44
+ agent_id, [basename_action_provider], agent=agent
45
+ )
46
+ tools: list[BasenameBaseTool] = []
47
+ for skill in available_skills:
48
+ for action in actions:
49
+ if action.name.endswith(skill):
50
+ tools.append(action_to_structured_tool(action))
51
+ return tools
@@ -0,0 +1,11 @@
1
+ """Basename AgentKit skills base class."""
2
+
3
+ from intentkit.skills.cdp.base import CDPBaseTool
4
+
5
+
6
+ class BasenameBaseTool(CDPBaseTool):
7
+ """Base class for Basename tools."""
8
+
9
+ @property
10
+ def category(self) -> str:
11
+ return "basename"
@@ -0,0 +1,11 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" stop-color="#4c7dff" />
5
+ <stop offset="100%" stop-color="#0b2f80" />
6
+ </linearGradient>
7
+ </defs>
8
+ <rect width="128" height="128" fill="url(#bg)" rx="16" />
9
+ <text x="50%" y="52%" font-family="Arial,Helvetica,sans-serif" font-size="60" fill="#ffffff" font-weight="700" text-anchor="middle">B</text>
10
+ <text x="50%" y="86%" font-family="Arial,Helvetica,sans-serif" font-size="20" fill="#dbe4ff" text-anchor="middle">Base</text>
11
+ </svg>
@@ -0,0 +1,58 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "Basename",
5
+ "description": "Basename ENS-style name registration via Coinbase AgentKit",
6
+ "x-icon": "https://ai.service.crestal.dev/skills/basename/basename.svg",
7
+ "x-tags": [
8
+ "Crypto",
9
+ "Identity"
10
+ ],
11
+ "properties": {
12
+ "enabled": {
13
+ "type": "boolean",
14
+ "title": "Enabled",
15
+ "description": "Whether this skill is enabled",
16
+ "default": false
17
+ },
18
+ "states": {
19
+ "type": "object",
20
+ "properties": {
21
+ "BasenameActionProvider_register_basename": {
22
+ "type": "string",
23
+ "title": "Register Basename",
24
+ "enum": [
25
+ "disabled",
26
+ "public",
27
+ "private"
28
+ ],
29
+ "x-enum-title": [
30
+ "Disabled",
31
+ "Agent Owner + All Users",
32
+ "Agent Owner Only"
33
+ ],
34
+ "description": "State for BasenameActionProvider_register_basename",
35
+ "default": "disabled"
36
+ }
37
+ },
38
+ "description": "States for each Basename skill (disabled, public, or private)"
39
+ },
40
+ "api_key_provider": {
41
+ "type": "string",
42
+ "title": "API Key Provider",
43
+ "description": "Who provides the API key",
44
+ "enum": [
45
+ "platform"
46
+ ],
47
+ "x-enum-title": [
48
+ "Nation Hosted"
49
+ ],
50
+ "default": "platform"
51
+ }
52
+ },
53
+ "required": [
54
+ "states",
55
+ "enabled"
56
+ ],
57
+ "additionalProperties": true
58
+ }