intentkit 0.8.16.dev1__py3-none-any.whl → 0.8.17.dev2__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 (274) 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 +6 -5
  5. intentkit/abstracts/skill.py +5 -5
  6. intentkit/abstracts/twitter.py +4 -5
  7. intentkit/clients/cdp.py +19 -77
  8. intentkit/clients/twitter.py +26 -34
  9. intentkit/clients/web3.py +1 -3
  10. intentkit/config/config.py +4 -0
  11. intentkit/core/agent.py +15 -15
  12. intentkit/core/asset.py +1 -2
  13. intentkit/core/client.py +1 -1
  14. intentkit/core/credit.py +19 -20
  15. intentkit/core/engine.py +2 -4
  16. intentkit/core/node.py +2 -1
  17. intentkit/core/prompt.py +3 -4
  18. intentkit/core/scheduler.py +1 -1
  19. intentkit/core/statistics.py +6 -7
  20. intentkit/models/agent.py +125 -92
  21. intentkit/models/agent_data.py +62 -36
  22. intentkit/models/app_setting.py +6 -6
  23. intentkit/models/chat.py +27 -24
  24. intentkit/models/conversation.py +8 -8
  25. intentkit/models/credit.py +62 -64
  26. intentkit/models/db.py +8 -7
  27. intentkit/models/db_mig.py +2 -2
  28. intentkit/models/llm.py +12 -14
  29. intentkit/models/redis.py +2 -3
  30. intentkit/models/skill.py +25 -27
  31. intentkit/models/skills.csv +29 -28
  32. intentkit/models/user.py +21 -22
  33. intentkit/skills/acolyt/ask.py +3 -4
  34. intentkit/skills/acolyt/base.py +1 -3
  35. intentkit/skills/aixbt/base.py +1 -3
  36. intentkit/skills/aixbt/projects.py +13 -13
  37. intentkit/skills/allora/base.py +1 -3
  38. intentkit/skills/allora/price.py +2 -3
  39. intentkit/skills/base.py +15 -22
  40. intentkit/skills/basename/__init__.py +3 -5
  41. intentkit/skills/carv/__init__.py +7 -8
  42. intentkit/skills/carv/base.py +6 -6
  43. intentkit/skills/carv/fetch_news.py +3 -3
  44. intentkit/skills/carv/onchain_query.py +4 -4
  45. intentkit/skills/carv/token_info_and_price.py +5 -5
  46. intentkit/skills/casino/base.py +1 -3
  47. intentkit/skills/casino/deck_draw.py +1 -2
  48. intentkit/skills/casino/deck_shuffle.py +1 -2
  49. intentkit/skills/casino/dice_roll.py +1 -2
  50. intentkit/skills/cdp/__init__.py +3 -5
  51. intentkit/skills/cdp/base.py +1 -3
  52. intentkit/skills/chainlist/base.py +1 -3
  53. intentkit/skills/chainlist/chain_lookup.py +18 -18
  54. intentkit/skills/common/base.py +1 -3
  55. intentkit/skills/common/current_time.py +1 -2
  56. intentkit/skills/cookiefun/base.py +1 -2
  57. intentkit/skills/cookiefun/get_account_details.py +7 -7
  58. intentkit/skills/cookiefun/get_account_feed.py +19 -19
  59. intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
  60. intentkit/skills/cookiefun/get_sectors.py +3 -3
  61. intentkit/skills/cookiefun/search_accounts.py +9 -9
  62. intentkit/skills/cryptocompare/api.py +2 -3
  63. intentkit/skills/cryptocompare/base.py +6 -6
  64. intentkit/skills/cryptocompare/fetch_news.py +3 -4
  65. intentkit/skills/cryptocompare/fetch_price.py +5 -6
  66. intentkit/skills/cryptocompare/fetch_top_exchanges.py +3 -4
  67. intentkit/skills/cryptocompare/fetch_top_market_cap.py +3 -4
  68. intentkit/skills/cryptocompare/fetch_top_volume.py +3 -4
  69. intentkit/skills/cryptocompare/fetch_trading_signals.py +4 -5
  70. intentkit/skills/cryptopanic/__init__.py +4 -4
  71. intentkit/skills/cryptopanic/base.py +1 -3
  72. intentkit/skills/cryptopanic/fetch_crypto_news.py +3 -5
  73. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +3 -3
  74. intentkit/skills/dapplooker/base.py +1 -3
  75. intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
  76. intentkit/skills/defillama/api.py +6 -9
  77. intentkit/skills/defillama/base.py +5 -6
  78. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +6 -8
  79. intentkit/skills/defillama/coins/fetch_block.py +4 -6
  80. intentkit/skills/defillama/coins/fetch_current_prices.py +6 -8
  81. intentkit/skills/defillama/coins/fetch_first_price.py +5 -7
  82. intentkit/skills/defillama/coins/fetch_historical_prices.py +7 -9
  83. intentkit/skills/defillama/coins/fetch_price_chart.py +7 -9
  84. intentkit/skills/defillama/coins/fetch_price_percentage.py +5 -7
  85. intentkit/skills/defillama/config/chains.py +1 -3
  86. intentkit/skills/defillama/fees/fetch_fees_overview.py +22 -24
  87. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +14 -16
  88. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +6 -8
  89. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +3 -5
  90. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +5 -7
  91. intentkit/skills/defillama/tests/api_integration.test.py +1 -1
  92. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +2 -4
  93. intentkit/skills/defillama/tvl/fetch_chains.py +7 -9
  94. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +2 -4
  95. intentkit/skills/defillama/tvl/fetch_protocol.py +30 -36
  96. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +1 -3
  97. intentkit/skills/defillama/tvl/fetch_protocols.py +35 -43
  98. intentkit/skills/defillama/volumes/fetch_dex_overview.py +40 -46
  99. intentkit/skills/defillama/volumes/fetch_dex_summary.py +33 -35
  100. intentkit/skills/defillama/volumes/fetch_options_overview.py +22 -26
  101. intentkit/skills/defillama/yields/fetch_pool_chart.py +8 -10
  102. intentkit/skills/defillama/yields/fetch_pools.py +24 -28
  103. intentkit/skills/dexscreener/__init__.py +2 -2
  104. intentkit/skills/dexscreener/base.py +3 -3
  105. intentkit/skills/dexscreener/get_pair_info.py +2 -2
  106. intentkit/skills/dexscreener/get_token_pairs.py +2 -2
  107. intentkit/skills/dexscreener/get_tokens_info.py +5 -5
  108. intentkit/skills/dexscreener/model/search_token_response.py +80 -82
  109. intentkit/skills/dexscreener/search_token.py +182 -182
  110. intentkit/skills/dexscreener/utils.py +15 -14
  111. intentkit/skills/dune_analytics/__init__.py +4 -4
  112. intentkit/skills/dune_analytics/base.py +1 -3
  113. intentkit/skills/dune_analytics/fetch_kol_buys.py +4 -4
  114. intentkit/skills/dune_analytics/fetch_nation_metrics.py +5 -5
  115. intentkit/skills/elfa/base.py +1 -3
  116. intentkit/skills/elfa/mention.py +19 -21
  117. intentkit/skills/elfa/stats.py +4 -4
  118. intentkit/skills/elfa/tokens.py +12 -12
  119. intentkit/skills/elfa/utils.py +25 -27
  120. intentkit/skills/enso/__init__.py +2 -2
  121. intentkit/skills/enso/base.py +5 -8
  122. intentkit/skills/enso/best_yield.py +4 -6
  123. intentkit/skills/enso/networks.py +1 -2
  124. intentkit/skills/enso/prices.py +1 -3
  125. intentkit/skills/enso/route.py +1 -3
  126. intentkit/skills/enso/tokens.py +1 -3
  127. intentkit/skills/enso/wallet.py +5 -5
  128. intentkit/skills/erc20/__init__.py +4 -6
  129. intentkit/skills/erc721/__init__.py +4 -6
  130. intentkit/skills/firecrawl/base.py +1 -3
  131. intentkit/skills/firecrawl/clear.py +1 -2
  132. intentkit/skills/firecrawl/crawl.py +9 -10
  133. intentkit/skills/firecrawl/query.py +1 -2
  134. intentkit/skills/firecrawl/scrape.py +7 -8
  135. intentkit/skills/firecrawl/utils.py +13 -13
  136. intentkit/skills/github/base.py +1 -3
  137. intentkit/skills/github/github_search.py +1 -2
  138. intentkit/skills/heurist/base.py +1 -3
  139. intentkit/skills/heurist/image_generation_animagine_xl.py +7 -8
  140. intentkit/skills/heurist/image_generation_arthemy_comics.py +7 -8
  141. intentkit/skills/heurist/image_generation_arthemy_real.py +7 -8
  142. intentkit/skills/heurist/image_generation_braindance.py +7 -8
  143. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +7 -8
  144. intentkit/skills/heurist/image_generation_flux_1_dev.py +7 -8
  145. intentkit/skills/heurist/image_generation_sdxl.py +7 -8
  146. intentkit/skills/http/base.py +1 -3
  147. intentkit/skills/http/get.py +7 -7
  148. intentkit/skills/http/post.py +9 -9
  149. intentkit/skills/http/put.py +9 -9
  150. intentkit/skills/lifi/__init__.py +4 -4
  151. intentkit/skills/lifi/base.py +1 -3
  152. intentkit/skills/lifi/token_execute.py +13 -13
  153. intentkit/skills/lifi/token_quote.py +6 -6
  154. intentkit/skills/lifi/utils.py +16 -16
  155. intentkit/skills/moralis/__init__.py +3 -3
  156. intentkit/skills/moralis/api.py +6 -7
  157. intentkit/skills/moralis/base.py +2 -4
  158. intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
  159. intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
  160. intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
  161. intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
  162. intentkit/skills/morpho/__init__.py +4 -6
  163. intentkit/skills/nation/__init__.py +2 -2
  164. intentkit/skills/nation/base.py +1 -3
  165. intentkit/skills/nation/nft_check.py +3 -4
  166. intentkit/skills/onchain.py +2 -6
  167. intentkit/skills/openai/base.py +1 -3
  168. intentkit/skills/openai/dalle_image_generation.py +1 -3
  169. intentkit/skills/openai/gpt_image_generation.py +2 -3
  170. intentkit/skills/openai/gpt_image_to_image.py +2 -3
  171. intentkit/skills/openai/image_to_text.py +1 -2
  172. intentkit/skills/portfolio/base.py +6 -6
  173. intentkit/skills/portfolio/token_balances.py +21 -21
  174. intentkit/skills/portfolio/wallet_approvals.py +7 -7
  175. intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
  176. intentkit/skills/portfolio/wallet_history.py +21 -21
  177. intentkit/skills/portfolio/wallet_net_worth.py +13 -13
  178. intentkit/skills/portfolio/wallet_nfts.py +19 -19
  179. intentkit/skills/portfolio/wallet_profitability.py +7 -7
  180. intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
  181. intentkit/skills/portfolio/wallet_stats.py +3 -3
  182. intentkit/skills/portfolio/wallet_swaps.py +19 -19
  183. intentkit/skills/pyth/__init__.py +3 -5
  184. intentkit/skills/slack/base.py +2 -4
  185. intentkit/skills/slack/get_channel.py +8 -8
  186. intentkit/skills/slack/get_message.py +9 -9
  187. intentkit/skills/slack/schedule_message.py +5 -5
  188. intentkit/skills/slack/send_message.py +3 -5
  189. intentkit/skills/supabase/base.py +1 -3
  190. intentkit/skills/supabase/delete_data.py +4 -4
  191. intentkit/skills/supabase/fetch_data.py +12 -12
  192. intentkit/skills/supabase/insert_data.py +4 -4
  193. intentkit/skills/supabase/invoke_function.py +6 -6
  194. intentkit/skills/supabase/update_data.py +6 -6
  195. intentkit/skills/supabase/upsert_data.py +4 -4
  196. intentkit/skills/superfluid/__init__.py +4 -6
  197. intentkit/skills/system/add_autonomous_task.py +8 -10
  198. intentkit/skills/system/edit_autonomous_task.py +12 -14
  199. intentkit/skills/system/list_autonomous_tasks.py +1 -3
  200. intentkit/skills/tavily/base.py +1 -3
  201. intentkit/skills/tavily/tavily_extract.py +1 -2
  202. intentkit/skills/tavily/tavily_search.py +1 -3
  203. intentkit/skills/token/base.py +5 -5
  204. intentkit/skills/token/erc20_transfers.py +19 -19
  205. intentkit/skills/token/token_analytics.py +3 -3
  206. intentkit/skills/token/token_price.py +13 -13
  207. intentkit/skills/token/token_search.py +9 -9
  208. intentkit/skills/twitter/base.py +3 -4
  209. intentkit/skills/twitter/follow_user.py +1 -2
  210. intentkit/skills/twitter/get_mentions.py +3 -4
  211. intentkit/skills/twitter/get_timeline.py +1 -2
  212. intentkit/skills/twitter/get_user_by_username.py +1 -2
  213. intentkit/skills/twitter/get_user_tweets.py +2 -3
  214. intentkit/skills/twitter/like_tweet.py +1 -2
  215. intentkit/skills/twitter/post_tweet.py +3 -4
  216. intentkit/skills/twitter/reply_tweet.py +3 -4
  217. intentkit/skills/twitter/retweet.py +1 -2
  218. intentkit/skills/twitter/search_tweets.py +1 -2
  219. intentkit/skills/unrealspeech/base.py +1 -3
  220. intentkit/skills/unrealspeech/text_to_speech.py +8 -8
  221. intentkit/skills/venice_audio/__init__.py +8 -9
  222. intentkit/skills/venice_audio/base.py +3 -4
  223. intentkit/skills/venice_audio/input.py +41 -41
  224. intentkit/skills/venice_audio/venice_audio.py +6 -6
  225. intentkit/skills/venice_image/__init__.py +5 -5
  226. intentkit/skills/venice_image/api.py +138 -138
  227. intentkit/skills/venice_image/base.py +3 -3
  228. intentkit/skills/venice_image/config.py +33 -35
  229. intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
  230. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
  231. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
  232. intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
  233. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
  234. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
  235. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
  236. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
  237. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
  238. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
  239. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
  240. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
  241. intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
  242. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
  243. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
  244. intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
  245. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
  246. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
  247. intentkit/skills/venice_image/utils.py +77 -78
  248. intentkit/skills/web_scraper/base.py +1 -3
  249. intentkit/skills/web_scraper/document_indexer.py +1 -2
  250. intentkit/skills/web_scraper/scrape_and_index.py +4 -5
  251. intentkit/skills/web_scraper/utils.py +25 -26
  252. intentkit/skills/web_scraper/website_indexer.py +10 -11
  253. intentkit/skills/weth/__init__.py +4 -6
  254. intentkit/skills/wow/__init__.py +4 -6
  255. intentkit/skills/x402/__init__.py +11 -3
  256. intentkit/skills/x402/ask_agent.py +12 -78
  257. intentkit/skills/x402/base.py +90 -0
  258. intentkit/skills/x402/http_request.py +117 -0
  259. intentkit/skills/x402/schema.json +15 -10
  260. intentkit/skills/xmtp/base.py +3 -3
  261. intentkit/skills/xmtp/price.py +2 -2
  262. intentkit/skills/xmtp/swap.py +2 -4
  263. intentkit/skills/xmtp/transfer.py +4 -6
  264. intentkit/utils/error.py +2 -2
  265. intentkit/utils/logging.py +2 -4
  266. intentkit/utils/s3.py +8 -9
  267. intentkit/utils/schema.py +5 -5
  268. intentkit/utils/slack_alert.py +7 -8
  269. {intentkit-0.8.16.dev1.dist-info → intentkit-0.8.17.dev2.dist-info}/METADATA +3 -4
  270. intentkit-0.8.17.dev2.dist-info/RECORD +464 -0
  271. intentkit/models/generator.py +0 -347
  272. intentkit-0.8.16.dev1.dist-info/RECORD +0 -464
  273. {intentkit-0.8.16.dev1.dist-info → intentkit-0.8.17.dev2.dist-info}/WHEEL +0 -0
  274. {intentkit-0.8.16.dev1.dist-info → intentkit-0.8.17.dev2.dist-info}/licenses/LICENSE +0 -0
intentkit/__init__.py CHANGED
@@ -3,7 +3,7 @@
3
3
  A powerful platform for building AI agents with blockchain and cryptocurrency capabilities.
4
4
  """
5
5
 
6
- __version__ = "0.8.16-dev1"
6
+ __version__ = "0.8.17-dev2"
7
7
  __author__ = "hyacinthus"
8
8
  __email__ = "hyacinthus@gmail.com"
9
9
 
@@ -1,5 +1,4 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Dict, Optional
3
2
 
4
3
  from intentkit.models.agent import Agent
5
4
  from intentkit.models.agent_data import AgentData, AgentQuota
@@ -24,7 +23,7 @@ class AgentStoreABC(ABC):
24
23
  self.agent_id = agent_id
25
24
 
26
25
  @abstractmethod
27
- async def get_config(self) -> Optional[Agent]:
26
+ async def get_config(self) -> Agent | None:
28
27
  """Get agent configuration.
29
28
 
30
29
  Returns:
@@ -33,7 +32,7 @@ class AgentStoreABC(ABC):
33
32
  pass
34
33
 
35
34
  @abstractmethod
36
- async def get_data(self) -> Optional[AgentData]:
35
+ async def get_data(self) -> AgentData | None:
37
36
  """Get additional agent data.
38
37
 
39
38
  Returns:
@@ -42,7 +41,7 @@ class AgentStoreABC(ABC):
42
41
  pass
43
42
 
44
43
  @abstractmethod
45
- async def set_data(self, data: Dict) -> None:
44
+ async def set_data(self, data: dict) -> None:
46
45
  """Update agent data.
47
46
 
48
47
  Args:
@@ -51,7 +50,7 @@ class AgentStoreABC(ABC):
51
50
  pass
52
51
 
53
52
  @abstractmethod
54
- async def get_quota(self) -> Optional[AgentQuota]:
53
+ async def get_quota(self) -> AgentQuota | None:
55
54
  """Get agent quota information.
56
55
 
57
56
  Returns:
@@ -1,4 +1,4 @@
1
- from typing import Callable, List
1
+ from collections.abc import Callable
2
2
 
3
3
  from pydantic import BaseModel
4
4
 
@@ -12,19 +12,19 @@ class AgentMessageInput(BaseModel):
12
12
 
13
13
  Attributes:
14
14
  text (str): The main text content of the message or query
15
- images (List[str]): List of image references/URLs to be processed by the agent.
15
+ images (list[str]): List of image references/URLs to be processed by the agent.
16
16
  Empty list if no images are provided.
17
17
  """
18
18
 
19
19
  text: str # required
20
20
  """The main text content or query to be processed by the agent"""
21
21
 
22
- images: List[str] = [] # optional, defaults to empty list
22
+ images: list[str] = [] # optional, defaults to empty list
23
23
  """List of image references or URLs for multimodal processing"""
24
24
 
25
25
 
26
26
  # Define a type hint for the callback that takes three strings and returns a list of strings
27
- AgentExecutionCallback = Callable[[str, AgentMessageInput, str], List[str]]
27
+ AgentExecutionCallback = Callable[[str, AgentMessageInput, str], list[str]]
28
28
  """Callback function type for agent execution.
29
29
 
30
30
  Args:
@@ -33,6 +33,6 @@ Args:
33
33
  thread_id (str): The thread ID for tracking the conversation context
34
34
 
35
35
  Returns:
36
- List[str]: A list of formatted response lines from the agent execution. Each line
36
+ list[str]: A list of formatted response lines from the agent execution. Each line
37
37
  typically contains input/output markers, agent responses, and timing information.
38
38
  """
@@ -1,5 +1,6 @@
1
+ from collections.abc import Callable
1
2
  from enum import Enum
2
- from typing import Any, Callable, Dict, NotRequired, Optional
3
+ from typing import Any, NotRequired
3
4
 
4
5
  from langgraph.prebuilt.chat_agent_executor import AgentState as BaseAgentState
5
6
  from pydantic import BaseModel
@@ -23,20 +24,20 @@ class AgentState(BaseAgentState):
23
24
 
24
25
  context: dict[str, Any]
25
26
  error: NotRequired[AgentError]
26
- __extra__: NotRequired[Dict[str, Any]]
27
+ __extra__: NotRequired[dict[str, Any]]
27
28
 
28
29
 
29
30
  class AgentContext(BaseModel):
30
31
  agent_id: str
31
32
  get_agent: Callable[[], Agent]
32
33
  chat_id: str
33
- user_id: Optional[str] = None
34
- app_id: Optional[str] = None
34
+ user_id: str | None = None
35
+ app_id: str | None = None
35
36
  entrypoint: AuthorType
36
37
  is_private: bool
37
38
  search: bool = False
38
39
  thinking: bool = False
39
- payer: Optional[str] = None
40
+ payer: str | None = None
40
41
 
41
42
  @property
42
43
  def agent(self) -> Agent:
@@ -1,5 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Any, Dict, Optional
2
+ from typing import Any
3
3
 
4
4
  from intentkit.models.agent import Agent
5
5
  from intentkit.models.agent_data import AgentData, AgentQuota
@@ -20,7 +20,7 @@ class SkillStoreABC(ABC):
20
20
 
21
21
  @staticmethod
22
22
  @abstractmethod
23
- async def get_agent_config(agent_id: str) -> Optional[Agent]:
23
+ async def get_agent_config(agent_id: str) -> Agent | None:
24
24
  """Get agent configuration.
25
25
 
26
26
  Returns:
@@ -30,7 +30,7 @@ class SkillStoreABC(ABC):
30
30
 
31
31
  @staticmethod
32
32
  @abstractmethod
33
- async def get_agent_data(agent_id: str) -> Optional[AgentData]:
33
+ async def get_agent_data(agent_id: str) -> AgentData | None:
34
34
  """Get additional agent data.
35
35
 
36
36
  Returns:
@@ -40,7 +40,7 @@ class SkillStoreABC(ABC):
40
40
 
41
41
  @staticmethod
42
42
  @abstractmethod
43
- async def set_agent_data(agent_id: str, data: Dict) -> None:
43
+ async def set_agent_data(agent_id: str, data: dict) -> None:
44
44
  """Update agent data.
45
45
 
46
46
  Args:
@@ -51,7 +51,7 @@ class SkillStoreABC(ABC):
51
51
 
52
52
  @staticmethod
53
53
  @abstractmethod
54
- async def get_agent_quota(agent_id: str) -> Optional[AgentQuota]:
54
+ async def get_agent_quota(agent_id: str) -> AgentQuota | None:
55
55
  """Get agent quota information.
56
56
 
57
57
  Returns:
@@ -1,5 +1,4 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Optional
3
2
 
4
3
  from tweepy.asynchronous import AsyncClient
5
4
 
@@ -15,7 +14,7 @@ class TwitterABC(ABC):
15
14
  use_key = False
16
15
 
17
16
  @abstractmethod
18
- async def get_client(self) -> Optional[AsyncClient]:
17
+ async def get_client(self) -> AsyncClient | None:
19
18
  """Get a configured Tweepy client.
20
19
 
21
20
  Returns:
@@ -25,7 +24,7 @@ class TwitterABC(ABC):
25
24
 
26
25
  @property
27
26
  @abstractmethod
28
- def self_id(self) -> Optional[str]:
27
+ def self_id(self) -> str | None:
29
28
  """Get the Twitter user ID.
30
29
 
31
30
  Returns:
@@ -35,7 +34,7 @@ class TwitterABC(ABC):
35
34
 
36
35
  @property
37
36
  @abstractmethod
38
- def self_username(self) -> Optional[str]:
37
+ def self_username(self) -> str | None:
39
38
  """Get the Twitter username.
40
39
 
41
40
  Returns:
@@ -45,7 +44,7 @@ class TwitterABC(ABC):
45
44
 
46
45
  @property
47
46
  @abstractmethod
48
- def self_name(self) -> Optional[str]:
47
+ def self_name(self) -> str | None:
49
48
  """Get the Twitter display name.
50
49
 
51
50
  Returns:
intentkit/clients/cdp.py CHANGED
@@ -1,16 +1,11 @@
1
1
  import asyncio
2
- import json
3
2
  import logging
4
- from typing import Dict, Optional, Tuple
5
3
 
6
- from bip32 import BIP32
7
4
  from cdp import CdpClient, EvmServerAccount # noqa: E402
8
5
  from coinbase_agentkit import ( # noqa: E402
9
6
  CdpEvmWalletProvider,
10
7
  CdpEvmWalletProviderConfig,
11
8
  )
12
- from eth_keys.datatypes import PrivateKey
13
- from eth_utils import to_checksum_address
14
9
 
15
10
  from intentkit.config.config import config
16
11
  from intentkit.models.agent import Agent, AgentTable # noqa: E402
@@ -18,47 +13,12 @@ from intentkit.models.agent_data import AgentData
18
13
  from intentkit.models.db import get_session
19
14
  from intentkit.utils.error import IntentKitAPIError # noqa: E402
20
15
 
21
- _wallet_providers: Dict[str, Tuple[str, str, CdpEvmWalletProvider]] = {}
22
- _cdp_client: Optional[CdpClient] = None
16
+ _wallet_providers: dict[str, tuple[str, str, CdpEvmWalletProvider]] = {}
17
+ _cdp_client: CdpClient | None = None
23
18
 
24
19
  logger = logging.getLogger(__name__)
25
20
 
26
21
 
27
- def bip39_seed_to_eth_keys(seed_hex: str) -> Dict[str, str]:
28
- """
29
- Converts a BIP39 seed to an Ethereum private key, public key, and address.
30
-
31
- Args:
32
- seed_hex: The BIP39 seed in hexadecimal format
33
-
34
- Returns:
35
- Dict containing private_key, public_key, and address
36
- """
37
- # Convert the hex seed to bytes
38
- seed_bytes = bytes.fromhex(seed_hex)
39
-
40
- # Derive the master key from the seed
41
- bip32 = BIP32.from_seed(seed_bytes)
42
-
43
- # Derive the Ethereum address using the standard derivation path
44
- private_key_bytes = bip32.get_privkey_from_path("m/44'/60'/0'/0/0")
45
-
46
- # Create a private key object
47
- private_key = PrivateKey(private_key_bytes)
48
-
49
- # Get the public key
50
- public_key = private_key.public_key
51
-
52
- # Get the Ethereum address
53
- address = public_key.to_address()
54
-
55
- return {
56
- "private_key": private_key.to_hex(),
57
- "public_key": public_key.to_hex(),
58
- "address": to_checksum_address(address),
59
- }
60
-
61
-
62
22
  def get_cdp_client() -> CdpClient:
63
23
  global _cdp_client
64
24
  if _cdp_client:
@@ -88,46 +48,28 @@ def _assert_cdp_wallet_provider(agent: Agent) -> None:
88
48
 
89
49
  async def _ensure_evm_account(
90
50
  agent: Agent, agent_data: AgentData | None = None
91
- ) -> Tuple[EvmServerAccount, AgentData]:
51
+ ) -> tuple[EvmServerAccount, AgentData]:
92
52
  cdp_client = get_cdp_client()
93
53
  agent_data = agent_data or await AgentData.get(agent.id)
94
54
  address = agent_data.evm_wallet_address
95
- account: Optional[EvmServerAccount] = None
55
+ account: EvmServerAccount | None = None
96
56
 
97
57
  if not address:
98
- if agent_data.cdp_wallet_data:
99
- wallet_data = json.loads(agent_data.cdp_wallet_data)
100
- if not isinstance(wallet_data, dict):
101
- raise ValueError("Invalid wallet data format")
102
- if wallet_data.get("default_address_id") and wallet_data.get("seed"):
103
- keys = bip39_seed_to_eth_keys(wallet_data["seed"])
104
- if keys["address"] != wallet_data["default_address_id"]:
105
- raise ValueError(
106
- "Bad wallet data, seed does not match default_address_id"
107
- )
108
- logger.info("Migrating wallet data to v2...")
109
- account = await cdp_client.evm.import_account(
110
- name=agent.id,
111
- private_key=keys["private_key"],
112
- )
113
- address = account.address
114
- logger.info("Migrated wallet data to v2 successfully: %s", address)
115
- if not address:
116
- logger.info("Creating new wallet...")
117
- account = await cdp_client.evm.create_account(
118
- name=agent.id,
119
- )
120
- address = account.address
121
- logger.info("Created new wallet: %s", address)
122
-
123
- agent_data.evm_wallet_address = address
124
- await agent_data.save()
125
- if not agent.slug:
126
- async with get_session() as db:
127
- db_agent = await db.get(AgentTable, agent.id)
128
- if db_agent and not db_agent.slug:
129
- db_agent.slug = agent_data.evm_wallet_address
130
- await db.commit()
58
+ logger.info("Creating new wallet...")
59
+ account = await cdp_client.evm.create_account(
60
+ name=agent.id,
61
+ )
62
+ address = account.address
63
+ logger.info("Created new wallet: %s", address)
64
+
65
+ agent_data.evm_wallet_address = address
66
+ await agent_data.save()
67
+ if not agent.slug:
68
+ async with get_session() as db:
69
+ db_agent = await db.get(AgentTable, agent.id)
70
+ if db_agent and not db_agent.slug:
71
+ db_agent.slug = agent_data.evm_wallet_address
72
+ await db.commit()
131
73
 
132
74
  if account is None:
133
75
  account = await cdp_client.evm.get_account(address=address)
@@ -1,8 +1,8 @@
1
1
  import logging
2
2
  import os
3
3
  import tempfile
4
- from datetime import datetime, timedelta, timezone
5
- from typing import Any, Dict, List, NotRequired, Optional, TypedDict
4
+ from datetime import UTC, datetime, timedelta
5
+ from typing import Any, NotRequired, TypedDict
6
6
  from urllib.parse import urlencode
7
7
 
8
8
  import httpx
@@ -17,8 +17,8 @@ from intentkit.models.redis import get_redis
17
17
 
18
18
  logger = logging.getLogger(__name__)
19
19
 
20
- _clients_linked: Dict[str, "TwitterClient"] = {}
21
- _clients_self_key: Dict[str, "TwitterClient"] = {}
20
+ _clients_linked: dict[str, "TwitterClient"] = {}
21
+ _clients_self_key: dict[str, "TwitterClient"] = {}
22
22
 
23
23
  _VERIFIER_KEY = "intentkit:twitter:code_verifier"
24
24
  _CHALLENGE_KEY = "intentkit:twitter:code_challenge"
@@ -29,7 +29,7 @@ class TwitterMedia(BaseModel):
29
29
 
30
30
  media_key: str
31
31
  type: str
32
- url: Optional[str] = None
32
+ url: str | None = None
33
33
 
34
34
 
35
35
  class TwitterUser(BaseModel):
@@ -58,10 +58,10 @@ class Tweet(BaseModel):
58
58
  id: str
59
59
  text: str
60
60
  author_id: str
61
- author: Optional[TwitterUser] = None
61
+ author: TwitterUser | None = None
62
62
  created_at: datetime
63
- referenced_tweets: Optional[List["Tweet"]] = None
64
- attachments: Optional[List[TwitterMedia]] = None
63
+ referenced_tweets: list["Tweet"] | None = None
64
+ attachments: list[TwitterMedia] | None = None
65
65
 
66
66
 
67
67
  class TwitterClientConfig(TypedDict):
@@ -82,7 +82,7 @@ class TwitterClient(TwitterABC):
82
82
  config: Configuration dictionary that may contain API keys
83
83
  """
84
84
 
85
- def __init__(self, agent_id: str, config: Dict) -> None:
85
+ def __init__(self, agent_id: str, config: dict) -> None:
86
86
  """Initialize the Twitter client.
87
87
 
88
88
  Args:
@@ -90,8 +90,8 @@ class TwitterClient(TwitterABC):
90
90
  config: Configuration dictionary that may contain API keys
91
91
  """
92
92
  self.agent_id = agent_id
93
- self._client: Optional[AsyncClient] = None
94
- self._agent_data: Optional[AgentData] = None
93
+ self._client: AsyncClient | None = None
94
+ self._agent_data: AgentData | None = None
95
95
  self.use_key = _is_self_key(config)
96
96
  self._config = config
97
97
 
@@ -130,7 +130,7 @@ class TwitterClient(TwitterABC):
130
130
  # refresh userinfo if needed
131
131
  if not agent_data.twitter_self_key_refreshed_at or (
132
132
  agent_data.twitter_self_key_refreshed_at
133
- < datetime.now(tz=timezone.utc) - timedelta(days=1)
133
+ < datetime.now(tz=UTC) - timedelta(days=1)
134
134
  ):
135
135
  me = await self._client.get_me(
136
136
  user_auth=self.use_key,
@@ -144,9 +144,7 @@ class TwitterClient(TwitterABC):
144
144
  "twitter_username": me["data"]["username"],
145
145
  "twitter_name": me["data"]["name"],
146
146
  "twitter_is_verified": me["data"]["verified"],
147
- "twitter_self_key_refreshed_at": datetime.now(
148
- tz=timezone.utc
149
- ),
147
+ "twitter_self_key_refreshed_at": datetime.now(tz=UTC),
150
148
  },
151
149
  )
152
150
  agent_data = await self._refresh_agent_data()
@@ -166,9 +164,7 @@ class TwitterClient(TwitterABC):
166
164
  raise Exception(
167
165
  f"[{self.agent_id}] Twitter access token expiration not found"
168
166
  )
169
- if agent_data.twitter_access_token_expires_at <= datetime.now(
170
- tz=timezone.utc
171
- ):
167
+ if agent_data.twitter_access_token_expires_at <= datetime.now(tz=UTC):
172
168
  raise Exception(f"[{self.agent_id}] Twitter access token has expired")
173
169
  self._client = AsyncClient(
174
170
  bearer_token=agent_data.twitter_access_token,
@@ -178,13 +174,9 @@ class TwitterClient(TwitterABC):
178
174
 
179
175
  if not self.use_key:
180
176
  # check if access token has expired
181
- if agent_data.twitter_access_token_expires_at <= datetime.now(
182
- tz=timezone.utc
183
- ):
177
+ if agent_data.twitter_access_token_expires_at <= datetime.now(tz=UTC):
184
178
  agent_data = await self._refresh_agent_data()
185
- if agent_data.twitter_access_token_expires_at <= datetime.now(
186
- tz=timezone.utc
187
- ):
179
+ if agent_data.twitter_access_token_expires_at <= datetime.now(tz=UTC):
188
180
  raise Exception(
189
181
  f"[{self.agent_id}] Twitter access token has expired"
190
182
  )
@@ -197,7 +189,7 @@ class TwitterClient(TwitterABC):
197
189
  return self._client
198
190
 
199
191
  @property
200
- def self_id(self) -> Optional[str]:
192
+ def self_id(self) -> str | None:
201
193
  """Get the Twitter user ID.
202
194
 
203
195
  Returns:
@@ -210,7 +202,7 @@ class TwitterClient(TwitterABC):
210
202
  return self._agent_data.twitter_id
211
203
 
212
204
  @property
213
- def self_username(self) -> Optional[str]:
205
+ def self_username(self) -> str | None:
214
206
  """Get the Twitter username.
215
207
 
216
208
  Returns:
@@ -223,7 +215,7 @@ class TwitterClient(TwitterABC):
223
215
  return self._agent_data.twitter_username
224
216
 
225
217
  @property
226
- def self_name(self) -> Optional[str]:
218
+ def self_name(self) -> str | None:
227
219
  """Get the Twitter display name.
228
220
 
229
221
  Returns:
@@ -236,7 +228,7 @@ class TwitterClient(TwitterABC):
236
228
  return self._agent_data.twitter_name
237
229
 
238
230
  @property
239
- def self_is_verified(self) -> Optional[bool]:
231
+ def self_is_verified(self) -> bool | None:
240
232
  """Get the Twitter account verification status.
241
233
 
242
234
  Returns:
@@ -248,14 +240,14 @@ class TwitterClient(TwitterABC):
248
240
  return None
249
241
  return self._agent_data.twitter_is_verified
250
242
 
251
- def process_tweets_response(self, response: Dict[str, Any]) -> List[Tweet]:
243
+ def process_tweets_response(self, response: dict[str, Any]) -> list[Tweet]:
252
244
  """Process Twitter API response and convert it to a list of Tweet objects.
253
245
 
254
246
  Args:
255
247
  response: Raw Twitter API response containing tweets data and includes.
256
248
 
257
249
  Returns:
258
- List[Tweet]: List of processed Tweet objects.
250
+ list[Tweet]: List of processed Tweet objects.
259
251
  """
260
252
  result = []
261
253
  if not response.get("data"):
@@ -347,7 +339,7 @@ class TwitterClient(TwitterABC):
347
339
 
348
340
  return result
349
341
 
350
- async def upload_media(self, agent_id: str, image_url: str) -> List[str]:
342
+ async def upload_media(self, agent_id: str, image_url: str) -> list[str]:
351
343
  """Upload media to Twitter and return the media IDs.
352
344
 
353
345
  Args:
@@ -355,7 +347,7 @@ class TwitterClient(TwitterABC):
355
347
  image_url: The URL of the image to upload.
356
348
 
357
349
  Returns:
358
- List[str]: A list of media IDs for the uploaded media.
350
+ list[str]: A list of media IDs for the uploaded media.
359
351
 
360
352
  Raises:
361
353
  ValueError: If there's an error uploading the media.
@@ -428,11 +420,11 @@ class TwitterClient(TwitterABC):
428
420
  return media_ids
429
421
 
430
422
 
431
- def _is_self_key(config: Dict) -> bool:
423
+ def _is_self_key(config: dict) -> bool:
432
424
  return config.get("api_key_provider") == "agent_owner"
433
425
 
434
426
 
435
- def get_twitter_client(agent_id: str, config: Dict) -> "TwitterClient":
427
+ def get_twitter_client(agent_id: str, config: dict) -> "TwitterClient":
436
428
  if _is_self_key(config):
437
429
  if agent_id not in _clients_self_key:
438
430
  _clients_self_key[agent_id] = TwitterClient(agent_id, config)
intentkit/clients/web3.py CHANGED
@@ -1,12 +1,10 @@
1
- from typing import Dict
2
-
3
1
  from web3 import Web3
4
2
 
5
3
  from intentkit.config.config import config
6
4
  from intentkit.utils.chain import ChainProvider
7
5
 
8
6
  # Global cache for Web3 clients by network_id
9
- _web3_client_cache: Dict[str, Web3] = {}
7
+ _web3_client_cache: dict[str, Web3] = {}
10
8
 
11
9
 
12
10
  def get_web3_client(network_id: str) -> Web3:
@@ -109,6 +109,10 @@ class Config:
109
109
  self.tg_server_host = self.load("TG_SERVER_HOST", "127.0.0.1")
110
110
  self.tg_server_port = self.load("TG_SERVER_PORT", "8081")
111
111
  self.tg_new_agent_poll_interval = self.load("TG_NEW_AGENT_POLL_INTERVAL", "60")
112
+ # Discord server settings
113
+ self.discord_new_agent_poll_interval = self.load(
114
+ "DISCORD_NEW_AGENT_POLL_INTERVAL", "30"
115
+ )
112
116
  # Twitter
113
117
  self.twitter_oauth2_client_id = self.load("TWITTER_OAUTH2_CLIENT_ID")
114
118
  self.twitter_oauth2_client_secret = self.load("TWITTER_OAUTH2_CLIENT_SECRET")
intentkit/core/agent.py CHANGED
@@ -1,8 +1,8 @@
1
1
  import logging
2
2
  import time
3
- from datetime import datetime, timedelta, timezone
3
+ from collections.abc import AsyncGenerator
4
+ from datetime import UTC, datetime, timedelta
4
5
  from decimal import Decimal
5
- from typing import AsyncGenerator, Dict, Optional, Tuple
6
6
 
7
7
  from sqlalchemy import func, select, text, update
8
8
 
@@ -193,8 +193,8 @@ def send_agent_notification(agent: Agent, agent_data: AgentData, message: str) -
193
193
 
194
194
 
195
195
  async def override_agent(
196
- agent_id: str, agent: AgentUpdate, owner: Optional[str] = None
197
- ) -> Tuple[Agent, AgentData]:
196
+ agent_id: str, agent: AgentUpdate, owner: str | None = None
197
+ ) -> tuple[Agent, AgentData]:
198
198
  """Override an existing agent with new configuration.
199
199
 
200
200
  This function updates an existing agent with the provided configuration.
@@ -234,7 +234,7 @@ async def override_agent(
234
234
  return latest_agent, agent_data
235
235
 
236
236
 
237
- async def create_agent(agent: AgentCreate) -> Tuple[Agent, AgentData]:
237
+ async def create_agent(agent: AgentCreate) -> tuple[Agent, AgentData]:
238
238
  """Create a new agent with the provided configuration.
239
239
 
240
240
  This function creates a new agent instance with the given configuration,
@@ -271,8 +271,8 @@ async def create_agent(agent: AgentCreate) -> Tuple[Agent, AgentData]:
271
271
 
272
272
 
273
273
  async def deploy_agent(
274
- agent_id: str, agent: AgentUpdate, owner: Optional[str] = None
275
- ) -> Tuple[Agent, AgentData]:
274
+ agent_id: str, agent: AgentUpdate, owner: str | None = None
275
+ ) -> tuple[Agent, AgentData]:
276
276
  """Deploy an agent by first attempting to override, then creating if not found.
277
277
 
278
278
  This function first tries to override an existing agent. If the agent is not found
@@ -307,7 +307,7 @@ async def deploy_agent(
307
307
  raise
308
308
 
309
309
 
310
- async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
310
+ async def agent_action_cost(agent_id: str) -> dict[str, Decimal]:
311
311
  """
312
312
  Calculate various action cost metrics for an agent based on past three days of credit events.
313
313
 
@@ -323,7 +323,7 @@ async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
323
323
  agent_id: ID of the agent
324
324
 
325
325
  Returns:
326
- Dict[str, Decimal]: Dictionary containing all calculated cost metrics
326
+ dict[str, Decimal]: Dictionary containing all calculated cost metrics
327
327
  """
328
328
  start_time = time.time()
329
329
  default_value = Decimal("0")
@@ -336,7 +336,7 @@ async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
336
336
 
337
337
  async with get_session() as session:
338
338
  # Calculate the date 3 days ago from now
339
- three_days_ago = datetime.now(timezone.utc) - timedelta(days=3)
339
+ three_days_ago = datetime.now(UTC) - timedelta(days=3)
340
340
 
341
341
  # First, count the number of distinct start_message_ids to determine if we have enough data
342
342
  count_query = select(
@@ -489,7 +489,7 @@ async def _iterate_agent_id_batches(
489
489
  ) -> AsyncGenerator[list[str], None]:
490
490
  """Yield agent IDs in ascending batches to limit memory usage."""
491
491
 
492
- last_id: Optional[str] = None
492
+ last_id: str | None = None
493
493
  while True:
494
494
  async with get_session() as session:
495
495
  query = select(AgentTable.id).order_by(AgentTable.id)
@@ -679,18 +679,18 @@ async def update_agents_assets(batch_size: int = 100) -> None:
679
679
 
680
680
 
681
681
  async def update_agents_statistics(
682
- *, end_time: Optional[datetime] = None, batch_size: int = 100
682
+ *, end_time: datetime | None = None, batch_size: int = 100
683
683
  ) -> None:
684
684
  """Refresh cached statistics for every agent."""
685
685
 
686
686
  from intentkit.core.statistics import get_agent_statistics
687
687
 
688
688
  if end_time is None:
689
- end_time = datetime.now(timezone.utc)
689
+ end_time = datetime.now(UTC)
690
690
  elif end_time.tzinfo is None:
691
- end_time = end_time.replace(tzinfo=timezone.utc)
691
+ end_time = end_time.replace(tzinfo=UTC)
692
692
  else:
693
- end_time = end_time.astimezone(timezone.utc)
693
+ end_time = end_time.astimezone(UTC)
694
694
 
695
695
  logger.info("Starting update of agent statistics using end_time %s", end_time)
696
696
  start_time = time.time()
intentkit/core/asset.py CHANGED
@@ -5,7 +5,6 @@ from __future__ import annotations
5
5
  import json
6
6
  import logging
7
7
  from decimal import Decimal
8
- from typing import Optional
9
8
 
10
9
  import httpx
11
10
  from pydantic import BaseModel, Field
@@ -139,7 +138,7 @@ async def _build_assets_list(
139
138
  return assets
140
139
 
141
140
  wallet_address = agent_data.evm_wallet_address
142
- network_id: Optional[str] = agent.network_id
141
+ network_id: str | None = agent.network_id
143
142
 
144
143
  # ETH is always included
145
144
  eth_balance = await _get_eth_balance(web3_client, wallet_address)
intentkit/core/client.py CHANGED
@@ -3,7 +3,7 @@
3
3
  This module provides client functions for core API endpoints with environment-aware routing.
4
4
  """
5
5
 
6
- from typing import AsyncIterator
6
+ from collections.abc import AsyncIterator
7
7
 
8
8
  import httpx
9
9