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
intentkit/core/credit.py CHANGED
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from datetime import datetime
3
3
  from decimal import ROUND_HALF_UP, Decimal
4
- from typing import List, Optional, Tuple
5
4
 
6
5
  from epyxid import XID
7
6
  from pydantic import BaseModel
@@ -50,7 +49,7 @@ FOURPLACES = Decimal("0.0001")
50
49
  async def update_credit_event_note(
51
50
  session: AsyncSession,
52
51
  event_id: str,
53
- note: Optional[str] = None,
52
+ note: str | None = None,
54
53
  ) -> CreditEvent:
55
54
  """
56
55
  Update the note of a credit event.
@@ -89,7 +88,7 @@ async def recharge(
89
88
  user_id: str,
90
89
  amount: Decimal,
91
90
  upstream_tx_id: str,
92
- note: Optional[str] = None,
91
+ note: str | None = None,
93
92
  ) -> CreditAccount:
94
93
  """
95
94
  Recharge credits to a user account.
@@ -220,7 +219,7 @@ async def withdraw(
220
219
  agent_id: str,
221
220
  amount: Decimal,
222
221
  upstream_tx_id: str,
223
- note: Optional[str] = None,
222
+ note: str | None = None,
224
223
  ) -> CreditAccount:
225
224
  """
226
225
  Withdraw credits from an agent account to platform account.
@@ -385,8 +384,8 @@ async def reward(
385
384
  user_id: str,
386
385
  amount: Decimal,
387
386
  upstream_tx_id: str,
388
- note: Optional[str] = None,
389
- reward_type: Optional[RewardType] = RewardType.REWARD,
387
+ note: str | None = None,
388
+ reward_type: RewardType | None = RewardType.REWARD,
390
389
  ) -> CreditAccount:
391
390
  """
392
391
  Reward a user account with reward credits.
@@ -679,8 +678,8 @@ async def adjustment(
679
678
  async def update_daily_quota(
680
679
  session: AsyncSession,
681
680
  user_id: str,
682
- free_quota: Optional[Decimal] = None,
683
- refill_amount: Optional[Decimal] = None,
681
+ free_quota: Decimal | None = None,
682
+ refill_amount: Decimal | None = None,
684
683
  upstream_tx_id: str = "",
685
684
  note: str = "",
686
685
  ) -> CreditAccount:
@@ -706,11 +705,11 @@ async def update_daily_quota(
706
705
  async def list_credit_events_by_user(
707
706
  session: AsyncSession,
708
707
  user_id: str,
709
- direction: Optional[Direction] = None,
710
- cursor: Optional[str] = None,
708
+ direction: Direction | None = None,
709
+ cursor: str | None = None,
711
710
  limit: int = 20,
712
- event_type: Optional[EventType] = None,
713
- ) -> Tuple[List[CreditEvent], Optional[str], bool]:
711
+ event_type: EventType | None = None,
712
+ ) -> tuple[list[CreditEvent], str | None, bool]:
714
713
  """
715
714
  List credit events for a user account with cursor pagination.
716
715
 
@@ -771,13 +770,13 @@ async def list_credit_events_by_user(
771
770
 
772
771
  async def list_credit_events(
773
772
  session: AsyncSession,
774
- direction: Optional[Direction] = Direction.EXPENSE,
775
- cursor: Optional[str] = None,
773
+ direction: Direction | None = Direction.EXPENSE,
774
+ cursor: str | None = None,
776
775
  limit: int = 20,
777
- event_type: Optional[EventType] = None,
778
- start_at: Optional[datetime] = None,
779
- end_at: Optional[datetime] = None,
780
- ) -> Tuple[List[CreditEvent], Optional[str], bool]:
776
+ event_type: EventType | None = None,
777
+ start_at: datetime | None = None,
778
+ end_at: datetime | None = None,
779
+ ) -> tuple[list[CreditEvent], str | None, bool]:
781
780
  """
782
781
  List all credit events with cursor pagination.
783
782
 
@@ -841,9 +840,9 @@ async def list_credit_events(
841
840
  async def list_fee_events_by_agent(
842
841
  session: AsyncSession,
843
842
  agent_id: str,
844
- cursor: Optional[str] = None,
843
+ cursor: str | None = None,
845
844
  limit: int = 20,
846
- ) -> Tuple[List[CreditEvent], Optional[str], bool]:
845
+ ) -> tuple[list[CreditEvent], str | None, bool]:
847
846
  """
848
847
  List fee events for an agent with cursor pagination.
849
848
  These events represent income for the agent from users' expenses.
intentkit/core/engine.py CHANGED
@@ -17,7 +17,6 @@ import textwrap
17
17
  import time
18
18
  import traceback
19
19
  from datetime import datetime
20
- from typing import Optional, Tuple
21
20
 
22
21
  import sqlalchemy
23
22
  from epyxid import XID
@@ -36,7 +35,6 @@ from sqlalchemy.exc import SQLAlchemyError
36
35
 
37
36
  from intentkit.abstracts.graph import AgentContext, AgentError, AgentState
38
37
  from intentkit.config.config import config
39
- from intentkit.core.agent import agent_store
40
38
  from intentkit.core.chat import clear_thread_memory
41
39
  from intentkit.core.credit import expense_message, expense_skill
42
40
  from intentkit.core.node import PreModelNode, post_model_node
@@ -56,13 +54,12 @@ from intentkit.models.chat import (
56
54
  from intentkit.models.credit import CreditAccount, OwnerType
57
55
  from intentkit.models.db import get_langgraph_checkpointer, get_session
58
56
  from intentkit.models.llm import LLMModelInfo, LLMProvider, create_llm_model
59
- from intentkit.models.skill import AgentSkillData, ThreadSkillData
57
+ from intentkit.models.skill import AgentSkillData, ChatSkillData, Skill
60
58
  from intentkit.models.user import User
61
59
  from intentkit.utils.error import IntentKitAPIError
62
60
 
63
61
  logger = logging.getLogger(__name__)
64
62
 
65
-
66
63
  # Global variable to cache all agent executors
67
64
  _agents: dict[str, CompiledStateGraph] = {}
68
65
 
@@ -70,7 +67,9 @@ _agents: dict[str, CompiledStateGraph] = {}
70
67
  _agents_updated: dict[str, datetime] = {}
71
68
 
72
69
 
73
- async def build_agent(agent: Agent, agent_data: AgentData) -> CompiledStateGraph:
70
+ async def build_agent(
71
+ agent: Agent, agent_data: AgentData, custom_skills: list[BaseTool] = []
72
+ ) -> CompiledStateGraph:
74
73
  """Build an AI agent with specified configuration and tools.
75
74
 
76
75
  This function:
@@ -82,7 +81,8 @@ async def build_agent(agent: Agent, agent_data: AgentData) -> CompiledStateGraph
82
81
  Args:
83
82
  agent (Agent): Agent configuration object
84
83
  agent_data (AgentData): Agent data object
85
- is_private (bool, optional): Flag indicating whether the agent is private. Defaults to False.
84
+ custom_skills (list[BaseTool], optional): Designed for advanced user who directly
85
+ call this function to inject custom skills into the agent tool node.
86
86
 
87
87
  Returns:
88
88
  CompiledStateGraph: Initialized LangChain agent
@@ -112,13 +112,13 @@ async def build_agent(agent: Agent, agent_data: AgentData) -> CompiledStateGraph
112
112
  if hasattr(skill_module, "get_skills"):
113
113
  # all
114
114
  skill_tools = await skill_module.get_skills(
115
- v, False, agent_store, agent_id=agent.id, agent=agent
115
+ v, False, agent_id=agent.id, agent=agent
116
116
  )
117
117
  if skill_tools and len(skill_tools) > 0:
118
118
  tools.extend(skill_tools)
119
119
  # private
120
120
  skill_private_tools = await skill_module.get_skills(
121
- v, True, agent_store, agent_id=agent.id, agent=agent
121
+ v, True, agent_id=agent.id, agent=agent
122
122
  )
123
123
  if skill_private_tools and len(skill_private_tools) > 0:
124
124
  private_tools.extend(skill_private_tools)
@@ -127,6 +127,10 @@ async def build_agent(agent: Agent, agent_data: AgentData) -> CompiledStateGraph
127
127
  except ImportError as e:
128
128
  logger.error(f"Could not import skill module: {k} ({e})")
129
129
 
130
+ # add custom skills to private tools
131
+ if custom_skills and len(custom_skills) > 0:
132
+ private_tools.extend(custom_skills)
133
+
130
134
  # filter the duplicate tools
131
135
  tools = list({tool.name: tool for tool in tools}.values())
132
136
  private_tools = list({tool.name: tool for tool in private_tools}.values())
@@ -223,7 +227,7 @@ async def initialize_agent(aid):
223
227
  HTTPException: If agent not found (404) or database error (500)
224
228
  """
225
229
  # get the agent from the database
226
- agent: Optional[Agent] = await Agent.get(aid)
230
+ agent: Agent | None = await Agent.get(aid)
227
231
  if not agent:
228
232
  raise IntentKitAPIError(
229
233
  status_code=404, key="AgentNotFound", message="Agent not found"
@@ -237,7 +241,7 @@ async def initialize_agent(aid):
237
241
  _agents_updated[aid] = agent.deployed_at if agent.deployed_at else agent.updated_at
238
242
 
239
243
 
240
- async def agent_executor(agent_id: str) -> Tuple[CompiledStateGraph, float]:
244
+ async def agent_executor(agent_id: str) -> tuple[CompiledStateGraph, float]:
241
245
  start = time.perf_counter()
242
246
  agent = await Agent.get(agent_id)
243
247
  if not agent:
@@ -293,6 +297,12 @@ async def stream_agent_raw(
293
297
  # save input message first
294
298
  user_message = await message.save()
295
299
 
300
+ # temporary debug logging for telegram messages
301
+ if user_message.author_type == AuthorType.TELEGRAM:
302
+ logger.info(
303
+ f"[TELEGRAM DEBUG] Agent: {user_message.agent_id} | Chat: {user_message.chat_id} | Message: {user_message.message}"
304
+ )
305
+
296
306
  if re.search(
297
307
  r"(@clear|/clear)(?!\w)",
298
308
  user_message.message.strip(),
@@ -320,6 +330,8 @@ async def stream_agent_raw(
320
330
  model = await LLMModelInfo.get(agent.model)
321
331
 
322
332
  payment_enabled = config.payment_enabled
333
+ if user_message.author_type == AuthorType.X402:
334
+ payment_enabled = False
323
335
 
324
336
  # check user balance
325
337
  if payment_enabled:
@@ -690,6 +702,9 @@ async def stream_agent_raw(
690
702
  for skill_call in skill_calls:
691
703
  if not skill_call["success"]:
692
704
  continue
705
+ skill = await Skill.get(skill_call["name"])
706
+ if not skill:
707
+ continue
693
708
  payment_event = await expense_skill(
694
709
  session,
695
710
  payer,
@@ -883,7 +898,7 @@ async def clean_agent_memory(
883
898
 
884
899
  if clean_skill:
885
900
  await AgentSkillData.clean_data(agent_id)
886
- await ThreadSkillData.clean_data(agent_id, chat_id)
901
+ await ChatSkillData.clean_data(agent_id, chat_id)
887
902
 
888
903
  async with get_session() as db:
889
904
  if clean_agent:
intentkit/core/node.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import logging
2
- from typing import Any, Sequence
2
+ from collections.abc import Sequence
3
+ from typing import Any
3
4
 
4
5
  from langchain_core.language_models import LanguageModelLike
5
6
  from langchain_core.messages import (
intentkit/core/prompt.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import re
2
- from typing import Callable, Optional
2
+ from collections.abc import Callable
3
3
 
4
4
  from eth_utils import is_address
5
5
  from langchain_core.messages import BaseMessage
@@ -12,6 +12,7 @@ from intentkit.models.agent import Agent
12
12
  from intentkit.models.agent_data import AgentData
13
13
  from intentkit.models.chat import AuthorType
14
14
  from intentkit.models.skill import Skill
15
+ from intentkit.models.user import User
15
16
 
16
17
  # ============================================================================
17
18
  # CONSTANTS AND CONFIGURATION
@@ -34,7 +35,6 @@ user confirmation before broadcasting any approval transactions for security rea
34
35
 
35
36
  """
36
37
 
37
-
38
38
  # ============================================================================
39
39
  # CORE PROMPT BUILDING FUNCTIONS
40
40
  # ============================================================================
@@ -110,28 +110,66 @@ def _build_wallet_section(agent: Agent, agent_data: AgentData) -> str:
110
110
 
111
111
  if agent_data.evm_wallet_address and network_id != "solana":
112
112
  wallet_parts.append(
113
- f"Your wallet address in {network_id} is {agent_data.evm_wallet_address}."
113
+ f"Your EVM wallet address is {agent_data.evm_wallet_address}."
114
+ f"You are now in {network_id} network."
114
115
  )
115
116
  if agent_data.solana_wallet_address and network_id == "solana":
116
117
  wallet_parts.append(
117
- f"Your wallet address in {network_id} is {agent_data.solana_wallet_address}."
118
+ f"Your Solana wallet address is {agent_data.solana_wallet_address}."
119
+ f"You are now in {network_id} network."
118
120
  )
119
121
 
122
+ # Add CDP skills prompt if CDP skills are enabled
123
+ if agent.skills and "cdp" in agent.skills:
124
+ cdp_config = agent.skills["cdp"]
125
+ if cdp_config and cdp_config.get("enabled") is True:
126
+ # Check if any CDP skills are in public or private state (not disabled)
127
+ states = cdp_config.get("states", {})
128
+ has_enabled_cdp_skills = any(
129
+ state in ["public", "private"] for state in states.values()
130
+ )
131
+ if has_enabled_cdp_skills:
132
+ wallet_parts.append(
133
+ "If a skill input parameter requires a token address but you only have the user-provided token symbol, "
134
+ "and the address cannot be found in the nearby context, you must use the `token_search` skill to query "
135
+ f"the address of that symbol on the current chain ({network_id}) and confirm this address with the user."
136
+ "If the `token_search` skill is not found, remind the user to enable it."
137
+ )
138
+
120
139
  return "\n".join(wallet_parts) + ("\n" if wallet_parts else "")
121
140
 
122
141
 
123
- def _build_user_info_section(context: AgentContext) -> str:
142
+ async def _build_user_info_section(context: AgentContext) -> str:
124
143
  """Build user information section when user_id is a valid EVM wallet address."""
125
144
  if not context.user_id:
126
145
  return ""
127
146
 
128
- # Check if user_id is a valid EVM wallet address
129
- try:
130
- if is_address(context.user_id):
131
- return f"## User Info\n\nThe person you are talking to has wallet address: {context.user_id}\n\n"
132
- except Exception:
133
- # If validation fails, don't include the section
134
- pass
147
+ user = await User.get(context.user_id)
148
+
149
+ prompt_array = []
150
+
151
+ evm_wallet_address = ""
152
+ if user and user.evm_wallet_address:
153
+ evm_wallet_address = user.evm_wallet_address
154
+ elif is_address(context.user_id):
155
+ evm_wallet_address = context.user_id
156
+
157
+ if evm_wallet_address:
158
+ prompt_array.append(
159
+ f"The user you are talking to has EVM wallet address: {evm_wallet_address}\n"
160
+ )
161
+
162
+ if user:
163
+ if user.email:
164
+ prompt_array.append(f"User Email: {user.email}\n")
165
+ if user.x_username:
166
+ prompt_array.append(f"User X Username: {user.x_username}\n")
167
+ if user.telegram_username:
168
+ prompt_array.append(f"User Telegram Username: {user.telegram_username}\n")
169
+
170
+ if prompt_array:
171
+ prompt_array.append("\n")
172
+ return "## User Info\n\n" + "".join(prompt_array)
135
173
 
136
174
  return ""
137
175
 
@@ -289,7 +327,7 @@ def _build_autonomous_task_prompt(agent: Agent, context: AgentContext) -> str:
289
327
  return f"{task_info}. "
290
328
 
291
329
 
292
- async def build_entrypoint_prompt(agent: Agent, context: AgentContext) -> Optional[str]:
330
+ async def build_entrypoint_prompt(agent: Agent, context: AgentContext) -> str | None:
293
331
  """
294
332
  Build entrypoint-specific prompt based on context.
295
333
 
@@ -302,7 +340,7 @@ async def build_entrypoint_prompt(agent: Agent, context: AgentContext) -> Option
302
340
  context: The agent context containing entrypoint information
303
341
 
304
342
  Returns:
305
- Optional[str]: The entrypoint-specific prompt, or None if no entrypoint
343
+ str | None: The entrypoint-specific prompt, or None if no entrypoint
306
344
  """
307
345
  if not context.entrypoint:
308
346
  return None
@@ -397,7 +435,7 @@ def create_formatted_prompt_function(agent: Agent, agent_data: AgentData) -> Cal
397
435
  )
398
436
 
399
437
  # Add user info if user_id is a valid EVM wallet address
400
- user_info = _build_user_info_section(context)
438
+ user_info = await _build_user_info_section(context)
401
439
  if user_info:
402
440
  final_system_prompt = f"{final_system_prompt}{user_info}"
403
441
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Mapping, MutableMapping
5
+ from collections.abc import Mapping, MutableMapping
6
6
 
7
7
  from apscheduler.jobstores.base import BaseJobStore
8
8
  from apscheduler.schedulers.asyncio import AsyncIOScheduler
@@ -11,7 +11,6 @@ from apscheduler.triggers.cron import CronTrigger
11
11
  from intentkit.core.agent import (
12
12
  update_agent_action_cost,
13
13
  update_agents_account_snapshot,
14
- update_agents_assets,
15
14
  update_agents_statistics,
16
15
  )
17
16
  from intentkit.core.credit import refill_all_free_credits
@@ -63,13 +62,14 @@ def create_scheduler(
63
62
  )
64
63
 
65
64
  # Update agent assets daily at UTC midnight
66
- scheduler.add_job(
67
- update_agents_assets,
68
- trigger=CronTrigger(hour=0, minute=0, timezone="UTC"),
69
- id="update_agent_assets",
70
- name="Update agent assets",
71
- replace_existing=True,
72
- )
65
+ # This is too expensive to run daily, so it will only be triggered when detail page is visited
66
+ # scheduler.add_job(
67
+ # update_agents_assets,
68
+ # trigger=CronTrigger(hour=0, minute=0, timezone="UTC"),
69
+ # id="update_agent_assets",
70
+ # name="Update agent assets",
71
+ # replace_existing=True,
72
+ # )
73
73
 
74
74
  # Update agent action costs hourly at minute 40
75
75
  scheduler.add_job(
@@ -2,9 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from datetime import datetime, timedelta, timezone
5
+ from datetime import UTC, datetime, timedelta
6
6
  from decimal import Decimal
7
- from typing import Optional
8
7
 
9
8
  from pydantic import BaseModel, Field
10
9
  from sqlalchemy import func, select
@@ -46,8 +45,8 @@ class AgentStatistics(BaseModel):
46
45
  async def get_agent_statistics(
47
46
  agent_id: str,
48
47
  *,
49
- end_time: Optional[datetime] = None,
50
- session: Optional[AsyncSession] = None,
48
+ end_time: datetime | None = None,
49
+ session: AsyncSession | None = None,
51
50
  ) -> AgentStatistics:
52
51
  """Calculate statistics for an agent credit account.
53
52
 
@@ -64,11 +63,11 @@ async def get_agent_statistics(
64
63
 
65
64
  managed_session = session is None
66
65
  if end_time is None:
67
- end_time = datetime.now(timezone.utc)
66
+ end_time = datetime.now(UTC)
68
67
  elif end_time.tzinfo is None:
69
- end_time = end_time.replace(tzinfo=timezone.utc)
68
+ end_time = end_time.replace(tzinfo=UTC)
70
69
  else:
71
- end_time = end_time.astimezone(timezone.utc)
70
+ end_time = end_time.astimezone(UTC)
72
71
 
73
72
  async def _compute(session: AsyncSession) -> AgentStatistics:
74
73
  account = await CreditAccount.get_or_create_in_session(