intentkit 0.8.6.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 (312) 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 +10 -5
  5. intentkit/abstracts/skill.py +6 -144
  6. intentkit/abstracts/twitter.py +4 -5
  7. intentkit/clients/__init__.py +3 -2
  8. intentkit/clients/cdp.py +53 -92
  9. intentkit/clients/twitter.py +56 -57
  10. intentkit/clients/web3.py +1 -3
  11. intentkit/config/config.py +5 -0
  12. intentkit/core/agent.py +16 -388
  13. intentkit/core/asset.py +64 -18
  14. intentkit/core/client.py +1 -1
  15. intentkit/core/credit.py +19 -20
  16. intentkit/core/engine.py +26 -11
  17. intentkit/core/node.py +2 -1
  18. intentkit/core/prompt.py +53 -15
  19. intentkit/core/scheduler.py +9 -9
  20. intentkit/core/statistics.py +6 -7
  21. intentkit/models/agent.py +256 -176
  22. intentkit/models/agent_data.py +62 -36
  23. intentkit/models/agent_schema.json +6 -9
  24. intentkit/models/app_setting.py +6 -6
  25. intentkit/models/chat.py +28 -24
  26. intentkit/models/conversation.py +8 -8
  27. intentkit/models/credit.py +62 -64
  28. intentkit/models/db.py +8 -7
  29. intentkit/models/db_mig.py +2 -2
  30. intentkit/models/llm.csv +15 -12
  31. intentkit/models/llm.py +18 -16
  32. intentkit/models/redis.py +2 -3
  33. intentkit/models/skill.py +62 -66
  34. intentkit/models/skills.csv +30 -26
  35. intentkit/models/user.py +46 -21
  36. intentkit/skills/acolyt/__init__.py +2 -9
  37. intentkit/skills/acolyt/ask.py +3 -4
  38. intentkit/skills/acolyt/base.py +4 -9
  39. intentkit/skills/aixbt/__init__.py +2 -13
  40. intentkit/skills/aixbt/base.py +1 -7
  41. intentkit/skills/aixbt/projects.py +14 -15
  42. intentkit/skills/allora/__init__.py +2 -9
  43. intentkit/skills/allora/base.py +4 -9
  44. intentkit/skills/allora/price.py +3 -4
  45. intentkit/skills/base.py +175 -52
  46. intentkit/skills/basename/__init__.py +4 -8
  47. intentkit/skills/carv/__init__.py +115 -121
  48. intentkit/skills/carv/base.py +184 -185
  49. intentkit/skills/carv/fetch_news.py +3 -3
  50. intentkit/skills/carv/onchain_query.py +4 -4
  51. intentkit/skills/carv/token_info_and_price.py +5 -5
  52. intentkit/skills/casino/__init__.py +4 -15
  53. intentkit/skills/casino/base.py +1 -7
  54. intentkit/skills/casino/deck_draw.py +5 -8
  55. intentkit/skills/casino/deck_shuffle.py +6 -6
  56. intentkit/skills/casino/dice_roll.py +2 -4
  57. intentkit/skills/cdp/__init__.py +3 -10
  58. intentkit/skills/cdp/base.py +1 -7
  59. intentkit/skills/cdp/schema.json +1 -17
  60. intentkit/skills/chainlist/__init__.py +2 -7
  61. intentkit/skills/chainlist/base.py +1 -7
  62. intentkit/skills/chainlist/chain_lookup.py +18 -18
  63. intentkit/skills/common/__init__.py +2 -9
  64. intentkit/skills/common/base.py +1 -7
  65. intentkit/skills/common/current_time.py +1 -2
  66. intentkit/skills/cookiefun/__init__.py +6 -9
  67. intentkit/skills/cookiefun/base.py +2 -7
  68. intentkit/skills/cookiefun/get_account_details.py +7 -7
  69. intentkit/skills/cookiefun/get_account_feed.py +19 -19
  70. intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
  71. intentkit/skills/cookiefun/get_sectors.py +3 -3
  72. intentkit/skills/cookiefun/search_accounts.py +9 -9
  73. intentkit/skills/cryptocompare/__init__.py +7 -24
  74. intentkit/skills/cryptocompare/api.py +2 -3
  75. intentkit/skills/cryptocompare/base.py +10 -24
  76. intentkit/skills/cryptocompare/fetch_news.py +4 -5
  77. intentkit/skills/cryptocompare/fetch_price.py +6 -7
  78. intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
  79. intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
  80. intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
  81. intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
  82. intentkit/skills/cryptopanic/__init__.py +7 -10
  83. intentkit/skills/cryptopanic/base.py +51 -55
  84. intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
  85. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
  86. intentkit/skills/dapplooker/__init__.py +2 -9
  87. intentkit/skills/dapplooker/base.py +4 -9
  88. intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
  89. intentkit/skills/defillama/__init__.py +24 -74
  90. intentkit/skills/defillama/api.py +6 -9
  91. intentkit/skills/defillama/base.py +8 -19
  92. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
  93. intentkit/skills/defillama/coins/fetch_block.py +6 -8
  94. intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
  95. intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
  96. intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
  97. intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
  98. intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
  99. intentkit/skills/defillama/config/chains.py +1 -3
  100. intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
  101. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
  102. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
  103. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
  104. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
  105. intentkit/skills/defillama/tests/api_integration.test.py +1 -1
  106. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
  107. intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
  108. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
  109. intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
  110. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
  111. intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
  112. intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
  113. intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
  114. intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
  115. intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
  116. intentkit/skills/defillama/yields/fetch_pools.py +26 -30
  117. intentkit/skills/dexscreener/__init__.py +97 -102
  118. intentkit/skills/dexscreener/base.py +125 -130
  119. intentkit/skills/dexscreener/get_pair_info.py +4 -5
  120. intentkit/skills/dexscreener/get_token_pairs.py +4 -5
  121. intentkit/skills/dexscreener/get_tokens_info.py +7 -8
  122. intentkit/skills/dexscreener/model/search_token_response.py +80 -82
  123. intentkit/skills/dexscreener/search_token.py +182 -184
  124. intentkit/skills/dexscreener/utils.py +15 -14
  125. intentkit/skills/dune_analytics/__init__.py +7 -9
  126. intentkit/skills/dune_analytics/base.py +48 -52
  127. intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
  128. intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
  129. intentkit/skills/elfa/__init__.py +5 -18
  130. intentkit/skills/elfa/base.py +10 -14
  131. intentkit/skills/elfa/mention.py +19 -21
  132. intentkit/skills/elfa/stats.py +4 -4
  133. intentkit/skills/elfa/tokens.py +12 -12
  134. intentkit/skills/elfa/utils.py +26 -28
  135. intentkit/skills/enso/__init__.py +11 -31
  136. intentkit/skills/enso/base.py +9 -15
  137. intentkit/skills/enso/best_yield.py +5 -7
  138. intentkit/skills/enso/networks.py +3 -9
  139. intentkit/skills/enso/prices.py +2 -4
  140. intentkit/skills/enso/route.py +6 -12
  141. intentkit/skills/enso/tokens.py +4 -16
  142. intentkit/skills/enso/wallet.py +6 -6
  143. intentkit/skills/erc20/__init__.py +5 -11
  144. intentkit/skills/erc721/__init__.py +5 -9
  145. intentkit/skills/firecrawl/__init__.py +5 -18
  146. intentkit/skills/firecrawl/base.py +4 -9
  147. intentkit/skills/firecrawl/clear.py +4 -8
  148. intentkit/skills/firecrawl/crawl.py +19 -19
  149. intentkit/skills/firecrawl/query.py +4 -3
  150. intentkit/skills/firecrawl/scrape.py +17 -22
  151. intentkit/skills/firecrawl/utils.py +50 -42
  152. intentkit/skills/github/__init__.py +2 -7
  153. intentkit/skills/github/base.py +1 -7
  154. intentkit/skills/github/github_search.py +1 -2
  155. intentkit/skills/heurist/__init__.py +8 -27
  156. intentkit/skills/heurist/base.py +4 -9
  157. intentkit/skills/heurist/image_generation_animagine_xl.py +12 -13
  158. intentkit/skills/heurist/image_generation_arthemy_comics.py +12 -13
  159. intentkit/skills/heurist/image_generation_arthemy_real.py +12 -13
  160. intentkit/skills/heurist/image_generation_braindance.py +12 -13
  161. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +12 -13
  162. intentkit/skills/heurist/image_generation_flux_1_dev.py +12 -13
  163. intentkit/skills/heurist/image_generation_sdxl.py +12 -13
  164. intentkit/skills/http/__init__.py +4 -15
  165. intentkit/skills/http/base.py +1 -7
  166. intentkit/skills/http/get.py +21 -16
  167. intentkit/skills/http/post.py +23 -18
  168. intentkit/skills/http/put.py +23 -18
  169. intentkit/skills/lifi/__init__.py +5 -10
  170. intentkit/skills/lifi/base.py +1 -7
  171. intentkit/skills/lifi/token_execute.py +14 -17
  172. intentkit/skills/lifi/token_quote.py +7 -9
  173. intentkit/skills/lifi/utils.py +16 -16
  174. intentkit/skills/moralis/__init__.py +6 -10
  175. intentkit/skills/moralis/api.py +6 -7
  176. intentkit/skills/moralis/base.py +5 -10
  177. intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
  178. intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
  179. intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
  180. intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
  181. intentkit/skills/morpho/__init__.py +5 -9
  182. intentkit/skills/nation/__init__.py +4 -9
  183. intentkit/skills/nation/base.py +5 -10
  184. intentkit/skills/nation/nft_check.py +3 -4
  185. intentkit/skills/onchain.py +23 -0
  186. intentkit/skills/openai/__init__.py +17 -18
  187. intentkit/skills/openai/base.py +10 -14
  188. intentkit/skills/openai/dalle_image_generation.py +3 -8
  189. intentkit/skills/openai/gpt_avatar_generator.py +102 -0
  190. intentkit/skills/openai/gpt_image_generation.py +4 -8
  191. intentkit/skills/openai/gpt_image_mini_generator.py +91 -0
  192. intentkit/skills/openai/gpt_image_to_image.py +4 -8
  193. intentkit/skills/openai/image_to_text.py +3 -7
  194. intentkit/skills/openai/schema.json +32 -0
  195. intentkit/skills/portfolio/__init__.py +11 -35
  196. intentkit/skills/portfolio/base.py +33 -19
  197. intentkit/skills/portfolio/token_balances.py +21 -21
  198. intentkit/skills/portfolio/wallet_approvals.py +17 -18
  199. intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
  200. intentkit/skills/portfolio/wallet_history.py +31 -31
  201. intentkit/skills/portfolio/wallet_net_worth.py +13 -13
  202. intentkit/skills/portfolio/wallet_nfts.py +19 -19
  203. intentkit/skills/portfolio/wallet_profitability.py +18 -18
  204. intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
  205. intentkit/skills/portfolio/wallet_stats.py +3 -3
  206. intentkit/skills/portfolio/wallet_swaps.py +19 -19
  207. intentkit/skills/pyth/__init__.py +4 -10
  208. intentkit/skills/skills.toml +4 -0
  209. intentkit/skills/slack/__init__.py +5 -17
  210. intentkit/skills/slack/base.py +3 -9
  211. intentkit/skills/slack/get_channel.py +8 -8
  212. intentkit/skills/slack/get_message.py +9 -9
  213. intentkit/skills/slack/schedule_message.py +5 -5
  214. intentkit/skills/slack/send_message.py +3 -5
  215. intentkit/skills/supabase/__init__.py +7 -23
  216. intentkit/skills/supabase/base.py +1 -7
  217. intentkit/skills/supabase/delete_data.py +4 -4
  218. intentkit/skills/supabase/fetch_data.py +12 -12
  219. intentkit/skills/supabase/insert_data.py +4 -4
  220. intentkit/skills/supabase/invoke_function.py +6 -6
  221. intentkit/skills/supabase/update_data.py +6 -6
  222. intentkit/skills/supabase/upsert_data.py +4 -4
  223. intentkit/skills/superfluid/__init__.py +5 -9
  224. intentkit/skills/system/__init__.py +7 -24
  225. intentkit/skills/system/add_autonomous_task.py +10 -12
  226. intentkit/skills/system/delete_autonomous_task.py +2 -2
  227. intentkit/skills/system/edit_autonomous_task.py +14 -18
  228. intentkit/skills/system/list_autonomous_tasks.py +3 -5
  229. intentkit/skills/system/read_agent_api_key.py +6 -4
  230. intentkit/skills/system/regenerate_agent_api_key.py +6 -4
  231. intentkit/skills/tavily/__init__.py +3 -12
  232. intentkit/skills/tavily/base.py +4 -9
  233. intentkit/skills/tavily/tavily_extract.py +2 -4
  234. intentkit/skills/tavily/tavily_search.py +4 -6
  235. intentkit/skills/token/__init__.py +5 -10
  236. intentkit/skills/token/base.py +7 -11
  237. intentkit/skills/token/erc20_transfers.py +19 -19
  238. intentkit/skills/token/token_analytics.py +3 -3
  239. intentkit/skills/token/token_price.py +13 -13
  240. intentkit/skills/token/token_search.py +9 -9
  241. intentkit/skills/twitter/__init__.py +11 -35
  242. intentkit/skills/twitter/base.py +22 -34
  243. intentkit/skills/twitter/follow_user.py +2 -6
  244. intentkit/skills/twitter/get_mentions.py +5 -12
  245. intentkit/skills/twitter/get_timeline.py +4 -12
  246. intentkit/skills/twitter/get_user_by_username.py +2 -6
  247. intentkit/skills/twitter/get_user_tweets.py +5 -13
  248. intentkit/skills/twitter/like_tweet.py +2 -6
  249. intentkit/skills/twitter/post_tweet.py +6 -9
  250. intentkit/skills/twitter/reply_tweet.py +6 -9
  251. intentkit/skills/twitter/retweet.py +2 -6
  252. intentkit/skills/twitter/search_tweets.py +4 -12
  253. intentkit/skills/unrealspeech/__init__.py +2 -7
  254. intentkit/skills/unrealspeech/base.py +2 -8
  255. intentkit/skills/unrealspeech/text_to_speech.py +8 -8
  256. intentkit/skills/venice_audio/__init__.py +98 -106
  257. intentkit/skills/venice_audio/base.py +117 -121
  258. intentkit/skills/venice_audio/input.py +41 -41
  259. intentkit/skills/venice_audio/venice_audio.py +7 -11
  260. intentkit/skills/venice_image/__init__.py +147 -154
  261. intentkit/skills/venice_image/api.py +138 -138
  262. intentkit/skills/venice_image/base.py +185 -192
  263. intentkit/skills/venice_image/config.py +33 -35
  264. intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
  265. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
  266. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
  267. intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
  268. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
  269. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
  270. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
  271. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
  272. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
  273. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
  274. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
  275. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
  276. intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
  277. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
  278. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
  279. intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
  280. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
  281. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
  282. intentkit/skills/venice_image/utils.py +77 -78
  283. intentkit/skills/web_scraper/__init__.py +5 -18
  284. intentkit/skills/web_scraper/base.py +21 -7
  285. intentkit/skills/web_scraper/document_indexer.py +7 -6
  286. intentkit/skills/web_scraper/scrape_and_index.py +15 -15
  287. intentkit/skills/web_scraper/utils.py +62 -63
  288. intentkit/skills/web_scraper/website_indexer.py +17 -19
  289. intentkit/skills/weth/__init__.py +5 -11
  290. intentkit/skills/wow/__init__.py +5 -11
  291. intentkit/skills/x402/__init__.py +61 -0
  292. intentkit/skills/x402/ask_agent.py +98 -0
  293. intentkit/skills/x402/base.py +99 -0
  294. intentkit/skills/x402/http_request.py +117 -0
  295. intentkit/skills/x402/schema.json +45 -0
  296. intentkit/skills/x402/x402.webp +0 -0
  297. intentkit/skills/xmtp/__init__.py +4 -15
  298. intentkit/skills/xmtp/base.py +5 -5
  299. intentkit/skills/xmtp/price.py +6 -6
  300. intentkit/skills/xmtp/swap.py +6 -8
  301. intentkit/skills/xmtp/transfer.py +4 -6
  302. intentkit/utils/error.py +2 -2
  303. intentkit/utils/logging.py +2 -4
  304. intentkit/utils/s3.py +8 -9
  305. intentkit/utils/schema.py +100 -0
  306. intentkit/utils/slack_alert.py +7 -8
  307. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +3 -4
  308. intentkit-0.8.17.dist-info/RECORD +466 -0
  309. intentkit/models/generator.py +0 -347
  310. intentkit-0.8.6.dev2.dist-info/RECORD +0 -457
  311. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
  312. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,7 @@
1
1
  import logging
2
- from typing import Any, Dict, Optional, Type
2
+ from typing import Any
3
3
 
4
+ from langchain_core.tools import ToolException
4
5
  from pydantic import BaseModel, Field
5
6
 
6
7
  from intentkit.skills.portfolio.base import PortfolioBaseTool
@@ -20,11 +21,11 @@ class WalletApprovalsInput(BaseModel):
20
21
  description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
21
22
  default=DEFAULT_CHAIN,
22
23
  )
23
- cursor: Optional[str] = Field(
24
+ cursor: str | None = Field(
24
25
  description="The cursor for pagination.",
25
26
  default=None,
26
27
  )
27
- limit: Optional[int] = Field(
28
+ limit: int | None = Field(
28
29
  description="The number of results per page.",
29
30
  default=DEFAULT_LIMIT,
30
31
  )
@@ -42,16 +43,16 @@ class WalletApprovals(PortfolioBaseTool):
42
43
  "Retrieve active ERC20 token approvals for the specified wallet address. "
43
44
  "This helps identify which contracts have permission to spend tokens."
44
45
  )
45
- args_schema: Type[BaseModel] = WalletApprovalsInput
46
+ args_schema: type[BaseModel] = WalletApprovalsInput
46
47
 
47
48
  async def _arun(
48
49
  self,
49
50
  address: str,
50
51
  chain: str = DEFAULT_CHAIN,
51
- cursor: Optional[str] = None,
52
- limit: Optional[int] = DEFAULT_LIMIT,
52
+ cursor: str | None = None,
53
+ limit: int | None = DEFAULT_LIMIT,
53
54
  **kwargs,
54
- ) -> Dict[str, Any]:
55
+ ) -> dict[str, Any]:
55
56
  """Fetch wallet token approvals from Moralis.
56
57
 
57
58
  Args:
@@ -69,11 +70,6 @@ class WalletApprovals(PortfolioBaseTool):
69
70
  f"wallet_approvals.py: Fetching wallet approvals with context {context}"
70
71
  )
71
72
 
72
- # Get the API key from the agent's configuration
73
- api_key = self.get_api_key()
74
- if not api_key:
75
- return {"error": "No Moralis API key provided in the configuration."}
76
-
77
73
  # Build query parameters
78
74
  params = {
79
75
  "chain": chain,
@@ -85,16 +81,19 @@ class WalletApprovals(PortfolioBaseTool):
85
81
  params["cursor"] = cursor
86
82
 
87
83
  # Call Moralis API
84
+ api_key = self.get_api_key()
85
+
88
86
  try:
89
87
  endpoint = f"/wallets/{address}/approvals"
90
88
  return await self._make_request(
91
89
  method="GET", endpoint=endpoint, api_key=api_key, params=params
92
90
  )
93
- except Exception as e:
91
+ except ToolException:
92
+ raise
93
+ except Exception as exc: # noqa: BLE001
94
94
  logger.error(
95
- f"wallet_approvals.py: Error fetching wallet approvals: {e}",
96
- exc_info=True,
95
+ "wallet_approvals.py: Error fetching wallet approvals", exc_info=exc
97
96
  )
98
- return {
99
- "error": "An error occurred while fetching wallet approvals. Please try again later."
100
- }
97
+ raise ToolException(
98
+ "An unexpected error occurred while fetching wallet approvals."
99
+ ) from exc
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, Field
5
5
 
@@ -31,14 +31,14 @@ class WalletDefiPositions(PortfolioBaseTool):
31
31
  "Get the DeFi positions summary of a wallet address. "
32
32
  "Returns information about liquidity positions, staking, lending, and other DeFi activities."
33
33
  )
34
- args_schema: Type[BaseModel] = WalletDefiPositionsInput
34
+ args_schema: type[BaseModel] = WalletDefiPositionsInput
35
35
 
36
36
  async def _arun(
37
37
  self,
38
38
  address: str,
39
39
  chain: str = DEFAULT_CHAIN,
40
40
  **kwargs,
41
- ) -> Dict[str, Any]:
41
+ ) -> dict[str, Any]:
42
42
  """Fetch wallet DeFi positions from Moralis.
43
43
 
44
44
  Args:
@@ -1,6 +1,7 @@
1
1
  import logging
2
- from typing import Any, Dict, Optional, Type
2
+ from typing import Any
3
3
 
4
+ from langchain_core.tools import ToolException
4
5
  from pydantic import BaseModel, Field
5
6
 
6
7
  from intentkit.skills.portfolio.base import PortfolioBaseTool
@@ -23,39 +24,39 @@ class WalletHistoryInput(BaseModel):
23
24
  description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
24
25
  default=DEFAULT_CHAIN,
25
26
  )
26
- limit: Optional[int] = Field(
27
+ limit: int | None = Field(
27
28
  description="The desired page size of the result.",
28
29
  default=DEFAULT_LIMIT,
29
30
  )
30
- cursor: Optional[str] = Field(
31
+ cursor: str | None = Field(
31
32
  description="The cursor returned in the previous response (for pagination).",
32
33
  default=None,
33
34
  )
34
- from_block: Optional[int] = Field(
35
+ from_block: int | None = Field(
35
36
  description="The minimum block number to get transactions from.",
36
37
  default=None,
37
38
  )
38
- to_block: Optional[int] = Field(
39
+ to_block: int | None = Field(
39
40
  description="The maximum block number to get transactions from.",
40
41
  default=None,
41
42
  )
42
- from_date: Optional[str] = Field(
43
+ from_date: str | None = Field(
43
44
  description="The start date to get transactions from (format in seconds or datestring).",
44
45
  default=None,
45
46
  )
46
- to_date: Optional[str] = Field(
47
+ to_date: str | None = Field(
47
48
  description="The end date to get transactions from (format in seconds or datestring).",
48
49
  default=None,
49
50
  )
50
- include_internal_transactions: Optional[bool] = Field(
51
+ include_internal_transactions: bool | None = Field(
51
52
  description="If the result should contain the internal transactions.",
52
53
  default=None,
53
54
  )
54
- nft_metadata: Optional[bool] = Field(
55
+ nft_metadata: bool | None = Field(
55
56
  description="If the result should contain the NFT metadata.",
56
57
  default=None,
57
58
  )
58
- order: Optional[str] = Field(
59
+ order: str | None = Field(
59
60
  description="The order of the result, in ascending (ASC) or descending (DESC).",
60
61
  default=DEFAULT_ORDER,
61
62
  )
@@ -73,23 +74,23 @@ class WalletHistory(PortfolioBaseTool):
73
74
  "Retrieve the full transaction history of a specified wallet address, including sends, "
74
75
  "receives, token and NFT transfers, and contract interactions."
75
76
  )
76
- args_schema: Type[BaseModel] = WalletHistoryInput
77
+ args_schema: type[BaseModel] = WalletHistoryInput
77
78
 
78
79
  async def _arun(
79
80
  self,
80
81
  address: str,
81
82
  chain: str = DEFAULT_CHAIN,
82
- limit: Optional[int] = DEFAULT_LIMIT,
83
- cursor: Optional[str] = None,
84
- from_block: Optional[int] = None,
85
- to_block: Optional[int] = None,
86
- from_date: Optional[str] = None,
87
- to_date: Optional[str] = None,
88
- include_internal_transactions: Optional[bool] = None,
89
- nft_metadata: Optional[bool] = None,
90
- order: Optional[str] = DEFAULT_ORDER,
83
+ limit: int | None = DEFAULT_LIMIT,
84
+ cursor: str | None = None,
85
+ from_block: int | None = None,
86
+ to_block: int | None = None,
87
+ from_date: str | None = None,
88
+ to_date: str | None = None,
89
+ include_internal_transactions: bool | None = None,
90
+ nft_metadata: bool | None = None,
91
+ order: str | None = DEFAULT_ORDER,
91
92
  **kwargs,
92
- ) -> Dict[str, Any]:
93
+ ) -> dict[str, Any]:
93
94
  """Fetch wallet transaction history from Moralis.
94
95
 
95
96
  Args:
@@ -114,11 +115,6 @@ class WalletHistory(PortfolioBaseTool):
114
115
  f"wallet_history.py: Fetching wallet history with context {context}"
115
116
  )
116
117
 
117
- # Get the API key from the agent's configuration
118
- api_key = self.get_api_key()
119
- if not api_key:
120
- return {"error": "No Moralis API key provided in the configuration."}
121
-
122
118
  # Build query parameters
123
119
  params = {"chain": chain, "limit": limit, "order": order}
124
120
 
@@ -139,15 +135,19 @@ class WalletHistory(PortfolioBaseTool):
139
135
  params["nft_metadata"] = nft_metadata
140
136
 
141
137
  # Call Moralis API
138
+ api_key = self.get_api_key()
139
+
142
140
  try:
143
141
  endpoint = f"/wallets/{address}/history"
144
142
  return await self._make_request(
145
143
  method="GET", endpoint=endpoint, api_key=api_key, params=params
146
144
  )
147
- except Exception as e:
145
+ except ToolException:
146
+ raise
147
+ except Exception as exc: # noqa: BLE001
148
148
  logger.error(
149
- f"wallet_history.py: Error fetching wallet history: {e}", exc_info=True
149
+ "wallet_history.py: Error fetching wallet history", exc_info=exc
150
150
  )
151
- return {
152
- "error": "An error occurred while fetching wallet history. Please try again later."
153
- }
151
+ raise ToolException(
152
+ "An unexpected error occurred while fetching wallet history."
153
+ ) from exc
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, List, Optional, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, Field
5
5
 
@@ -12,23 +12,23 @@ class WalletNetWorthInput(BaseModel):
12
12
  """Input for wallet net worth tool."""
13
13
 
14
14
  address: str = Field(description="The wallet address to calculate net worth for.")
15
- chains: Optional[List[str]] = Field(
15
+ chains: list[str] | None = Field(
16
16
  description="The chains to query (e.g., ['eth', 'bsc', 'polygon']).",
17
17
  default=None,
18
18
  )
19
- exclude_spam: Optional[bool] = Field(
19
+ exclude_spam: bool | None = Field(
20
20
  description="Exclude spam tokens from the result.",
21
21
  default=True,
22
22
  )
23
- exclude_unverified_contracts: Optional[bool] = Field(
23
+ exclude_unverified_contracts: bool | None = Field(
24
24
  description="Exclude unverified contracts from the result.",
25
25
  default=True,
26
26
  )
27
- max_token_inactivity: Optional[int] = Field(
27
+ max_token_inactivity: int | None = Field(
28
28
  description="Exclude tokens inactive for more than the given amount of days.",
29
29
  default=1,
30
30
  )
31
- min_pair_side_liquidity_usd: Optional[float] = Field(
31
+ min_pair_side_liquidity_usd: float | None = Field(
32
32
  description="Exclude tokens with liquidity less than the specified amount in USD.",
33
33
  default=1000,
34
34
  )
@@ -46,18 +46,18 @@ class WalletNetWorth(PortfolioBaseTool):
46
46
  "Get the net worth of a wallet in USD across multiple chains. "
47
47
  "Filters out spam tokens and low-liquidity assets for more accurate results."
48
48
  )
49
- args_schema: Type[BaseModel] = WalletNetWorthInput
49
+ args_schema: type[BaseModel] = WalletNetWorthInput
50
50
 
51
51
  async def _arun(
52
52
  self,
53
53
  address: str,
54
- chains: Optional[List[str]] = None,
55
- exclude_spam: Optional[bool] = True,
56
- exclude_unverified_contracts: Optional[bool] = True,
57
- max_token_inactivity: Optional[int] = 1,
58
- min_pair_side_liquidity_usd: Optional[float] = 1000,
54
+ chains: list[str] | None = None,
55
+ exclude_spam: bool | None = True,
56
+ exclude_unverified_contracts: bool | None = True,
57
+ max_token_inactivity: int | None = 1,
58
+ min_pair_side_liquidity_usd: float | None = 1000,
59
59
  **kwargs,
60
- ) -> Dict[str, Any]:
60
+ ) -> dict[str, Any]:
61
61
  """Calculate wallet net worth from Moralis.
62
62
 
63
63
  Args:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, List, Optional, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, Field
5
5
 
@@ -17,35 +17,35 @@ class WalletNFTsInput(BaseModel):
17
17
  description="The chain to query (e.g., 'eth', 'base', 'polygon').",
18
18
  default=DEFAULT_CHAIN,
19
19
  )
20
- format: Optional[str] = Field(
20
+ format: str | None = Field(
21
21
  description="The format of the token ID ('decimal' or 'hex').",
22
22
  default="decimal",
23
23
  )
24
- limit: Optional[int] = Field(
24
+ limit: int | None = Field(
25
25
  description="The desired page size of the result.",
26
26
  default=DEFAULT_LIMIT,
27
27
  )
28
- exclude_spam: Optional[bool] = Field(
28
+ exclude_spam: bool | None = Field(
29
29
  description="Should spam NFTs be excluded from the result?",
30
30
  default=True,
31
31
  )
32
- token_addresses: Optional[List[str]] = Field(
32
+ token_addresses: list[str] | None = Field(
33
33
  description="The non-fungible token (NFT) addresses to get balances for.",
34
34
  default=None,
35
35
  )
36
- cursor: Optional[str] = Field(
36
+ cursor: str | None = Field(
37
37
  description="The cursor returned in the previous response (for pagination).",
38
38
  default=None,
39
39
  )
40
- normalize_metadata: Optional[bool] = Field(
40
+ normalize_metadata: bool | None = Field(
41
41
  description="The option to enable metadata normalization.",
42
42
  default=True,
43
43
  )
44
- media_items: Optional[bool] = Field(
44
+ media_items: bool | None = Field(
45
45
  description="Should preview media data be returned?",
46
46
  default=False,
47
47
  )
48
- include_prices: Optional[bool] = Field(
48
+ include_prices: bool | None = Field(
49
49
  description="Should NFT last sale prices be included in the result?",
50
50
  default=False,
51
51
  )
@@ -63,22 +63,22 @@ class WalletNFTs(PortfolioBaseTool):
63
63
  "Get NFTs owned by a given wallet address. Results include token details, "
64
64
  "metadata, collection information, and optionally prices."
65
65
  )
66
- args_schema: Type[BaseModel] = WalletNFTsInput
66
+ args_schema: type[BaseModel] = WalletNFTsInput
67
67
 
68
68
  async def _arun(
69
69
  self,
70
70
  address: str,
71
71
  chain: str = DEFAULT_CHAIN,
72
- format: Optional[str] = "decimal",
73
- limit: Optional[int] = DEFAULT_LIMIT,
74
- exclude_spam: Optional[bool] = True,
75
- token_addresses: Optional[List[str]] = None,
76
- cursor: Optional[str] = None,
77
- normalize_metadata: Optional[bool] = True,
78
- media_items: Optional[bool] = False,
79
- include_prices: Optional[bool] = False,
72
+ format: str | None = "decimal",
73
+ limit: int | None = DEFAULT_LIMIT,
74
+ exclude_spam: bool | None = True,
75
+ token_addresses: list[str] | None = None,
76
+ cursor: str | None = None,
77
+ normalize_metadata: bool | None = True,
78
+ media_items: bool | None = False,
79
+ include_prices: bool | None = False,
80
80
  **kwargs,
81
- ) -> Dict[str, Any]:
81
+ ) -> dict[str, Any]:
82
82
  """Fetch NFTs owned by a wallet from Moralis.
83
83
 
84
84
  Args:
@@ -1,6 +1,7 @@
1
1
  import logging
2
- from typing import Any, Dict, List, Optional, Type
2
+ from typing import Any
3
3
 
4
+ from langchain_core.tools import ToolException
4
5
  from pydantic import BaseModel, Field
5
6
 
6
7
  from intentkit.skills.portfolio.base import PortfolioBaseTool
@@ -19,11 +20,11 @@ class WalletProfitabilityInput(BaseModel):
19
20
  description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
20
21
  default=DEFAULT_CHAIN,
21
22
  )
22
- days: Optional[str] = Field(
23
+ days: str | None = Field(
23
24
  description="Timeframe in days for which profitability is calculated. Options: 'all', '7', '30', '60', '90'.",
24
25
  default="all",
25
26
  )
26
- token_addresses: Optional[List[str]] = Field(
27
+ token_addresses: list[str] | None = Field(
27
28
  description="The token addresses list to filter the result with.",
28
29
  default=None,
29
30
  )
@@ -41,16 +42,16 @@ class WalletProfitability(PortfolioBaseTool):
41
42
  "Retrieve detailed profitability breakdown for a wallet, including profit/loss per token, "
42
43
  "average buy/sell prices, and realized profits. Can be filtered by specific tokens."
43
44
  )
44
- args_schema: Type[BaseModel] = WalletProfitabilityInput
45
+ args_schema: type[BaseModel] = WalletProfitabilityInput
45
46
 
46
47
  async def _arun(
47
48
  self,
48
49
  address: str,
49
50
  chain: str = DEFAULT_CHAIN,
50
- days: Optional[str] = "all",
51
- token_addresses: Optional[List[str]] = None,
51
+ days: str | None = "all",
52
+ token_addresses: list[str] | None = None,
52
53
  **kwargs,
53
- ) -> Dict[str, Any]:
54
+ ) -> dict[str, Any]:
54
55
  """Fetch detailed wallet profitability from Moralis.
55
56
 
56
57
  Args:
@@ -68,11 +69,6 @@ class WalletProfitability(PortfolioBaseTool):
68
69
  f"wallet_profitability.py: Fetching profitability breakdown with context {context}"
69
70
  )
70
71
 
71
- # Get the API key from the agent's configuration
72
- api_key = self.get_api_key()
73
- if not api_key:
74
- return {"error": "No Moralis API key provided in the configuration."}
75
-
76
72
  # Build query parameters
77
73
  params = {
78
74
  "chain": chain,
@@ -84,16 +80,20 @@ class WalletProfitability(PortfolioBaseTool):
84
80
  params["token_addresses"] = token_addresses
85
81
 
86
82
  # Call Moralis API
83
+ api_key = self.get_api_key()
84
+
87
85
  try:
88
86
  endpoint = f"/wallets/{address}/profitability"
89
87
  return await self._make_request(
90
88
  method="GET", endpoint=endpoint, api_key=api_key, params=params
91
89
  )
92
- except Exception as e:
90
+ except ToolException:
91
+ raise
92
+ except Exception as exc: # noqa: BLE001
93
93
  logger.error(
94
- f"wallet_profitability.py: Error fetching profitability breakdown: {e}",
95
- exc_info=True,
94
+ "wallet_profitability.py: Error fetching profitability breakdown",
95
+ exc_info=exc,
96
96
  )
97
- return {
98
- "error": "An error occurred while fetching profitability breakdown. Please try again later."
99
- }
97
+ raise ToolException(
98
+ "An unexpected error occurred while fetching profitability breakdown."
99
+ ) from exc
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, Optional, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, Field
5
5
 
@@ -19,7 +19,7 @@ class WalletProfitabilitySummaryInput(BaseModel):
19
19
  description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
20
20
  default=DEFAULT_CHAIN,
21
21
  )
22
- days: Optional[str] = Field(
22
+ days: str | None = Field(
23
23
  description="Timeframe in days for the profitability summary. Options: 'all', '7', '30', '60', '90'.",
24
24
  default="all",
25
25
  )
@@ -37,15 +37,15 @@ class WalletProfitabilitySummary(PortfolioBaseTool):
37
37
  "Retrieve a summary of wallet profitability including total profit/loss, "
38
38
  "trade volume, and other metrics. Filter by time period."
39
39
  )
40
- args_schema: Type[BaseModel] = WalletProfitabilitySummaryInput
40
+ args_schema: type[BaseModel] = WalletProfitabilitySummaryInput
41
41
 
42
42
  async def _arun(
43
43
  self,
44
44
  address: str,
45
45
  chain: str = DEFAULT_CHAIN,
46
- days: Optional[str] = "all",
46
+ days: str | None = "all",
47
47
  **kwargs,
48
- ) -> Dict[str, Any]:
48
+ ) -> dict[str, Any]:
49
49
  """Fetch wallet profitability summary from Moralis.
50
50
 
51
51
  Args:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, Field
5
5
 
@@ -31,14 +31,14 @@ class WalletStats(PortfolioBaseTool):
31
31
  "Get statistical information about a wallet, including the number of NFTs, "
32
32
  "collections, and transaction counts."
33
33
  )
34
- args_schema: Type[BaseModel] = WalletStatsInput
34
+ args_schema: type[BaseModel] = WalletStatsInput
35
35
 
36
36
  async def _arun(
37
37
  self,
38
38
  address: str,
39
39
  chain: str = DEFAULT_CHAIN,
40
40
  **kwargs,
41
- ) -> Dict[str, Any]:
41
+ ) -> dict[str, Any]:
42
42
  """Fetch wallet stats from Moralis.
43
43
 
44
44
  Args:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, List, Optional, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, Field
5
5
 
@@ -21,35 +21,35 @@ class WalletSwapsInput(BaseModel):
21
21
  description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
22
22
  default=DEFAULT_CHAIN,
23
23
  )
24
- cursor: Optional[str] = Field(
24
+ cursor: str | None = Field(
25
25
  description="The cursor for pagination.",
26
26
  default=None,
27
27
  )
28
- limit: Optional[int] = Field(
28
+ limit: int | None = Field(
29
29
  description="The number of results per page.",
30
30
  default=DEFAULT_LIMIT,
31
31
  )
32
- from_block: Optional[str] = Field(
32
+ from_block: str | None = Field(
33
33
  description="The minimum block number to get transactions from.",
34
34
  default=None,
35
35
  )
36
- to_block: Optional[str] = Field(
36
+ to_block: str | None = Field(
37
37
  description="The maximum block number to get transactions from.",
38
38
  default=None,
39
39
  )
40
- from_date: Optional[str] = Field(
40
+ from_date: str | None = Field(
41
41
  description="The start date to get transactions from (format in seconds or datestring).",
42
42
  default=None,
43
43
  )
44
- to_date: Optional[str] = Field(
44
+ to_date: str | None = Field(
45
45
  description="The end date to get transactions from (format in seconds or datestring).",
46
46
  default=None,
47
47
  )
48
- order: Optional[str] = Field(
48
+ order: str | None = Field(
49
49
  description="The order of the result (ASC or DESC).",
50
50
  default=DEFAULT_ORDER,
51
51
  )
52
- transaction_types: Optional[List[str]] = Field(
52
+ transaction_types: list[str] | None = Field(
53
53
  description="Array of transaction types. Allowed values are 'buy', 'sell'.",
54
54
  default=None,
55
55
  )
@@ -67,22 +67,22 @@ class WalletSwaps(PortfolioBaseTool):
67
67
  "Get all swap-related transactions (buy, sell) for a wallet address. "
68
68
  "Note that swaps data is only available from September 2024 onwards."
69
69
  )
70
- args_schema: Type[BaseModel] = WalletSwapsInput
70
+ args_schema: type[BaseModel] = WalletSwapsInput
71
71
 
72
72
  async def _arun(
73
73
  self,
74
74
  address: str,
75
75
  chain: str = DEFAULT_CHAIN,
76
- cursor: Optional[str] = None,
77
- limit: Optional[int] = DEFAULT_LIMIT,
78
- from_block: Optional[str] = None,
79
- to_block: Optional[str] = None,
80
- from_date: Optional[str] = None,
81
- to_date: Optional[str] = None,
82
- order: Optional[str] = DEFAULT_ORDER,
83
- transaction_types: Optional[List[str]] = None,
76
+ cursor: str | None = None,
77
+ limit: int | None = DEFAULT_LIMIT,
78
+ from_block: str | None = None,
79
+ to_block: str | None = None,
80
+ from_date: str | None = None,
81
+ to_date: str | None = None,
82
+ order: str | None = DEFAULT_ORDER,
83
+ transaction_types: list[str] | None = None,
84
84
  **kwargs,
85
- ) -> Dict[str, Any]:
85
+ ) -> dict[str, Any]:
86
86
  """Fetch wallet swap transactions from Moralis.
87
87
 
88
88
  Args:
@@ -1,10 +1,10 @@
1
1
  """Pyth AgentKit skills."""
2
2
 
3
- from typing import TYPE_CHECKING, Optional, TypedDict
3
+ from typing import TypedDict
4
4
 
5
5
  from coinbase_agentkit import pyth_action_provider
6
6
 
7
- from intentkit.abstracts.skill import SkillStoreABC
7
+ from intentkit.models.agent import Agent
8
8
  from intentkit.skills.base import (
9
9
  SkillConfig,
10
10
  SkillState,
@@ -13,9 +13,6 @@ from intentkit.skills.base import (
13
13
  )
14
14
  from intentkit.skills.pyth.base import PythBaseTool
15
15
 
16
- if TYPE_CHECKING:
17
- from intentkit.models.agent import Agent
18
-
19
16
 
20
17
  class SkillStates(TypedDict):
21
18
  PythActionProvider_fetch_price: SkillState
@@ -31,9 +28,8 @@ class Config(SkillConfig):
31
28
  async def get_skills(
32
29
  config: "Config",
33
30
  is_private: bool,
34
- store: SkillStoreABC,
35
31
  agent_id: str,
36
- agent: Optional["Agent"] = None,
32
+ agent: Agent | None = None,
37
33
  **_,
38
34
  ) -> list[PythBaseTool]:
39
35
  """Get all Pyth skills."""
@@ -45,9 +41,7 @@ async def get_skills(
45
41
  if state == "public" or (state == "private" and is_private):
46
42
  available_skills.append(skill_name)
47
43
 
48
- actions = await get_agentkit_actions(
49
- agent_id, store, [pyth_action_provider], agent=agent
50
- )
44
+ actions = await get_agentkit_actions(agent_id, [pyth_action_provider], agent=agent)
51
45
  tools: list[PythBaseTool] = []
52
46
  for skill in available_skills:
53
47
  for action in actions:
@@ -118,6 +118,10 @@ author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
118
118
  author_github = "yornfifty"
119
119
  author_wallet = "0xF60D4B6780D5D51827602D7aC319458bc9e921F4"
120
120
 
121
+ [x402]
122
+ author_github = "hyacinthus"
123
+ author_wallet = "0x445750026A4a1906b61302442E085f9cbAfe206a"
124
+
121
125
  [portfolio]
122
126
  author_github = "bluntbrain"
123
127
  author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"