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
@@ -1,121 +1,115 @@
1
- import logging
2
- from typing import List, Literal, Optional, TypedDict
3
-
4
- from intentkit.abstracts.skill import SkillStoreABC
5
- from intentkit.skills.base import SkillConfig, SkillState
6
- from intentkit.skills.carv.base import CarvBaseTool
7
- from intentkit.skills.carv.fetch_news import FetchNewsTool
8
- from intentkit.skills.carv.onchain_query import OnchainQueryTool
9
- from intentkit.skills.carv.token_info_and_price import TokenInfoAndPriceTool
10
-
11
- logger = logging.getLogger(__name__)
12
-
13
-
14
- _cache: dict[str, CarvBaseTool] = {}
15
-
16
- _SKILL_NAME_TO_CLASS_MAP: dict[str, type[CarvBaseTool]] = {
17
- "onchain_query": OnchainQueryTool,
18
- "token_info_and_price": TokenInfoAndPriceTool,
19
- "fetch_news": FetchNewsTool,
20
- }
21
-
22
-
23
- class SkillStates(TypedDict):
24
- onchain_query: SkillState
25
- token_info_and_price: SkillState
26
- fetch_news: SkillState
27
-
28
-
29
- class Config(SkillConfig):
30
- enabled: bool
31
- states: SkillStates # type: ignore
32
- api_key_provider: Optional[Literal["agent_owner", "platform"]]
33
-
34
- # conditionally required
35
- api_key: Optional[str]
36
-
37
- # optional
38
- rate_limit_number: Optional[int]
39
- rate_limit_minutes: Optional[int]
40
-
41
-
42
- async def get_skills(
43
- config: "Config",
44
- is_private: bool,
45
- store: SkillStoreABC,
46
- **_,
47
- ) -> list[CarvBaseTool]:
48
- """
49
- Factory function to create and return CARV skill tools based on the provided configuration.
50
-
51
- Args:
52
- config: The configuration object for the CARV skill.
53
- is_private: A boolean indicating whether the request is from a private context.
54
- store: An instance of `SkillStoreABC`.
55
-
56
- Returns:
57
- A list of `CarvBaseTool` instances.
58
- """
59
- # Check if the entire category is disabled first
60
- if not config.get("enabled", False):
61
- return []
62
-
63
- available_skills: List[CarvBaseTool] = []
64
- skill_states = config.get("states", {})
65
-
66
- # Iterate through all known skills defined in the map
67
- for skill_name in _SKILL_NAME_TO_CLASS_MAP:
68
- state = skill_states.get(
69
- skill_name, "disabled"
70
- ) # Default to disabled if not in config
71
-
72
- if state == "disabled":
73
- continue
74
- elif state == "public" or (state == "private" and is_private):
75
- # If enabled, get the skill instance using the factory function
76
- skill_instance = get_carv_skill(skill_name, store)
77
- if skill_instance:
78
- available_skills.append(skill_instance)
79
- else:
80
- logger.warning(f"Could not instantiate known skill: {skill_name}")
81
-
82
- return available_skills
83
-
84
-
85
- def get_carv_skill(
86
- name: str,
87
- store: SkillStoreABC,
88
- ) -> Optional[CarvBaseTool]:
89
- """
90
- Factory function to retrieve a cached CARV skill instance by name.
91
-
92
- Args:
93
- name: The name of the CARV skill to retrieve.
94
- store: An instance of `SkillStoreABC`.
95
-
96
- Returns:
97
- The requested `CarvBaseTool` instance if found and enabled, otherwise None.
98
- """
99
-
100
- # Return from cache immediately if already exists
101
- if name in _cache:
102
- return _cache[name]
103
-
104
- # Get the class from the map
105
- skill_class = _SKILL_NAME_TO_CLASS_MAP.get(name)
106
-
107
- if skill_class:
108
- try:
109
- # Instantiate the skill and add to cache
110
- instance = skill_class(skill_store=store) # type: ignore
111
- _cache[name] = instance
112
- return instance
113
- except Exception as e:
114
- logger.error(
115
- f"Failed to instantiate Carv skill '{name}': {e}", exc_info=True
116
- )
117
- return None # Failed to instantiate
118
- else:
119
- # This handles cases where a name might be in config but not in our map
120
- logger.warning(f"Attempted to get unknown Carv skill: {name}")
121
- return None
1
+ import logging
2
+ from typing import Literal, TypedDict
3
+
4
+ from intentkit.skills.base import SkillConfig, SkillState
5
+ from intentkit.skills.carv.base import CarvBaseTool
6
+ from intentkit.skills.carv.fetch_news import FetchNewsTool
7
+ from intentkit.skills.carv.onchain_query import OnchainQueryTool
8
+ from intentkit.skills.carv.token_info_and_price import TokenInfoAndPriceTool
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ _cache: dict[str, CarvBaseTool] = {}
13
+
14
+ _SKILL_NAME_TO_CLASS_MAP: dict[str, type[CarvBaseTool]] = {
15
+ "onchain_query": OnchainQueryTool,
16
+ "token_info_and_price": TokenInfoAndPriceTool,
17
+ "fetch_news": FetchNewsTool,
18
+ }
19
+
20
+
21
+ class SkillStates(TypedDict):
22
+ onchain_query: SkillState
23
+ token_info_and_price: SkillState
24
+ fetch_news: SkillState
25
+
26
+
27
+ class Config(SkillConfig):
28
+ enabled: bool
29
+ states: SkillStates # type: ignore
30
+ api_key_provider: Literal["agent_owner", "platform"] | None
31
+
32
+ # conditionally required
33
+ api_key: str | None
34
+
35
+ # optional
36
+ rate_limit_number: int | None
37
+ rate_limit_minutes: int | None
38
+
39
+
40
+ async def get_skills(
41
+ config: "Config",
42
+ is_private: bool,
43
+ **_,
44
+ ) -> list[CarvBaseTool]:
45
+ """
46
+ Factory function to create and return CARV skill tools based on the provided configuration.
47
+
48
+ Args:
49
+ config: The configuration object for the CARV skill.
50
+ is_private: A boolean indicating whether the request is from a private context.
51
+
52
+ Returns:
53
+ A list of `CarvBaseTool` instances.
54
+ """
55
+ # Check if the entire category is disabled first
56
+ if not config.get("enabled", False):
57
+ return []
58
+
59
+ available_skills: list[CarvBaseTool] = []
60
+ skill_states = config.get("states", {})
61
+
62
+ # Iterate through all known skills defined in the map
63
+ for skill_name in _SKILL_NAME_TO_CLASS_MAP:
64
+ state = skill_states.get(
65
+ skill_name, "disabled"
66
+ ) # Default to disabled if not in config
67
+
68
+ if state == "disabled":
69
+ continue
70
+ elif state == "public" or (state == "private" and is_private):
71
+ # If enabled, get the skill instance using the factory function
72
+ skill_instance = get_carv_skill(skill_name)
73
+ if skill_instance:
74
+ available_skills.append(skill_instance)
75
+ else:
76
+ logger.warning(f"Could not instantiate known skill: {skill_name}")
77
+
78
+ return available_skills
79
+
80
+
81
+ def get_carv_skill(
82
+ name: str,
83
+ ) -> CarvBaseTool | None:
84
+ """
85
+ Factory function to retrieve a cached CARV skill instance by name.
86
+
87
+ Args:
88
+ name: The name of the CARV skill to retrieve.
89
+
90
+ Returns:
91
+ The requested `CarvBaseTool` instance if found and enabled, otherwise None.
92
+ """
93
+
94
+ # Return from cache immediately if already exists
95
+ if name in _cache:
96
+ return _cache[name]
97
+
98
+ # Get the class from the map
99
+ skill_class = _SKILL_NAME_TO_CLASS_MAP.get(name)
100
+
101
+ if skill_class:
102
+ try:
103
+ # Instantiate the skill and add to cache
104
+ instance = skill_class() # type: ignore
105
+ _cache[name] = instance
106
+ return instance
107
+ except Exception as e:
108
+ logger.error(
109
+ f"Failed to instantiate Carv skill '{name}': {e}", exc_info=True
110
+ )
111
+ return None # Failed to instantiate
112
+ else:
113
+ # This handles cases where a name might be in config but not in our map
114
+ logger.warning(f"Attempted to get unknown Carv skill: {name}")
115
+ return None
@@ -1,185 +1,184 @@
1
- import logging
2
- from typing import Any, Dict, Optional, Tuple, Type
3
-
4
- import httpx # Ensure httpx is installed: pip install httpx
5
- from langchain.tools.base import ToolException
6
- from pydantic import BaseModel, Field
7
-
8
- from intentkit.abstracts.skill import SkillStoreABC
9
- from intentkit.skills.base import IntentKitSkill
10
-
11
- logger = logging.getLogger(__name__)
12
-
13
- CARV_API_BASE_URL = "https://interface.carv.io"
14
-
15
-
16
- class CarvBaseTool(IntentKitSkill):
17
- """Base class for CARV API tools."""
18
-
19
- name: str = Field(description="Tool name") # type: ignore
20
- description: str = Field(description="Tool description")
21
- args_schema: Type[BaseModel] # type: ignore
22
- skill_store: SkillStoreABC = Field(description="Skill store for data persistence")
23
-
24
- @property
25
- def category(self) -> str:
26
- return "carv"
27
-
28
- def get_api_key(self) -> str:
29
- """
30
- Retrieves the CARV API key based on the api_key_provider setting.
31
-
32
- Returns:
33
- The API key if found.
34
-
35
- Raises:
36
- ToolException: If the API key is not found or provider is invalid.
37
- """
38
- try:
39
- context = self.get_context()
40
- skill_config = context.agent.skill_config(self.category)
41
- api_key_provider = skill_config.get("api_key_provider")
42
- if api_key_provider == "agent_owner":
43
- agent_api_key: Optional[str] = skill_config.get("api_key")
44
- if agent_api_key:
45
- logger.debug(
46
- f"Using agent-specific CARV API key for skill {self.name} in category {self.category}"
47
- )
48
- return agent_api_key
49
- raise ToolException(
50
- f"No agent-owned CARV API key found for skill '{self.name}' in category '{self.category}'."
51
- )
52
-
53
- elif api_key_provider == "platform":
54
- system_api_key = self.skill_store.get_system_config("carv_api_key")
55
- if system_api_key:
56
- logger.debug(
57
- f"Using system CARV API key for skill {self.name} in category {self.category}"
58
- )
59
- return system_api_key
60
- raise ToolException(
61
- f"No platform-hosted CARV API key found for skill '{self.name}' in category '{self.category}'."
62
- )
63
-
64
- else:
65
- raise ToolException(
66
- f"Invalid API key provider '{api_key_provider}' for skill '{self.name}'"
67
- )
68
-
69
- except Exception as e:
70
- # Re-raise ToolException if it's already one, otherwise wrap
71
- if isinstance(e, ToolException):
72
- raise
73
- raise ToolException(f"Failed to retrieve CARV API key: {str(e)}") from e
74
-
75
- async def apply_rate_limit(self, context) -> None:
76
- """
77
- Applies rate limiting ONLY if specified in the agent's config ('skill_config').
78
- Checks for 'rate_limit_number' and 'rate_limit_minutes'.
79
- If not configured, NO rate limiting is applied.
80
- Raises ConnectionAbortedError if the configured limit is exceeded.
81
- """
82
- skill_config = context.agent.skill_config(self.category)
83
- user_id = context.agent.id
84
-
85
- limit_num = skill_config.get("rate_limit_number")
86
- limit_min = skill_config.get("rate_limit_minutes")
87
-
88
- # Apply limit ONLY if both values are present and valid (truthy check handles None and 0)
89
- if limit_num and limit_min:
90
- logger.debug(
91
- f"Applying rate limit ({limit_num}/{limit_min} min) for user {user_id} on {self.name}"
92
- )
93
- if user_id:
94
- await self.user_rate_limit_by_category(user_id, limit_num, limit_min)
95
- else:
96
- # No valid agent configuration found, so do nothing.
97
- logger.debug(
98
- f"No agent rate limits configured for category '{self.category}'. Skipping rate limit for user {user_id}."
99
- )
100
-
101
- async def _call_carv_api(
102
- self,
103
- context,
104
- endpoint: str,
105
- method: str = "GET",
106
- params: Optional[Dict[str, Any]] = None,
107
- payload: Optional[Dict[str, Any]] = None,
108
- ) -> Tuple[Optional[Dict[str, Any]], Optional[Dict[str, Any]]]:
109
- """
110
- Makes a call to the CARV API and returns a tuple of (success, error).
111
-
112
- Args:
113
- context: The skill context.
114
- endpoint: The API endpoint path (e.g., "/ai-agent-backend/token_info").
115
- method: HTTP method ("GET", "POST", etc.).
116
- params: Query parameters for the request.
117
- payload: JSON payload for POST/PUT requests.
118
-
119
- Returns:
120
- Tuple where the first element is the response data if successful,
121
- and the second element is an error dict if an error occurred.
122
- """
123
-
124
- url = f"{CARV_API_BASE_URL}{endpoint}"
125
-
126
- try:
127
- api_key = self.get_api_key()
128
-
129
- headers = {
130
- "Authorization": api_key,
131
- "Content-Type": "application/json",
132
- }
133
-
134
- logger.debug(
135
- f"Calling CARV API: {method} {url} with params {params}, payload {payload}"
136
- )
137
-
138
- async with httpx.AsyncClient(timeout=30.0) as client:
139
- if method == "GET":
140
- response = await client.get(url, headers=headers, params=params)
141
- elif method == "POST":
142
- response = await client.post(
143
- url, headers=headers, json=payload, params=params
144
- )
145
- else:
146
- return None, {"error": f"Unsupported HTTP method: {method}"}
147
-
148
- # Do NOT raise for status here; always parse JSON
149
- try:
150
- response_json: dict[str, Any] = response.json()
151
- except Exception as json_err:
152
- err_msg = f"Failed to parse JSON response: {json_err}"
153
- logger.error(err_msg)
154
- return None, {"error": err_msg}
155
-
156
- logger.debug(
157
- f"CARV API Response (status {response.status_code}): {response_json}"
158
- )
159
-
160
- # Check if response_json signals an error explicitly (custom API error)
161
- if response.status_code >= 400 or "error" in response_json:
162
- # Return full error info (including status code, body, etc.)
163
- return None, {
164
- "error": response_json.get("error", "Unknown API error"),
165
- "status_code": response.status_code,
166
- "response": response_json,
167
- "url": url,
168
- "method": method,
169
- "params": params,
170
- "payload": payload,
171
- }
172
-
173
- # Otherwise return the 'data' field if present, else full response
174
- return response_json.get("data", response_json), None
175
-
176
- except Exception as e:
177
- logger.error(
178
- f"Error calling CARV API to {method} > {url}: {e}", exc_info=True
179
- )
180
- return None, {
181
- "error": str(e),
182
- "url": url,
183
- "method": method,
184
- "params": params,
185
- }
1
+ import logging
2
+ from typing import Any
3
+
4
+ import httpx # Ensure httpx is installed: pip install httpx
5
+ from langchain_core.tools.base import ToolException
6
+ from pydantic import BaseModel, Field
7
+
8
+ from intentkit.config.config import config
9
+ from intentkit.skills.base import IntentKitSkill
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ CARV_API_BASE_URL = "https://interface.carv.io"
14
+
15
+
16
+ class CarvBaseTool(IntentKitSkill):
17
+ """Base class for CARV API tools."""
18
+
19
+ name: str = Field(description="Tool name") # type: ignore
20
+ description: str = Field(description="Tool description")
21
+ args_schema: type[BaseModel] # type: ignore
22
+
23
+ @property
24
+ def category(self) -> str:
25
+ return "carv"
26
+
27
+ def get_api_key(self) -> str:
28
+ """
29
+ Retrieves the CARV API key based on the api_key_provider setting.
30
+
31
+ Returns:
32
+ The API key if found.
33
+
34
+ Raises:
35
+ ToolException: If the API key is not found or provider is invalid.
36
+ """
37
+ try:
38
+ context = self.get_context()
39
+ skill_config = context.agent.skill_config(self.category)
40
+ api_key_provider = skill_config.get("api_key_provider")
41
+ if api_key_provider == "agent_owner":
42
+ agent_api_key: str | None = skill_config.get("api_key")
43
+ if agent_api_key:
44
+ logger.debug(
45
+ f"Using agent-specific CARV API key for skill {self.name} in category {self.category}"
46
+ )
47
+ return agent_api_key
48
+ raise ToolException(
49
+ f"No agent-owned CARV API key found for skill '{self.name}' in category '{self.category}'."
50
+ )
51
+
52
+ elif api_key_provider == "platform":
53
+ system_api_key = config.carv_api_key
54
+ if system_api_key:
55
+ logger.debug(
56
+ f"Using system CARV API key for skill {self.name} in category {self.category}"
57
+ )
58
+ return system_api_key
59
+ raise ToolException(
60
+ f"No platform-hosted CARV API key found for skill '{self.name}' in category '{self.category}'."
61
+ )
62
+
63
+ else:
64
+ raise ToolException(
65
+ f"Invalid API key provider '{api_key_provider}' for skill '{self.name}'"
66
+ )
67
+
68
+ except Exception as e:
69
+ # Re-raise ToolException if it's already one, otherwise wrap
70
+ if isinstance(e, ToolException):
71
+ raise
72
+ raise ToolException(f"Failed to retrieve CARV API key: {str(e)}") from e
73
+
74
+ async def apply_rate_limit(self, context) -> None:
75
+ """
76
+ Applies rate limiting ONLY if specified in the agent's config ('skill_config').
77
+ Checks for 'rate_limit_number' and 'rate_limit_minutes'.
78
+ If not configured, NO rate limiting is applied.
79
+ Raises ConnectionAbortedError if the configured limit is exceeded.
80
+ """
81
+ skill_config = context.agent.skill_config(self.category)
82
+ user_id = context.agent.id
83
+
84
+ limit_num = skill_config.get("rate_limit_number")
85
+ limit_min = skill_config.get("rate_limit_minutes")
86
+
87
+ # Apply limit ONLY if both values are present and valid (truthy check handles None and 0)
88
+ if limit_num and limit_min:
89
+ logger.debug(
90
+ f"Applying rate limit ({limit_num}/{limit_min} min) for user {user_id} on {self.name}"
91
+ )
92
+ if user_id:
93
+ await self.user_rate_limit_by_category(limit_num, limit_min * 60)
94
+ else:
95
+ # No valid agent configuration found, so do nothing.
96
+ logger.debug(
97
+ f"No agent rate limits configured for category '{self.category}'. Skipping rate limit for user {user_id}."
98
+ )
99
+
100
+ async def _call_carv_api(
101
+ self,
102
+ context,
103
+ endpoint: str,
104
+ method: str = "GET",
105
+ params: dict[str, Any] | None = None,
106
+ payload: dict[str, Any] | None = None,
107
+ ) -> tuple[dict[str, Any] | None, dict[str, Any] | None]:
108
+ """
109
+ Makes a call to the CARV API and returns a tuple of (success, error).
110
+
111
+ Args:
112
+ context: The skill context.
113
+ endpoint: The API endpoint path (e.g., "/ai-agent-backend/token_info").
114
+ method: HTTP method ("GET", "POST", etc.).
115
+ params: Query parameters for the request.
116
+ payload: JSON payload for POST/PUT requests.
117
+
118
+ Returns:
119
+ Tuple where the first element is the response data if successful,
120
+ and the second element is an error dict if an error occurred.
121
+ """
122
+
123
+ url = f"{CARV_API_BASE_URL}{endpoint}"
124
+
125
+ try:
126
+ api_key = self.get_api_key()
127
+
128
+ headers = {
129
+ "Authorization": api_key,
130
+ "Content-Type": "application/json",
131
+ }
132
+
133
+ logger.debug(
134
+ f"Calling CARV API: {method} {url} with params {params}, payload {payload}"
135
+ )
136
+
137
+ async with httpx.AsyncClient(timeout=30.0) as client:
138
+ if method == "GET":
139
+ response = await client.get(url, headers=headers, params=params)
140
+ elif method == "POST":
141
+ response = await client.post(
142
+ url, headers=headers, json=payload, params=params
143
+ )
144
+ else:
145
+ return None, {"error": f"Unsupported HTTP method: {method}"}
146
+
147
+ # Do NOT raise for status here; always parse JSON
148
+ try:
149
+ response_json: dict[str, Any] = response.json()
150
+ except Exception as json_err:
151
+ err_msg = f"Failed to parse JSON response: {json_err}"
152
+ logger.error(err_msg)
153
+ return None, {"error": err_msg}
154
+
155
+ logger.debug(
156
+ f"CARV API Response (status {response.status_code}): {response_json}"
157
+ )
158
+
159
+ # Check if response_json signals an error explicitly (custom API error)
160
+ if response.status_code >= 400 or "error" in response_json:
161
+ # Return full error info (including status code, body, etc.)
162
+ return None, {
163
+ "error": response_json.get("error", "Unknown API error"),
164
+ "status_code": response.status_code,
165
+ "response": response_json,
166
+ "url": url,
167
+ "method": method,
168
+ "params": params,
169
+ "payload": payload,
170
+ }
171
+
172
+ # Otherwise return the 'data' field if present, else full response
173
+ return response_json.get("data", response_json), None
174
+
175
+ except Exception as e:
176
+ logger.error(
177
+ f"Error calling CARV API to {method} > {url}: {e}", exc_info=True
178
+ )
179
+ return None, {
180
+ "error": str(e),
181
+ "url": url,
182
+ "method": method,
183
+ "params": params,
184
+ }
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel
5
5
 
@@ -29,12 +29,12 @@ class FetchNewsTool(CarvBaseTool):
29
29
  "Fetches the latest news articles from the CARV API. "
30
30
  "Returns a list of news items, each with a title, URL, and a short summary (card_text)."
31
31
  )
32
- args_schema: Type[BaseModel] = CarvNewsInput
32
+ args_schema: type[BaseModel] = CarvNewsInput
33
33
 
34
34
  async def _arun(
35
35
  self, # type: ignore
36
36
  **kwargs: Any,
37
- ) -> Dict[str, Any]:
37
+ ) -> dict[str, Any]:
38
38
  """
39
39
  Fetches news from the CARV API and returns the response.
40
40
  The expected successful response structure is a dictionary containing an "infos" key,