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/agent.py CHANGED
@@ -1,22 +1,20 @@
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 Any, AsyncGenerator, Dict, List, Optional, Tuple
6
6
 
7
7
  from sqlalchemy import func, select, text, update
8
8
 
9
- from intentkit.abstracts.skill import SkillStoreABC
10
9
  from intentkit.clients.cdp import get_wallet_provider
11
10
  from intentkit.config.config import config
12
11
  from intentkit.models.agent import (
13
12
  Agent,
14
- AgentAutonomous,
15
13
  AgentCreate,
16
14
  AgentTable,
17
15
  AgentUpdate,
18
16
  )
19
- from intentkit.models.agent_data import AgentData, AgentQuota, AgentQuotaTable
17
+ from intentkit.models.agent_data import AgentData, AgentQuotaTable
20
18
  from intentkit.models.credit import (
21
19
  CreditAccount,
22
20
  CreditEventTable,
@@ -25,12 +23,6 @@ from intentkit.models.credit import (
25
23
  UpstreamType,
26
24
  )
27
25
  from intentkit.models.db import get_session
28
- from intentkit.models.skill import (
29
- AgentSkillData,
30
- AgentSkillDataCreate,
31
- ThreadSkillData,
32
- ThreadSkillDataCreate,
33
- )
34
26
  from intentkit.utils.error import IntentKitAPIError
35
27
  from intentkit.utils.slack_alert import send_slack_message
36
28
 
@@ -201,8 +193,8 @@ def send_agent_notification(agent: Agent, agent_data: AgentData, message: str) -
201
193
 
202
194
 
203
195
  async def override_agent(
204
- agent_id: str, agent: AgentUpdate, owner: Optional[str] = None
205
- ) -> Tuple[Agent, AgentData]:
196
+ agent_id: str, agent: AgentUpdate, owner: str | None = None
197
+ ) -> tuple[Agent, AgentData]:
206
198
  """Override an existing agent with new configuration.
207
199
 
208
200
  This function updates an existing agent with the provided configuration.
@@ -242,7 +234,7 @@ async def override_agent(
242
234
  return latest_agent, agent_data
243
235
 
244
236
 
245
- async def create_agent(agent: AgentCreate) -> Tuple[Agent, AgentData]:
237
+ async def create_agent(agent: AgentCreate) -> tuple[Agent, AgentData]:
246
238
  """Create a new agent with the provided configuration.
247
239
 
248
240
  This function creates a new agent instance with the given configuration,
@@ -279,8 +271,8 @@ async def create_agent(agent: AgentCreate) -> Tuple[Agent, AgentData]:
279
271
 
280
272
 
281
273
  async def deploy_agent(
282
- agent_id: str, agent: AgentUpdate, owner: Optional[str] = None
283
- ) -> Tuple[Agent, AgentData]:
274
+ agent_id: str, agent: AgentUpdate, owner: str | None = None
275
+ ) -> tuple[Agent, AgentData]:
284
276
  """Deploy an agent by first attempting to override, then creating if not found.
285
277
 
286
278
  This function first tries to override an existing agent. If the agent is not found
@@ -315,7 +307,7 @@ async def deploy_agent(
315
307
  raise
316
308
 
317
309
 
318
- async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
310
+ async def agent_action_cost(agent_id: str) -> dict[str, Decimal]:
319
311
  """
320
312
  Calculate various action cost metrics for an agent based on past three days of credit events.
321
313
 
@@ -331,7 +323,7 @@ async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
331
323
  agent_id: ID of the agent
332
324
 
333
325
  Returns:
334
- Dict[str, Decimal]: Dictionary containing all calculated cost metrics
326
+ dict[str, Decimal]: Dictionary containing all calculated cost metrics
335
327
  """
336
328
  start_time = time.time()
337
329
  default_value = Decimal("0")
@@ -344,7 +336,7 @@ async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
344
336
 
345
337
  async with get_session() as session:
346
338
  # Calculate the date 3 days ago from now
347
- three_days_ago = datetime.now(timezone.utc) - timedelta(days=3)
339
+ three_days_ago = datetime.now(UTC) - timedelta(days=3)
348
340
 
349
341
  # First, count the number of distinct start_message_ids to determine if we have enough data
350
342
  count_query = select(
@@ -492,188 +484,12 @@ async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
492
484
  return result
493
485
 
494
486
 
495
- class AgentStore(SkillStoreABC):
496
- """Implementation of skill data storage operations.
497
-
498
- This class provides concrete implementations for storing and retrieving
499
- skill-related data for both agents and threads.
500
- """
501
-
502
- @staticmethod
503
- def get_system_config(key: str) -> Any:
504
- # TODO: maybe need a whitelist here
505
- if hasattr(config, key):
506
- return getattr(config, key)
507
- return None
508
-
509
- @staticmethod
510
- async def get_agent_config(agent_id: str) -> Optional[Agent]:
511
- return await Agent.get(agent_id)
512
-
513
- @staticmethod
514
- async def get_agent_data(agent_id: str) -> AgentData:
515
- return await AgentData.get(agent_id)
516
-
517
- @staticmethod
518
- async def set_agent_data(agent_id: str, data: Dict) -> AgentData:
519
- return await AgentData.patch(agent_id, data)
520
-
521
- @staticmethod
522
- async def get_agent_quota(agent_id: str) -> AgentQuota:
523
- return await AgentQuota.get(agent_id)
524
-
525
- @staticmethod
526
- async def get_agent_skill_data(
527
- agent_id: str, skill: str, key: str
528
- ) -> Optional[Dict[str, Any]]:
529
- """Get skill data for an agent.
530
-
531
- Args:
532
- agent_id: ID of the agent
533
- skill: Name of the skill
534
- key: Data key
535
-
536
- Returns:
537
- Dictionary containing the skill data if found, None otherwise
538
- """
539
- return await AgentSkillData.get(agent_id, skill, key)
540
-
541
- @staticmethod
542
- async def save_agent_skill_data(
543
- agent_id: str, skill: str, key: str, data: Dict[str, Any]
544
- ) -> None:
545
- """Save or update skill data for an agent.
546
-
547
- Args:
548
- agent_id: ID of the agent
549
- skill: Name of the skill
550
- key: Data key
551
- data: JSON data to store
552
- """
553
- skill_data = AgentSkillDataCreate(
554
- agent_id=agent_id,
555
- skill=skill,
556
- key=key,
557
- data=data,
558
- )
559
- await skill_data.save()
560
-
561
- @staticmethod
562
- async def delete_agent_skill_data(agent_id: str, skill: str, key: str) -> None:
563
- """Delete skill data for an agent.
564
-
565
- Args:
566
- agent_id: ID of the agent
567
- skill: Name of the skill
568
- key: Data key
569
- """
570
- await AgentSkillData.delete(agent_id, skill, key)
571
-
572
- @staticmethod
573
- async def get_thread_skill_data(
574
- thread_id: str, skill: str, key: str
575
- ) -> Optional[Dict[str, Any]]:
576
- """Get skill data for a thread.
577
-
578
- Args:
579
- thread_id: ID of the thread
580
- skill: Name of the skill
581
- key: Data key
582
-
583
- Returns:
584
- Dictionary containing the skill data if found, None otherwise
585
- """
586
- return await ThreadSkillData.get(thread_id, skill, key)
587
-
588
- @staticmethod
589
- async def save_thread_skill_data(
590
- thread_id: str,
591
- agent_id: str,
592
- skill: str,
593
- key: str,
594
- data: Dict[str, Any],
595
- ) -> None:
596
- """Save or update skill data for a thread.
597
-
598
- Args:
599
- thread_id: ID of the thread
600
- agent_id: ID of the agent that owns this thread
601
- skill: Name of the skill
602
- key: Data key
603
- data: JSON data to store
604
- """
605
- skill_data = ThreadSkillDataCreate(
606
- thread_id=thread_id,
607
- agent_id=agent_id,
608
- skill=skill,
609
- key=key,
610
- data=data,
611
- )
612
- await skill_data.save()
613
-
614
- @staticmethod
615
- async def list_autonomous_tasks(agent_id: str) -> List[AgentAutonomous]:
616
- """List all autonomous tasks for an agent.
617
-
618
- Args:
619
- agent_id: ID of the agent
620
-
621
- Returns:
622
- List[AgentAutonomous]: List of autonomous task configurations
623
- """
624
- return await list_autonomous_tasks(agent_id)
625
-
626
- @staticmethod
627
- async def add_autonomous_task(
628
- agent_id: str, task: AgentAutonomous
629
- ) -> AgentAutonomous:
630
- """Add a new autonomous task to an agent.
631
-
632
- Args:
633
- agent_id: ID of the agent
634
- task: Autonomous task configuration
635
-
636
- Returns:
637
- AgentAutonomous: The created task
638
- """
639
- return await add_autonomous_task(agent_id, task)
640
-
641
- @staticmethod
642
- async def delete_autonomous_task(agent_id: str, task_id: str) -> None:
643
- """Delete an autonomous task from an agent.
644
-
645
- Args:
646
- agent_id: ID of the agent
647
- task_id: ID of the task to delete
648
- """
649
- await delete_autonomous_task(agent_id, task_id)
650
-
651
- @staticmethod
652
- async def update_autonomous_task(
653
- agent_id: str, task_id: str, task_updates: dict
654
- ) -> AgentAutonomous:
655
- """Update an autonomous task for an agent.
656
-
657
- Args:
658
- agent_id: ID of the agent
659
- task_id: ID of the task to update
660
- task_updates: Dictionary containing fields to update
661
-
662
- Returns:
663
- AgentAutonomous: The updated task
664
- """
665
- return await update_autonomous_task(agent_id, task_id, task_updates)
666
-
667
-
668
- agent_store = AgentStore()
669
-
670
-
671
487
  async def _iterate_agent_id_batches(
672
488
  batch_size: int = 100,
673
489
  ) -> AsyncGenerator[list[str], None]:
674
490
  """Yield agent IDs in ascending batches to limit memory usage."""
675
491
 
676
- last_id: Optional[str] = None
492
+ last_id: str | None = None
677
493
  while True:
678
494
  async with get_session() as session:
679
495
  query = select(AgentTable.id).order_by(AgentTable.id)
@@ -863,18 +679,18 @@ async def update_agents_assets(batch_size: int = 100) -> None:
863
679
 
864
680
 
865
681
  async def update_agents_statistics(
866
- *, end_time: Optional[datetime] = None, batch_size: int = 100
682
+ *, end_time: datetime | None = None, batch_size: int = 100
867
683
  ) -> None:
868
684
  """Refresh cached statistics for every agent."""
869
685
 
870
686
  from intentkit.core.statistics import get_agent_statistics
871
687
 
872
688
  if end_time is None:
873
- end_time = datetime.now(timezone.utc)
689
+ end_time = datetime.now(UTC)
874
690
  elif end_time.tzinfo is None:
875
- end_time = end_time.replace(tzinfo=timezone.utc)
691
+ end_time = end_time.replace(tzinfo=UTC)
876
692
  else:
877
- end_time = end_time.astimezone(timezone.utc)
693
+ end_time = end_time.astimezone(UTC)
878
694
 
879
695
  logger.info("Starting update of agent statistics using end_time %s", end_time)
880
696
  start_time = time.time()
@@ -923,191 +739,3 @@ async def update_agents_statistics(
923
739
  total_updated,
924
740
  total_time,
925
741
  )
926
-
927
-
928
- async def list_autonomous_tasks(agent_id: str) -> List[AgentAutonomous]:
929
- """
930
- List all autonomous tasks for an agent.
931
-
932
- Args:
933
- agent_id: ID of the agent
934
-
935
- Returns:
936
- List[AgentAutonomous]: List of autonomous task configurations
937
-
938
- Raises:
939
- IntentKitAPIError: If agent is not found
940
- """
941
- agent = await Agent.get(agent_id)
942
- if not agent:
943
- raise IntentKitAPIError(
944
- 400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
945
- )
946
-
947
- if not agent.autonomous:
948
- return []
949
-
950
- return agent.autonomous
951
-
952
-
953
- async def add_autonomous_task(agent_id: str, task: AgentAutonomous) -> AgentAutonomous:
954
- """
955
- Add a new autonomous task to an agent.
956
-
957
- Args:
958
- agent_id: ID of the agent
959
- task: Autonomous task configuration (id will be generated if not provided)
960
-
961
- Returns:
962
- AgentAutonomous: The created task with generated ID
963
-
964
- Raises:
965
- IntentKitAPIError: If agent is not found
966
- """
967
- agent = await Agent.get(agent_id)
968
- if not agent:
969
- raise IntentKitAPIError(
970
- 400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
971
- )
972
-
973
- # Get current autonomous tasks
974
- current_tasks = agent.autonomous or []
975
- if not isinstance(current_tasks, list):
976
- current_tasks = []
977
-
978
- # Add the new task
979
- current_tasks.append(task)
980
-
981
- # Convert all AgentAutonomous objects to dictionaries for JSON serialization
982
- serializable_tasks = [task_item.model_dump() for task_item in current_tasks]
983
-
984
- # Update the agent in the database
985
- async with get_session() as session:
986
- update_stmt = (
987
- update(AgentTable)
988
- .where(AgentTable.id == agent_id)
989
- .values(autonomous=serializable_tasks)
990
- )
991
- await session.execute(update_stmt)
992
- await session.commit()
993
-
994
- logger.info(f"Added autonomous task {task.id} to agent {agent_id}")
995
- return task
996
-
997
-
998
- async def delete_autonomous_task(agent_id: str, task_id: str) -> None:
999
- """
1000
- Delete an autonomous task from an agent.
1001
-
1002
- Args:
1003
- agent_id: ID of the agent
1004
- task_id: ID of the task to delete
1005
-
1006
- Raises:
1007
- IntentKitAPIError: If agent is not found or task is not found
1008
- """
1009
- agent = await Agent.get(agent_id)
1010
- if not agent:
1011
- raise IntentKitAPIError(
1012
- 400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
1013
- )
1014
-
1015
- # Get current autonomous tasks
1016
- current_tasks = agent.autonomous or []
1017
- if not isinstance(current_tasks, list):
1018
- current_tasks = []
1019
-
1020
- # Find and remove the task
1021
- task_found = False
1022
- updated_tasks = []
1023
- for task_data in current_tasks:
1024
- if task_data.id == task_id:
1025
- task_found = True
1026
- continue
1027
- updated_tasks.append(task_data)
1028
-
1029
- if not task_found:
1030
- raise IntentKitAPIError(
1031
- 404, "TaskNotFound", f"Autonomous task with ID {task_id} not found."
1032
- )
1033
-
1034
- # Convert remaining AgentAutonomous objects to dictionaries for JSON serialization
1035
- serializable_tasks = [task_item.model_dump() for task_item in updated_tasks]
1036
-
1037
- # Update the agent in the database
1038
- async with get_session() as session:
1039
- update_stmt = (
1040
- update(AgentTable)
1041
- .where(AgentTable.id == agent_id)
1042
- .values(autonomous=serializable_tasks)
1043
- )
1044
- await session.execute(update_stmt)
1045
- await session.commit()
1046
-
1047
- logger.info(f"Deleted autonomous task {task_id} from agent {agent_id}")
1048
-
1049
-
1050
- async def update_autonomous_task(
1051
- agent_id: str, task_id: str, task_updates: dict
1052
- ) -> AgentAutonomous:
1053
- """
1054
- Update an autonomous task for an agent.
1055
-
1056
- Args:
1057
- agent_id: ID of the agent
1058
- task_id: ID of the task to update
1059
- task_updates: Dictionary containing fields to update
1060
-
1061
- Returns:
1062
- AgentAutonomous: The updated task
1063
-
1064
- Raises:
1065
- IntentKitAPIError: If agent is not found or task is not found
1066
- """
1067
- agent = await Agent.get(agent_id)
1068
- if not agent:
1069
- raise IntentKitAPIError(
1070
- 400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
1071
- )
1072
-
1073
- # Get current autonomous tasks
1074
- current_tasks: List[AgentAutonomous] = agent.autonomous or []
1075
-
1076
- # Find and update the task
1077
- task_found = False
1078
- updated_tasks: List[AgentAutonomous] = []
1079
- updated_task = None
1080
-
1081
- for task_data in current_tasks:
1082
- if task_data.id == task_id:
1083
- task_found = True
1084
- # Create a dictionary with current task data
1085
- task_dict = task_data.model_dump()
1086
- # Update with provided fields
1087
- task_dict.update(task_updates)
1088
- # Create new AgentAutonomous instance
1089
- updated_task = AgentAutonomous.model_validate(task_dict)
1090
- updated_tasks.append(updated_task)
1091
- else:
1092
- updated_tasks.append(task_data)
1093
-
1094
- if not task_found:
1095
- raise IntentKitAPIError(
1096
- 404, "TaskNotFound", f"Autonomous task with ID {task_id} not found."
1097
- )
1098
-
1099
- # Convert all AgentAutonomous objects to dictionaries for JSON serialization
1100
- serializable_tasks = [task_item.model_dump() for task_item in updated_tasks]
1101
-
1102
- # Update the agent in the database
1103
- async with get_session() as session:
1104
- update_stmt = (
1105
- update(AgentTable)
1106
- .where(AgentTable.id == agent_id)
1107
- .values(autonomous=serializable_tasks)
1108
- )
1109
- await session.execute(update_stmt)
1110
- await session.commit()
1111
-
1112
- logger.info(f"Updated autonomous task {task_id} for agent {agent_id}")
1113
- return updated_task
intentkit/core/asset.py CHANGED
@@ -2,18 +2,21 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import json
5
6
  import logging
6
7
  from decimal import Decimal
7
- from typing import Optional
8
8
 
9
9
  import httpx
10
10
  from pydantic import BaseModel, Field
11
+ from sqlalchemy import update
11
12
  from web3 import Web3
12
13
 
13
14
  from intentkit.clients.web3 import get_web3_client
14
15
  from intentkit.config.config import config
15
- from intentkit.models.agent import Agent
16
+ from intentkit.models.agent import Agent, AgentTable
16
17
  from intentkit.models.agent_data import AgentData
18
+ from intentkit.models.db import get_session
19
+ from intentkit.models.redis import get_redis
17
20
  from intentkit.utils.error import IntentKitAPIError
18
21
 
19
22
  logger = logging.getLogger(__name__)
@@ -135,7 +138,7 @@ async def _build_assets_list(
135
138
  return assets
136
139
 
137
140
  wallet_address = agent_data.evm_wallet_address
138
- network_id: Optional[str] = agent.network_id
141
+ network_id: str | None = agent.network_id
139
142
 
140
143
  # ETH is always included
141
144
  eth_balance = await _get_eth_balance(web3_client, wallet_address)
@@ -171,29 +174,72 @@ async def _build_assets_list(
171
174
 
172
175
  async def agent_asset(agent_id: str) -> AgentAssets:
173
176
  """Fetch wallet net worth and token balances for an agent."""
177
+
178
+ cache_key = f"intentkit:agent_assets:{agent_id}"
179
+ redis_client = None
180
+
181
+ try:
182
+ redis_client = get_redis()
183
+ except Exception as exc: # pragma: no cover - best effort fallback
184
+ logger.debug("Redis unavailable for agent assets: %s", exc)
185
+
174
186
  agent = await Agent.get(agent_id)
175
187
  if not agent:
176
188
  raise IntentKitAPIError(404, "AgentNotFound", "Agent not found")
177
189
 
190
+ if redis_client:
191
+ try:
192
+ cached_raw = await redis_client.get(cache_key)
193
+ if cached_raw:
194
+ cached_data = json.loads(cached_raw)
195
+ cached_assets = AgentAssets.model_validate(cached_data)
196
+ return cached_assets
197
+ except Exception as exc: # pragma: no cover - cache read path only
198
+ logger.debug("Failed to read agent asset cache for %s: %s", agent_id, exc)
199
+
178
200
  agent_data = await AgentData.get(agent_id)
179
201
  if not agent_data or not agent_data.evm_wallet_address:
180
- return AgentAssets(net_worth="0", tokens=[])
181
-
182
- if not agent.network_id:
183
- return AgentAssets(net_worth="0", tokens=[])
202
+ assets_result = AgentAssets(net_worth="0", tokens=[])
203
+ elif not agent.network_id:
204
+ assets_result = AgentAssets(net_worth="0", tokens=[])
205
+ else:
206
+ try:
207
+ web3_client = get_web3_client(str(agent.network_id))
208
+ tokens = await _build_assets_list(agent, agent_data, web3_client)
209
+ net_worth = await _get_wallet_net_worth(agent_data.evm_wallet_address)
210
+ assets_result = AgentAssets(net_worth=net_worth, tokens=tokens)
211
+ except IntentKitAPIError:
212
+ raise
213
+ except Exception as exc:
214
+ logger.error("Error getting agent assets for %s: %s", agent_id, exc)
215
+ raise IntentKitAPIError(
216
+ 500, "AgentAssetError", "Failed to retrieve agent assets"
217
+ ) from exc
218
+
219
+ assets_payload = assets_result.model_dump(mode="json")
220
+
221
+ if redis_client:
222
+ try:
223
+ await redis_client.set(
224
+ cache_key,
225
+ json.dumps(assets_payload),
226
+ ex=3600,
227
+ )
228
+ except Exception as exc: # pragma: no cover - cache write path only
229
+ logger.debug("Failed to write agent asset cache for %s: %s", agent_id, exc)
184
230
 
185
231
  try:
186
- web3_client = get_web3_client(str(agent.network_id))
187
- tokens = await _build_assets_list(agent, agent_data, web3_client)
188
- net_worth = await _get_wallet_net_worth(agent_data.evm_wallet_address)
189
- return AgentAssets(net_worth=net_worth, tokens=tokens)
190
- except IntentKitAPIError:
191
- raise
192
- except Exception as exc:
193
- logger.error("Error getting agent assets for %s: %s", agent_id, exc)
194
- raise IntentKitAPIError(
195
- 500, "AgentAssetError", "Failed to retrieve agent assets"
196
- ) from exc
232
+ async with get_session() as session:
233
+ await session.execute(
234
+ update(AgentTable)
235
+ .where(AgentTable.id == agent_id)
236
+ .values(assets=assets_payload)
237
+ )
238
+ await session.commit()
239
+ except Exception as exc: # pragma: no cover - db persistence path only
240
+ logger.error("Error updating agent assets cache for %s: %s", agent_id, exc)
241
+
242
+ return assets_result
197
243
 
198
244
 
199
245
  __all__ = [
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