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,121 +0,0 @@
1
- from typing import Optional, Type, Union
2
-
3
- from pydantic import BaseModel, Field
4
-
5
- from intentkit.abstracts.skill import SkillStoreABC
6
- from intentkit.clients import get_cdp_client
7
- from intentkit.skills.cdp.base import CDPBaseTool
8
-
9
-
10
- class SwapInput(BaseModel):
11
- """Input for Swap tool."""
12
-
13
- from_token: str = Field(
14
- description="The contract address of the token to swap from (e.g., '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' for USDC on Base)"
15
- )
16
- to_token: str = Field(
17
- description="The contract address of the token to swap to (e.g., '0x4200000000000000000000000000000000000006' for WETH on Base)"
18
- )
19
- from_amount: Union[str, int] = Field(
20
- description="The amount to swap from in smallest unit (e.g., 1000000 for 1 USDC with 6 decimals)"
21
- )
22
- slippage_bps: Optional[int] = Field(
23
- default=100,
24
- description="Maximum slippage in basis points (100 = 1%). Defaults to 100 (1%)",
25
- )
26
-
27
-
28
- class Swap(CDPBaseTool):
29
- """Tool for swapping tokens using CDP wallet.
30
-
31
- This tool uses the CDP API to execute token swaps on supported networks.
32
- It wraps the swap functionality from the EVM account.
33
-
34
- Attributes:
35
- name: The name of the tool.
36
- description: A description of what the tool does.
37
- args_schema: The schema for the tool's input arguments.
38
- """
39
-
40
- agent_id: str
41
- skill_store: SkillStoreABC
42
-
43
- name: str = "cdp_swap"
44
- description: str = (
45
- "This tool will swap tokens using the CDP wallet. "
46
- "It supports swapping between any ERC-20 tokens on supported networks (Base and Ethereum). "
47
- "You need to provide the contract addresses of both tokens and the amount to swap. "
48
- "The amount should be in the smallest unit of the token (e.g., wei for ETH, or atomic units for ERC-20 tokens). "
49
- "Common token addresses on Base: USDC=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, WETH=0x4200000000000000000000000000000000000006. "
50
- "The tool will automatically handle gas estimation and transaction submission."
51
- )
52
- args_schema: Type[BaseModel] = SwapInput
53
-
54
- async def _arun(
55
- self,
56
- from_token: str,
57
- to_token: str,
58
- from_amount: Union[str, int],
59
- slippage_bps: Optional[int] = 100,
60
- ) -> str:
61
- """Async implementation of the tool to swap tokens.
62
-
63
- Args:
64
- from_token (str): The contract address of the token to swap from.
65
- to_token (str): The contract address of the token to swap to.
66
- from_amount (Union[str, int]): The amount to swap from in smallest unit.
67
- slippage_bps (Optional[int]): Maximum slippage in basis points. Defaults to 100 (1%).
68
-
69
- Returns:
70
- str: A message containing the swap result or error message.
71
- """
72
- try:
73
- # Get CDP client and network information
74
- cdp_client = await get_cdp_client(self.agent_id, self.skill_store)
75
- provider = await cdp_client.get_wallet_provider()
76
- provider_config = await cdp_client.get_provider_config()
77
- network_id = provider_config.network_id
78
-
79
- # Map network_id to the format expected by the swap API
80
- network_mapping = {
81
- "base-mainnet": "base",
82
- "ethereum-mainnet": "ethereum",
83
- }
84
- api_network = network_mapping.get(network_id, network_id)
85
-
86
- # Validate network is supported
87
- supported_networks = ["base", "ethereum"]
88
- if api_network not in supported_networks:
89
- return f"Error: Network {api_network} is not supported for swaps. Supported networks: {', '.join(supported_networks)}"
90
-
91
- # Get the EVM account
92
- client = provider.get_client()
93
- async with client:
94
- account = await client.evm.get_account(provider.get_address())
95
-
96
- # Import AccountSwapOptions here to avoid circular imports
97
- from cdp.actions.evm.swap.types import AccountSwapOptions
98
-
99
- # Create swap options
100
- swap_options = AccountSwapOptions(
101
- network=api_network,
102
- from_token=from_token,
103
- to_token=to_token,
104
- from_amount=str(from_amount),
105
- slippage_bps=slippage_bps,
106
- )
107
-
108
- # Execute the swap
109
- result = await account.swap(swap_options)
110
-
111
- return (
112
- f"Swap executed successfully!\n"
113
- f"Transaction hash: {result.transaction_hash}\n"
114
- f"Swapped from {from_token} to {to_token}\n"
115
- f"Amount: {from_amount} (smallest units)\n"
116
- f"Network: {api_network}\n"
117
- f"Slippage tolerance: {slippage_bps} basis points ({slippage_bps / 100 if slippage_bps else 0}%)"
118
- )
119
-
120
- except Exception as e:
121
- return f"Error executing swap: {e!s}"
File without changes
@@ -1,511 +0,0 @@
1
- """Tests for the Moralis Wallet Portfolio skills."""
2
-
3
- import asyncio
4
- import json
5
- import unittest
6
- from unittest.mock import AsyncMock, MagicMock, patch
7
-
8
- from intentkit.skills.moralis import (
9
- FetchChainPortfolio,
10
- FetchSolanaPortfolio,
11
- FetchWalletPortfolio,
12
- get_skills,
13
- )
14
- from intentkit.skills.moralis.api import (
15
- fetch_moralis_data,
16
- fetch_wallet_balances,
17
- get_solana_portfolio,
18
- )
19
- from intentkit.skills.moralis.base import WalletBaseTool
20
-
21
-
22
- class DummyResponse:
23
- """Mock HTTP response for testing."""
24
-
25
- def __init__(self, status_code, json_data):
26
- self.status_code = status_code
27
- self._json_data = json_data
28
- self.text = json.dumps(json_data) if json_data else ""
29
-
30
- def json(self):
31
- return self._json_data
32
-
33
- async def raise_for_status(self):
34
- if self.status_code >= 400:
35
- raise Exception(f"HTTP Error: {self.status_code}")
36
-
37
-
38
- class TestWalletBaseClass(unittest.TestCase):
39
- """Test the base wallet portfolio tool class."""
40
-
41
- def setUp(self):
42
- self.loop = asyncio.new_event_loop()
43
- asyncio.set_event_loop(self.loop)
44
-
45
- self.mock_skill_store = MagicMock()
46
-
47
- def tearDown(self):
48
- self.loop.close()
49
-
50
- def test_base_class_init(self):
51
- """Test base class initialization."""
52
-
53
- # Create a concrete subclass for testing
54
- class TestTool(WalletBaseTool):
55
- async def _arun(self, *args, **kwargs):
56
- return "test"
57
-
58
- tool = TestTool(
59
- name="test_tool",
60
- description="Test tool",
61
- args_schema=MagicMock(),
62
- api_key="test_key",
63
- skill_store=self.mock_skill_store,
64
- agent_id="test_agent",
65
- )
66
-
67
- self.assertEqual(tool.api_key, "test_key")
68
- self.assertEqual(tool.agent_id, "test_agent")
69
- self.assertEqual(tool.skill_store, self.mock_skill_store)
70
- self.assertEqual(tool.category, "moralis")
71
-
72
- def test_get_chain_name(self):
73
- """Test chain name conversion."""
74
-
75
- class TestTool(WalletBaseTool):
76
- async def _arun(self, *args, **kwargs):
77
- return "test"
78
-
79
- tool = TestTool(
80
- name="test_tool",
81
- description="Test tool",
82
- args_schema=MagicMock(),
83
- api_key="test_key",
84
- skill_store=self.mock_skill_store,
85
- agent_id="test_agent",
86
- )
87
-
88
- # Test with known chain IDs
89
- self.assertEqual(tool._get_chain_name(1), "eth")
90
- self.assertEqual(tool._get_chain_name(56), "bsc")
91
- self.assertEqual(tool._get_chain_name(137), "polygon")
92
-
93
- # Test with unknown chain ID
94
- self.assertEqual(tool._get_chain_name(999999), "eth")
95
-
96
-
97
- class TestAPIFunctions(unittest.IsolatedAsyncioTestCase):
98
- """Test the API interaction functions."""
99
-
100
- async def test_fetch_moralis_data(self):
101
- """Test the base Moralis API function."""
102
- with patch("httpx.AsyncClient") as MockClient:
103
- client_instance = AsyncMock()
104
- client_instance.get.return_value = DummyResponse(
105
- 200, {"success": True, "data": "test_data"}
106
- )
107
- MockClient.return_value.__aenter__.return_value = client_instance
108
-
109
- result = await fetch_moralis_data(
110
- "test_api_key", "test_endpoint", "0xAddress", 1
111
- )
112
-
113
- self.assertEqual(result, {"success": True, "data": "test_data"})
114
-
115
- # Test error handling
116
- client_instance.get.return_value = DummyResponse(404, None)
117
- client_instance.get.return_value.raise_for_status = AsyncMock(
118
- side_effect=Exception("HTTP error 404")
119
- )
120
-
121
- result = await fetch_moralis_data(
122
- "test_api_key", "test_endpoint", "0xAddress", 1
123
- )
124
- self.assertIn("error", result)
125
-
126
- async def test_fetch_wallet_balances(self):
127
- """Test fetching wallet balances."""
128
- with patch("skills.moralis.api.fetch_moralis_data") as mock_fetch:
129
- mock_fetch.return_value = {
130
- "result": [
131
- {
132
- "token_address": "0x123",
133
- "symbol": "TEST",
134
- "balance": "1000000",
135
- "usd_value": 100,
136
- }
137
- ]
138
- }
139
-
140
- result = await fetch_wallet_balances("test_api_key", "0xAddress", 1)
141
-
142
- self.assertEqual(result["result"][0]["symbol"], "TEST")
143
- mock_fetch.assert_called_once_with(
144
- "test_api_key", "wallets/{address}/tokens", "0xAddress", 1, None
145
- )
146
-
147
- async def test_get_solana_portfolio(self):
148
- """Test getting Solana portfolio."""
149
- with patch("skills.moralis.api.fetch_solana_api") as mock_fetch:
150
- mock_fetch.return_value = {
151
- "nativeBalance": {"solana": 1.5, "lamports": 1500000000},
152
- "tokens": [
153
- {
154
- "symbol": "TEST",
155
- "name": "Test Token",
156
- "mint": "TokenMintAddress",
157
- "associatedTokenAddress": "AssocTokenAddress",
158
- "amount": 10,
159
- "decimals": 9,
160
- "amountRaw": "10000000000",
161
- }
162
- ],
163
- }
164
-
165
- result = await get_solana_portfolio("test_api_key", "SolAddress", "mainnet")
166
-
167
- mock_fetch.assert_called_once_with(
168
- "test_api_key", "/account/mainnet/SolAddress/portfolio"
169
- )
170
- self.assertEqual(result["nativeBalance"]["solana"], 1.5)
171
- self.assertEqual(len(result["tokens"]), 1)
172
- self.assertEqual(result["tokens"][0]["symbol"], "TEST")
173
-
174
-
175
- class TestFetchWalletPortfolio(unittest.IsolatedAsyncioTestCase):
176
- """Test the FetchWalletPortfolio skill."""
177
-
178
- async def test_wallet_portfolio_success(self):
179
- """Test successful wallet portfolio fetch."""
180
- mock_skill_store = MagicMock()
181
-
182
- with (
183
- patch(
184
- "skills.moralis.moralis_fetch_wallet_portfolio.fetch_wallet_balances"
185
- ) as mock_balances,
186
- patch(
187
- "skills.moralis.moralis_fetch_wallet_portfolio.fetch_net_worth"
188
- ) as mock_net_worth,
189
- ):
190
- # Mock successful responses
191
- mock_balances.return_value = {
192
- "result": [
193
- {
194
- "token_address": "0x123",
195
- "symbol": "TEST",
196
- "name": "Test Token",
197
- "balance": "1000000000000000000",
198
- "balance_formatted": "1.0",
199
- "usd_value": 100,
200
- }
201
- ]
202
- }
203
- mock_net_worth.return_value = {"result": {"total_networth_usd": 1000}}
204
-
205
- tool = FetchWalletPortfolio(
206
- name="fetch_wallet_portfolio",
207
- description="Test description",
208
- args_schema=MagicMock(),
209
- api_key="test_key",
210
- skill_store=mock_skill_store,
211
- agent_id="test_agent",
212
- )
213
-
214
- result = await tool._arun(address="0xAddress")
215
-
216
- self.assertEqual(result.address, "0xAddress")
217
- self.assertEqual(result.total_net_worth, 1000)
218
- self.assertEqual(len(result.tokens), 1)
219
- self.assertEqual(result.tokens[0].symbol, "TEST")
220
-
221
- async def test_wallet_portfolio_with_solana(self):
222
- """Test wallet portfolio with Solana support."""
223
- mock_skill_store = MagicMock()
224
-
225
- with (
226
- patch(
227
- "skills.moralis.moralis_fetch_wallet_portfolio.fetch_wallet_balances"
228
- ) as mock_evm_balances,
229
- patch(
230
- "skills.moralis.moralis_fetch_wallet_portfolio.fetch_net_worth"
231
- ) as mock_net_worth,
232
- patch(
233
- "skills.moralis.moralis_fetch_wallet_portfolio.get_solana_portfolio"
234
- ) as mock_sol_portfolio,
235
- patch(
236
- "skills.moralis.moralis_fetch_wallet_portfolio.get_token_price"
237
- ) as mock_token_price,
238
- ):
239
- # Mock EVM responses
240
- mock_evm_balances.return_value = {
241
- "result": [
242
- {
243
- "token_address": "0x123",
244
- "symbol": "ETH",
245
- "name": "Ethereum",
246
- "balance": "1000000000000000000",
247
- "balance_formatted": "1.0",
248
- "usd_value": 2000,
249
- }
250
- ]
251
- }
252
- mock_net_worth.return_value = {"result": {"total_networth_usd": 3000}}
253
-
254
- # Mock Solana responses
255
- mock_sol_portfolio.return_value = {
256
- "nativeBalance": {"solana": 2.0, "lamports": 2000000000},
257
- "tokens": [
258
- {
259
- "symbol": "SOL",
260
- "name": "Solana",
261
- "mint": "So11111111111111111111111111111111111111112",
262
- "associatedTokenAddress": "AssocTokenAddress",
263
- "amount": 2.0,
264
- "decimals": 9,
265
- "amountRaw": "2000000000",
266
- }
267
- ],
268
- }
269
-
270
- mock_token_price.return_value = {"usdPrice": 500}
271
-
272
- tool = FetchWalletPortfolio(
273
- name="fetch_wallet_portfolio",
274
- description="Test description",
275
- args_schema=MagicMock(),
276
- api_key="test_key",
277
- skill_store=mock_skill_store,
278
- agent_id="test_agent",
279
- )
280
-
281
- result = await tool._arun(address="0xAddress", include_solana=True)
282
-
283
- self.assertEqual(result.address, "0xAddress")
284
- self.assertEqual(
285
- result.total_net_worth, 3000
286
- ) # Using the net worth from mock
287
- self.assertIn("eth", result.chains)
288
- self.assertIn("solana", result.chains)
289
-
290
- # Check that we have both EVM and Solana tokens
291
- token_symbols = [token.symbol for token in result.tokens]
292
- self.assertIn("ETH", token_symbols)
293
- self.assertIn("SOL", token_symbols)
294
-
295
-
296
- class TestFetchSolanaPortfolio(unittest.IsolatedAsyncioTestCase):
297
- """Test the FetchSolanaPortfolio skill."""
298
-
299
- async def test_solana_portfolio_success(self):
300
- """Test successful Solana portfolio fetch."""
301
- mock_skill_store = MagicMock()
302
-
303
- with (
304
- patch(
305
- "skills.moralis.moralis_fetch_solana_portfolio.get_solana_portfolio"
306
- ) as mock_portfolio,
307
- patch(
308
- "skills.moralis.moralis_fetch_solana_portfolio.get_solana_nfts"
309
- ) as mock_nfts,
310
- patch(
311
- "skills.moralis.moralis_fetch_solana_portfolio.get_token_price"
312
- ) as mock_token_price,
313
- ):
314
- # Mock successful responses
315
- mock_portfolio.return_value = {
316
- "nativeBalance": {"solana": 1.5, "lamports": 1500000000},
317
- "tokens": [
318
- {
319
- "symbol": "TEST",
320
- "name": "Test Token",
321
- "mint": "TokenMintAddress",
322
- "associatedTokenAddress": "AssocTokenAddress",
323
- "amount": 10,
324
- "decimals": 9,
325
- "amountRaw": "10000000000",
326
- }
327
- ],
328
- }
329
-
330
- mock_nfts.return_value = [
331
- {
332
- "mint": "NFTMintAddress",
333
- "name": "Test NFT",
334
- "symbol": "TNFT",
335
- "associatedTokenAddress": "AssocTokenAddress",
336
- "metadata": {"name": "Test NFT", "image": "image.png"},
337
- }
338
- ]
339
-
340
- mock_token_price.return_value = {"usdPrice": 25}
341
-
342
- tool = FetchSolanaPortfolio(
343
- name="fetch_solana_portfolio",
344
- description="Test description",
345
- args_schema=MagicMock(),
346
- api_key="test_key",
347
- skill_store=mock_skill_store,
348
- agent_id="test_agent",
349
- )
350
-
351
- result = await tool._arun(address="SolanaAddress", include_nfts=True)
352
-
353
- self.assertEqual(result.address, "SolanaAddress")
354
- self.assertEqual(result.sol_balance, 1.5)
355
- self.assertEqual(len(result.tokens), 1)
356
- self.assertEqual(result.tokens[0].token_info.symbol, "TEST")
357
- self.assertEqual(len(result.nfts), 1)
358
- self.assertEqual(result.nfts[0].name, "Test NFT")
359
- self.assertEqual(result.sol_price_usd, 25)
360
- self.assertEqual(result.sol_value_usd, 37.5) # 1.5 SOL * $25
361
-
362
-
363
- class TestFetchChainPortfolio(unittest.IsolatedAsyncioTestCase):
364
- """Test the FetchChainPortfolio skill."""
365
-
366
- async def test_chain_portfolio_success(self):
367
- """Test successful chain portfolio fetch."""
368
- mock_skill_store = MagicMock()
369
-
370
- with patch(
371
- "skills.moralis.moralis_fetch_chain_portfolio.fetch_wallet_balances"
372
- ) as mock_balances:
373
- # Mock successful responses
374
- mock_balances.return_value = {
375
- "result": [
376
- {
377
- "token_address": "0x123",
378
- "symbol": "ETH",
379
- "name": "Ethereum",
380
- "logo": "logo.png",
381
- "decimals": 18,
382
- "balance": "1000000000000000000",
383
- "balance_formatted": "1.0",
384
- "usd_value": 2000,
385
- "native_token": True,
386
- },
387
- {
388
- "token_address": "0x456",
389
- "symbol": "TOKEN",
390
- "name": "Test Token",
391
- "logo": "logo2.png",
392
- "decimals": 18,
393
- "balance": "2000000000000000000",
394
- "balance_formatted": "2.0",
395
- "usd_value": 200,
396
- "native_token": False,
397
- },
398
- ]
399
- }
400
-
401
- tool = FetchChainPortfolio(
402
- name="fetch_chain_portfolio",
403
- description="Test description",
404
- args_schema=MagicMock(),
405
- api_key="test_key",
406
- skill_store=mock_skill_store,
407
- agent_id="test_agent",
408
- )
409
-
410
- result = await tool._arun(address="0xAddress", chain_id=1)
411
-
412
- self.assertEqual(result.address, "0xAddress")
413
- self.assertEqual(result.chain_id, 1)
414
- self.assertEqual(result.chain_name, "eth")
415
- self.assertEqual(result.total_usd_value, 2200) # 2000 + 200
416
- self.assertEqual(len(result.tokens), 1) # Regular tokens, not native
417
- self.assertIsNotNone(result.native_token)
418
- self.assertEqual(result.native_token.symbol, "ETH")
419
- self.assertEqual(result.tokens[0].symbol, "TOKEN")
420
-
421
-
422
- class TestSkillInitialization(unittest.TestCase):
423
- """Test skill initialization and configuration."""
424
-
425
- def setUp(self):
426
- self.mock_skill_store = MagicMock()
427
-
428
- def test_get_skills(self):
429
- """Test getting multiple skills from config."""
430
- config = {
431
- "api_key": "test_api_key",
432
- "states": {
433
- "fetch_wallet_portfolio": "public",
434
- "fetch_chain_portfolio": "public",
435
- "fetch_nft_portfolio": "private",
436
- "fetch_transaction_history": "private",
437
- "fetch_solana_portfolio": "public",
438
- },
439
- "supported_chains": {"evm": True, "solana": True},
440
- }
441
-
442
- # Test with mock implementation
443
- with patch("skills.moralis.base.WalletBaseTool") as mock_tool:
444
- mock_tool.return_value = MagicMock()
445
-
446
- # This is just a test structure - actual implementation would create the skills
447
- skills = get_skills(
448
- config,
449
- is_private=False, # Only get public skills
450
- skill_store=self.mock_skill_store,
451
- agent_id="test_agent",
452
- )
453
-
454
- # In a real implementation, we'd test that the correct skills were returned
455
- # For now, we just verify the function exists
456
- self.assertIsNotNone(skills)
457
-
458
-
459
- class TestIntegration(unittest.TestCase):
460
- """Integration tests for wallet skills."""
461
-
462
- def test_wallet_skill_configuration(self):
463
- """Test wallet skill configuration in agent config."""
464
- # Example agent configuration
465
- agent_config = {
466
- "id": "crypto-agent",
467
- "skills": {
468
- "moralis": {
469
- "api_key": "test_api_key",
470
- "states": {
471
- "fetch_wallet_portfolio": "public",
472
- "fetch_chain_portfolio": "public",
473
- "fetch_nft_portfolio": "private",
474
- "fetch_transaction_history": "private",
475
- "fetch_solana_portfolio": "public",
476
- },
477
- "supported_chains": {"evm": True, "solana": True},
478
- }
479
- },
480
- }
481
-
482
- # Verify the configuration structure is valid
483
- moralis_config = agent_config["skills"]["moralis"]
484
- self.assertIn("api_key", moralis_config)
485
- self.assertIn("states", moralis_config)
486
- self.assertIn("supported_chains", moralis_config)
487
-
488
- # Check that all required skills are configured
489
- states = moralis_config["states"]
490
- required_skills = [
491
- "fetch_wallet_portfolio",
492
- "fetch_chain_portfolio",
493
- "fetch_nft_portfolio",
494
- "fetch_transaction_history",
495
- "fetch_solana_portfolio",
496
- ]
497
-
498
- for skill in required_skills:
499
- self.assertIn(skill, states)
500
- self.assertIn(states[skill], ["public", "private", "disabled"])
501
-
502
- # Check chain configuration
503
- chains = moralis_config["supported_chains"]
504
- self.assertIn("evm", chains)
505
- self.assertIn("solana", chains)
506
- self.assertTrue(isinstance(chains["evm"], bool))
507
- self.assertTrue(isinstance(chains["solana"], bool))
508
-
509
-
510
- if __name__ == "__main__":
511
- unittest.main()