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/utils/ens.py ADDED
@@ -0,0 +1,135 @@
1
+ """Utilities for resolving ENS domains to wallet addresses."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import logging
7
+
8
+ from ens import ENS
9
+ from web3 import Web3
10
+ from web3.middleware import ExtraDataToPOAMiddleware
11
+
12
+ from intentkit.config.config import config
13
+ from intentkit.models.redis import get_redis
14
+ from intentkit.utils.error import IntentKitAPIError
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ _CACHE_PREFIX = "intentkit:ens:"
19
+ _CACHE_TTL_SECONDS = 4 * 60 * 60
20
+
21
+ _NETWORKS_BY_SUFFIX: dict[str, tuple[str, ...]] = {
22
+ ".base.eth": ("base-mainnet", "ethereum-mainnet"),
23
+ ".eth": ("ethereum-mainnet",),
24
+ }
25
+
26
+ _POA_NETWORK_PREFIXES: tuple[str, ...] = ("base",)
27
+
28
+
29
+ async def resolve_ens_to_address(name: str) -> str:
30
+ """Resolve an ENS domain to a checksum wallet address.
31
+
32
+ Args:
33
+ name: ENS name to resolve.
34
+
35
+ Returns:
36
+ The checksum wallet address associated with the ENS name.
37
+
38
+ Raises:
39
+ IntentKitAPIError: If the ENS name cannot be resolved to a wallet address.
40
+ """
41
+
42
+ normalized = name.strip().lower()
43
+ if not normalized:
44
+ raise IntentKitAPIError(404, "ENSNameNotFound", "ENS name is empty.")
45
+
46
+ redis_client = None
47
+ cache_key = f"{_CACHE_PREFIX}{normalized}"
48
+ try:
49
+ redis_client = get_redis()
50
+ except Exception: # Redis is optional; ignore if unavailable
51
+ redis_client = None
52
+
53
+ if redis_client is not None:
54
+ cached_address = await redis_client.get(cache_key)
55
+ if cached_address:
56
+ return cached_address
57
+
58
+ networks = _networks_for_name(normalized)
59
+ if not networks:
60
+ raise IntentKitAPIError(
61
+ 404,
62
+ "ENSNameNotFound",
63
+ "Unsupported ENS name suffix.",
64
+ )
65
+
66
+ for network in networks:
67
+ address = await _resolve_on_network(normalized, network)
68
+ if address:
69
+ if redis_client is not None:
70
+ try:
71
+ await redis_client.set(cache_key, address, ex=_CACHE_TTL_SECONDS)
72
+ except Exception as exc: # pragma: no cover - optional cache
73
+ logger.debug("Failed to cache ENS resolution: %s", exc)
74
+ return address
75
+
76
+ raise IntentKitAPIError(
77
+ 404,
78
+ "ENSNameNotFound",
79
+ f"ENS name {name} could not be resolved.",
80
+ )
81
+
82
+
83
+ def _networks_for_name(name: str) -> tuple[str, ...]:
84
+ for suffix, networks in _NETWORKS_BY_SUFFIX.items():
85
+ if name.endswith(suffix):
86
+ return networks
87
+ return tuple()
88
+
89
+
90
+ def _requires_poa_middleware(network: str) -> bool:
91
+ return network.startswith(_POA_NETWORK_PREFIXES)
92
+
93
+
94
+ def _build_ens_client(rpc_url: str, network: str) -> ENS:
95
+ web3_client = Web3(Web3.HTTPProvider(rpc_url))
96
+ if _requires_poa_middleware(network):
97
+ web3_client.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0)
98
+
99
+ return ENS.from_web3(web3_client)
100
+
101
+
102
+ async def _resolve_on_network(name: str, network: str) -> str | None:
103
+ chain_provider = getattr(config, "chain_provider", None)
104
+ if chain_provider is None:
105
+ logger.debug("No chain provider configured; cannot resolve ENS name.")
106
+ return None
107
+
108
+ try:
109
+ chain_config = chain_provider.get_chain_config(network)
110
+ except Exception as exc: # pragma: no cover - dependent on external config
111
+ logger.debug("Chain config for %s unavailable: %s", network, exc)
112
+ return None
113
+
114
+ rpc_url = chain_config.ens_url or chain_config.rpc_url
115
+ if not rpc_url:
116
+ logger.debug("No RPC/ENS URL configured for %s", network)
117
+ return None
118
+
119
+ def _resolve() -> str | None:
120
+ ens_client = _build_ens_client(rpc_url, network)
121
+ try:
122
+ resolved = ens_client.address(name)
123
+ except Exception as exc: # pragma: no cover - dependent on external provider
124
+ logger.debug("Error resolving %s on %s: %s", name, network, exc)
125
+ return None
126
+
127
+ if not resolved:
128
+ return None
129
+
130
+ try:
131
+ return Web3.to_checksum_address(resolved)
132
+ except ValueError:
133
+ return None
134
+
135
+ return await asyncio.to_thread(_resolve)
intentkit/utils/error.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Optional, Sequence
2
+ from collections.abc import Sequence
3
3
 
4
4
  from fastapi.exceptions import RequestValidationError
5
5
  from fastapi.utils import is_body_allowed_for_status_code
@@ -17,12 +17,15 @@ logger = logging.getLogger(__name__)
17
17
  class RateLimitExceeded(Exception):
18
18
  """Rate limit exceeded"""
19
19
 
20
- def __init__(self, message: Optional[str] = "Rate limit exceeded"):
20
+ def __init__(self, message: str | None = "Rate limit exceeded"):
21
21
  self.message = message
22
22
  super().__init__(self.message)
23
23
 
24
24
 
25
25
  class IntentKitAPIError(Exception):
26
+ """All 3 parameters: status_code, key and message is required.
27
+ The key is PascalCase string, to allow the frontend to test errors."""
28
+
26
29
  def __init__(self, status_code: int, key: str, message: str):
27
30
  self.key = key
28
31
  self.message = message
@@ -4,17 +4,17 @@ Logging configuration module
4
4
 
5
5
  import json
6
6
  import logging
7
- from typing import Callable, Optional
7
+ from collections.abc import Callable
8
+ from typing import override
8
9
 
9
10
 
10
11
  class JsonFormatter(logging.Formatter):
11
- def __init__(
12
- self, filter_func: Optional[Callable[[logging.LogRecord], bool]] = None
13
- ):
12
+ def __init__(self, filter_func: Callable[[logging.LogRecord], bool] | None = None):
14
13
  super().__init__()
15
14
  self.filter_func = filter_func
16
15
 
17
- def format(self, record):
16
+ @override
17
+ def format(self, record: logging.LogRecord) -> str:
18
18
  if self.filter_func and not self.filter_func(record):
19
19
  return ""
20
20
 
@@ -24,17 +24,15 @@ class JsonFormatter(logging.Formatter):
24
24
  "level": record.levelname,
25
25
  "message": record.getMessage(),
26
26
  }
27
- # Include any extra attributes
28
- if hasattr(record, "extra"):
29
- log_obj.update(record.extra)
30
- elif record.__dict__.get("extra"):
31
- log_obj.update(record.__dict__["extra"])
27
+ extra = record.__dict__.get("extra")
28
+ if isinstance(extra, dict):
29
+ log_obj.update(extra)
32
30
  if record.exc_info:
33
31
  log_obj["exc_info"] = self.formatException(record.exc_info)
34
32
  return json.dumps(log_obj)
35
33
 
36
34
 
37
- def setup_logging(env: str, debug: bool = False):
35
+ def setup_logging(env: str, debug: bool = False) -> None:
38
36
  """
39
37
  Setup global logging configuration.
40
38
 
@@ -0,0 +1,100 @@
1
+ """JSON Schema utilities for IntentKit.
2
+
3
+ This module provides utilities for working with JSON schemas, including
4
+ resolving $defs references and generating nested schemas.
5
+ """
6
+
7
+ import copy
8
+ from typing import Any
9
+
10
+
11
+ def resolve_schema_refs(schema: dict[str, Any]) -> dict[str, Any]:
12
+ """Recursively resolve $defs references in a JSON schema.
13
+
14
+ This function takes a JSON schema with $defs references and returns
15
+ a fully nested schema without any $ref pointers. This is useful for
16
+ creating schemas that can be easily consumed by external systems
17
+ that don't support JSON Schema references.
18
+
19
+ Args:
20
+ schema: The JSON schema dictionary that may contain $defs and $ref
21
+
22
+ Returns:
23
+ dict: A new schema with all $ref resolved to nested objects
24
+
25
+ Example:
26
+ >>> schema = {
27
+ ... "type": "object",
28
+ ... "properties": {
29
+ ... "user": {"$ref": "#/$defs/User"}
30
+ ... },
31
+ ... "$defs": {
32
+ ... "User": {
33
+ ... "type": "object",
34
+ ... "properties": {"name": {"type": "string"}}
35
+ ... }
36
+ ... }
37
+ ... }
38
+ >>> resolved = resolve_schema_refs(schema)
39
+ >>> # resolved will have the User definition inlined
40
+ """
41
+ # Deep copy to avoid modifying the original
42
+ resolved_schema = copy.deepcopy(schema)
43
+
44
+ # Extract $defs if they exist
45
+ defs = resolved_schema.pop("$defs", {})
46
+
47
+ def resolve_refs(obj: Any, defs_dict: dict[str, Any]) -> Any:
48
+ """Recursively resolve $ref in an object."""
49
+ if isinstance(obj, dict):
50
+ if "$ref" in obj:
51
+ ref_path = obj["$ref"]
52
+ if ref_path.startswith("#/$defs/"):
53
+ def_name = ref_path.replace("#/$defs/", "")
54
+ if def_name in defs_dict:
55
+ # Recursively resolve the referenced definition
56
+ resolved_def = resolve_refs(defs_dict[def_name], defs_dict)
57
+ return resolved_def
58
+ else:
59
+ # Keep the reference if definition not found
60
+ return obj
61
+ else:
62
+ # Keep non-$defs references as is
63
+ return obj
64
+ else:
65
+ # Recursively process all values in the dictionary
66
+ return {
67
+ key: resolve_refs(value, defs_dict) for key, value in obj.items()
68
+ }
69
+ elif isinstance(obj, list):
70
+ # Recursively process all items in the list
71
+ return [resolve_refs(item, defs_dict) for item in obj]
72
+ else:
73
+ # Return primitive values as is
74
+ return obj
75
+
76
+ # Resolve all references in the schema
77
+ return resolve_refs(resolved_schema, defs)
78
+
79
+
80
+ def create_array_schema(
81
+ item_schema: dict[str, Any], resolve_refs: bool = True
82
+ ) -> dict[str, Any]:
83
+ """Create an array schema with the given item schema.
84
+
85
+ Args:
86
+ item_schema: The schema for array items
87
+ resolve_refs: Whether to resolve $defs references in the item schema
88
+
89
+ Returns:
90
+ dict: Array schema with resolved item schema
91
+ """
92
+ if resolve_refs:
93
+ resolved_item_schema = resolve_schema_refs(item_schema)
94
+ else:
95
+ resolved_item_schema = item_schema
96
+
97
+ return {
98
+ "type": "array",
99
+ "items": resolved_item_schema,
100
+ }
@@ -3,7 +3,7 @@ Slack notification module for sending messages to Slack channels.
3
3
  """
4
4
 
5
5
  import logging
6
- from typing import Optional
6
+ from typing import Any, Sequence
7
7
 
8
8
  from slack_sdk import WebClient
9
9
  from slack_sdk.errors import SlackApiError
@@ -11,9 +11,9 @@ from slack_sdk.errors import SlackApiError
11
11
  logger = logging.getLogger(__name__)
12
12
 
13
13
  # Global variables for Slack configuration
14
- _slack_token: Optional[str] = None
15
- _slack_channel: Optional[str] = None
16
- _slack_client: Optional[WebClient] = None
14
+ _slack_token: str | None = None
15
+ _slack_channel: str | None = None
16
+ _slack_client: WebClient | None = None
17
17
 
18
18
 
19
19
  def init_slack(token: str, channel: str) -> None:
@@ -36,10 +36,10 @@ def init_slack(token: str, channel: str) -> None:
36
36
 
37
37
  def send_slack_message(
38
38
  message: str,
39
- blocks: Optional[list] = None,
40
- attachments: Optional[list] = None,
41
- thread_ts: Optional[str] = None,
42
- channel: Optional[str] = None,
39
+ blocks: Sequence[dict[str, Any]] | None = None,
40
+ attachments: Sequence[dict[str, Any]] | None = None,
41
+ thread_ts: str | None = None,
42
+ channel: str | None = None,
43
43
  ):
44
44
  """
45
45
  Send a message to a Slack channel.
intentkit/utils/tx.py CHANGED
@@ -1,13 +1,17 @@
1
+ from typing import Any, Dict, Tuple
2
+
1
3
  from pydantic import BaseModel, Field
2
4
  from web3 import Web3
3
5
 
4
6
 
5
7
  class EvmContractWrapper:
6
- def __init__(self, rpc_url: str, abi: list[dict], tx_data: str):
8
+ def __init__(
9
+ self, rpc_url: str, abi: list[dict[str, Any]], tx_data: Dict[str, Any]
10
+ ):
7
11
  w3 = Web3(Web3.HTTPProvider(rpc_url))
8
12
  contract = w3.eth.contract(abi=abi)
9
13
 
10
- self.evm_tx = EvmTx(**tx_data)
14
+ self.evm_tx = EvmTx.model_validate(tx_data)
11
15
  self.fn, self.fn_args = contract.decode_function_input(self.evm_tx.data)
12
16
 
13
17
  for i, arg in self.fn_args.items():
@@ -19,19 +23,23 @@ class EvmContractWrapper:
19
23
  ] # Convert list of bytes to list of hex strings
20
24
 
21
25
  @property
22
- def fn_and_args(self):
26
+ def fn_and_args(self) -> Tuple[Any, Dict[str, Any]]:
23
27
  return self.fn, self.fn_args
24
28
 
25
29
  @property
26
- def dst_addr(self):
30
+ def dst_addr(self) -> str | None:
27
31
  return self.evm_tx.to
28
32
 
29
33
 
30
34
  class EvmTx(BaseModel):
31
- data: str = Field(None, description="Data of the transaction.")
32
- to: str = Field(None, description="Address of the receiver of the transaction.")
33
- from_: str = Field(None, description="Address of the sender of the transaction.")
34
- value: str = Field(None, description="Amount of token to send.")
35
+ data: str | None = Field(None, description="Data of the transaction.")
36
+ to: str | None = Field(
37
+ None, description="Address of the receiver of the transaction."
38
+ )
39
+ from_: str | None = Field(
40
+ None, description="Address of the sender of the transaction."
41
+ )
42
+ value: str | None = Field(None, description="Amount of token to send.")
35
43
  gas: int | None = Field(None, description="Gas amount.")
36
44
  gasPrice: int | None = Field(None, description="Gas Price.")
37
45
  nonce: int | None = Field(None, description="Nonce of transaction.")