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/models/skill.py CHANGED
@@ -1,10 +1,12 @@
1
+ from __future__ import annotations
2
+
1
3
  import csv
2
4
  import json
3
5
  import logging
4
- from datetime import datetime, timezone
6
+ from datetime import UTC, datetime
5
7
  from decimal import Decimal
6
8
  from pathlib import Path
7
- from typing import Annotated, Any, Dict, Optional
9
+ from typing import Annotated, Any
8
10
 
9
11
  from intentkit.models.base import Base
10
12
  from intentkit.models.db import get_session
@@ -46,7 +48,7 @@ class AgentSkillDataTable(Base):
46
48
  DateTime(timezone=True),
47
49
  nullable=False,
48
50
  server_default=func.now(),
49
- onupdate=lambda: datetime.now(timezone.utc),
51
+ onupdate=lambda: datetime.now(UTC),
50
52
  )
51
53
 
52
54
 
@@ -58,7 +60,7 @@ class AgentSkillDataCreate(BaseModel):
58
60
  agent_id: Annotated[str, Field(description="ID of the agent this data belongs to")]
59
61
  skill: Annotated[str, Field(description="Name of the skill this data is for")]
60
62
  key: Annotated[str, Field(description="Key for this specific piece of data")]
61
- data: Annotated[Dict[str, Any], Field(description="JSON data stored for this key")]
63
+ data: Annotated[dict[str, Any], Field(description="JSON data stored for this key")]
62
64
 
63
65
  async def save(self) -> "AgentSkillData":
64
66
  """Save or update skill data.
@@ -157,7 +159,7 @@ class AgentSkillData(AgentSkillDataCreate):
157
159
  return result or 0
158
160
 
159
161
  @classmethod
160
- async def get(cls, agent_id: str, skill: str, key: str) -> Optional[dict]:
162
+ async def get(cls, agent_id: str, skill: str, key: str) -> dict | None:
161
163
  """Get skill data for an agent.
162
164
 
163
165
  Args:
@@ -232,7 +234,7 @@ class ChatSkillDataTable(Base):
232
234
  DateTime(timezone=True),
233
235
  nullable=False,
234
236
  server_default=func.now(),
235
- onupdate=lambda: datetime.now(timezone.utc),
237
+ onupdate=lambda: datetime.now(UTC),
236
238
  )
237
239
 
238
240
 
@@ -245,7 +247,7 @@ class ChatSkillDataCreate(BaseModel):
245
247
  skill: Annotated[str, Field(description="Name of the skill this data is for")]
246
248
  key: Annotated[str, Field(description="Key for this specific piece of data")]
247
249
  agent_id: Annotated[str, Field(description="ID of the agent that owns this chat")]
248
- data: Annotated[Dict[str, Any], Field(description="JSON data stored for this key")]
250
+ data: Annotated[dict[str, Any], Field(description="JSON data stored for this key")]
249
251
 
250
252
  async def save(self) -> "ChatSkillData":
251
253
  """Save or update skill data.
@@ -296,7 +298,7 @@ class ChatSkillData(ChatSkillDataCreate):
296
298
  ]
297
299
 
298
300
  @classmethod
299
- async def get(cls, chat_id: str, skill: str, key: str) -> Optional[dict]:
301
+ async def get(cls, chat_id: str, skill: str, key: str) -> dict | None:
300
302
  """Get skill data for a chat.
301
303
 
302
304
  Args:
@@ -353,20 +355,20 @@ class ChatSkillData(ChatSkillDataCreate):
353
355
  await db.commit()
354
356
 
355
357
 
356
- def _skill_parse_bool(value: Optional[str]) -> bool:
358
+ def _skill_parse_bool(value: str | None) -> bool:
357
359
  if value is None:
358
360
  return False
359
361
  return value.strip().lower() in {"true", "1", "yes"}
360
362
 
361
363
 
362
- def _skill_parse_optional_int(value: Optional[str]) -> Optional[int]:
364
+ def _skill_parse_optional_int(value: str | None) -> int | None:
363
365
  if value is None:
364
366
  return None
365
367
  value = value.strip()
366
368
  return int(value) if value else None
367
369
 
368
370
 
369
- def _skill_parse_decimal(value: Optional[str], default: str = "0") -> Decimal:
371
+ def _skill_parse_decimal(value: str | None, default: str = "0") -> Decimal:
370
372
  value = (value or "").strip()
371
373
  if not value:
372
374
  value = default
@@ -381,14 +383,14 @@ def _load_default_skills() -> tuple[dict[str, "Skill"], dict[tuple[str, str], "S
381
383
  logger.warning("Default skills CSV not found at %s", path)
382
384
  return {}, {}
383
385
 
384
- by_name: dict[str, "Skill"] = {}
385
- by_category_config: dict[tuple[str, str], "Skill"] = {}
386
+ by_name: dict[str, Skill] = {}
387
+ by_category_config: dict[tuple[str, str], Skill] = {}
386
388
 
387
389
  with path.open(newline="", encoding="utf-8") as csvfile:
388
390
  reader = csv.DictReader(csvfile)
389
391
  for row in reader:
390
392
  try:
391
- timestamp = datetime.now(timezone.utc)
393
+ timestamp = datetime.now(UTC)
392
394
  price_default = row.get("price") or "1"
393
395
  skill = Skill(
394
396
  name=row["name"],
@@ -447,7 +449,7 @@ class SkillTable(Base):
447
449
  DateTime(timezone=True),
448
450
  nullable=False,
449
451
  server_default=func.now(),
450
- onupdate=lambda: datetime.now(timezone.utc),
452
+ onupdate=lambda: datetime.now(UTC),
451
453
  )
452
454
 
453
455
 
@@ -464,10 +466,8 @@ class Skill(BaseModel):
464
466
  name: Annotated[str, Field(description="Name of the skill")]
465
467
  enabled: Annotated[bool, Field(description="Is this skill enabled?")]
466
468
  category: Annotated[str, Field(description="Category of the skill")]
467
- config_name: Annotated[Optional[str], Field(description="Config name of the skill")]
468
- price_level: Annotated[
469
- Optional[int], Field(description="Price level for this skill")
470
- ]
469
+ config_name: Annotated[str | None, Field(description="Config name of the skill")]
470
+ price_level: Annotated[int | None, Field(description="Price level for this skill")]
471
471
  price: Annotated[
472
472
  Decimal, Field(description="Price for this skill", default=Decimal("1"))
473
473
  ]
@@ -475,11 +475,9 @@ class Skill(BaseModel):
475
475
  Decimal,
476
476
  Field(description="Price for this skill with self key", default=Decimal("1")),
477
477
  ]
478
- rate_limit_count: Annotated[Optional[int], Field(description="Rate limit count")]
479
- rate_limit_minutes: Annotated[
480
- Optional[int], Field(description="Rate limit minutes")
481
- ]
482
- author: Annotated[Optional[str], Field(description="Author of the skill")]
478
+ rate_limit_count: Annotated[int | None, Field(description="Rate limit count")]
479
+ rate_limit_minutes: Annotated[int | None, Field(description="Rate limit minutes")]
480
+ author: Annotated[str | None, Field(description="Author of the skill")]
483
481
  created_at: Annotated[
484
482
  datetime, Field(description="Timestamp when this record was created")
485
483
  ]
@@ -488,7 +486,7 @@ class Skill(BaseModel):
488
486
  ]
489
487
 
490
488
  @staticmethod
491
- async def get(name: str) -> Optional["Skill"]:
489
+ async def get(name: str) -> Skill | None:
492
490
  """Get a skill by name with Redis caching.
493
491
 
494
492
  The skill is cached in Redis for 3 minutes.
@@ -537,7 +535,7 @@ class Skill(BaseModel):
537
535
  return None
538
536
 
539
537
  @staticmethod
540
- async def get_by_config_name(category: str, config_name: str) -> Optional["Skill"]:
538
+ async def get_by_config_name(category: str, config_name: str) -> "Skill" | None:
541
539
  """Get a skill by category and config_name.
542
540
 
543
541
  Args:
@@ -573,7 +571,7 @@ class Skill(BaseModel):
573
571
  async with get_session() as db:
574
572
  return await cls.get_all(session=db)
575
573
 
576
- skills: dict[str, "Skill"] = {
574
+ skills: dict[str, Skill] = {
577
575
  name: skill.model_copy(deep=True)
578
576
  for name, skill in DEFAULT_SKILLS_BY_NAME.items()
579
577
  }
@@ -2,29 +2,29 @@ category,config_name,name,enabled,price_level,price,price_self_key,rate_limit_co
2
2
  acolyt,ask_gpt,acolyt_ask_gpt,FALSE,1,1,1,,,0x2Bd32A312280bF5A01140e68ca630fB76cE8A3De
3
3
  aixbt,aixbt_projects,aixbt_projects,TRUE,3,100,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
4
4
  allora,get_price_prediction,allora_get_price_prediction,TRUE,4,230,5,,,0x2Bd32A312280bF5A01140e68ca630fB76cE8A3De
5
- basename,BasenameActionProvider_register_basename,BasenameActionProvider_register_basename,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
6
- cdp,CdpApiActionProvider_request_faucet_funds,CdpApiActionProvider_request_faucet_funds,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
7
- cdp,CdpEvmWalletActionProvider_get_swap_price,CdpEvmWalletActionProvider_get_swap_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
8
- cdp,CdpEvmWalletActionProvider_swap,CdpEvmWalletActionProvider_swap,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
9
- cdp,WalletActionProvider_get_balance,WalletActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
10
- cdp,WalletActionProvider_get_wallet_details,WalletActionProvider_get_wallet_details,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
11
- cdp,WalletActionProvider_native_transfer,WalletActionProvider_native_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
12
- erc20,ERC20ActionProvider_get_balance,ERC20ActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
13
- erc20,ERC20ActionProvider_transfer,ERC20ActionProvider_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
14
- erc721,Erc721ActionProvider_get_balance,Erc721ActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
15
- erc721,Erc721ActionProvider_mint,Erc721ActionProvider_mint,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
16
- erc721,Erc721ActionProvider_transfer,Erc721ActionProvider_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
17
- morpho,MorphoActionProvider_deposit,MorphoActionProvider_deposit,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
18
- morpho,MorphoActionProvider_withdraw,MorphoActionProvider_withdraw,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
19
- pyth,PythActionProvider_fetch_price,PythActionProvider_fetch_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
20
- pyth,PythActionProvider_fetch_price_feed,PythActionProvider_fetch_price_feed,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
21
- superfluid,SuperfluidActionProvider_create_flow,SuperfluidActionProvider_create_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
22
- superfluid,SuperfluidActionProvider_delete_flow,SuperfluidActionProvider_delete_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
23
- superfluid,SuperfluidActionProvider_update_flow,SuperfluidActionProvider_update_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
24
- weth,WethActionProvider_wrap_eth,WethActionProvider_wrap_eth,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
25
- wow,WowActionProvider_buy_token,WowActionProvider_buy_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
26
- wow,WowActionProvider_create_token,WowActionProvider_create_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
27
- wow,WowActionProvider_sell_token,WowActionProvider_sell_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
5
+ basename,BasenameActionProvider_register_basename,BasenameActionProvider_register_basename,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
6
+ cdp,CdpApiActionProvider_request_faucet_funds,CdpApiActionProvider_request_faucet_funds,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
7
+ cdp,CdpEvmWalletActionProvider_get_swap_price,CdpEvmWalletActionProvider_get_swap_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
8
+ cdp,CdpEvmWalletActionProvider_swap,CdpEvmWalletActionProvider_swap,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
9
+ cdp,WalletActionProvider_get_balance,WalletActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
10
+ cdp,WalletActionProvider_get_wallet_details,WalletActionProvider_get_wallet_details,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
11
+ cdp,WalletActionProvider_native_transfer,WalletActionProvider_native_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
12
+ erc20,ERC20ActionProvider_get_balance,ERC20ActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
13
+ erc20,ERC20ActionProvider_transfer,ERC20ActionProvider_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
14
+ erc721,Erc721ActionProvider_get_balance,Erc721ActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
15
+ erc721,Erc721ActionProvider_mint,Erc721ActionProvider_mint,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
16
+ erc721,Erc721ActionProvider_transfer,Erc721ActionProvider_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
17
+ morpho,MorphoActionProvider_deposit,MorphoActionProvider_deposit,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
18
+ morpho,MorphoActionProvider_withdraw,MorphoActionProvider_withdraw,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
19
+ pyth,PythActionProvider_fetch_price,PythActionProvider_fetch_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
20
+ pyth,PythActionProvider_fetch_price_feed,PythActionProvider_fetch_price_feed,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
21
+ superfluid,SuperfluidActionProvider_create_flow,SuperfluidActionProvider_create_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
22
+ superfluid,SuperfluidActionProvider_delete_flow,SuperfluidActionProvider_delete_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
23
+ superfluid,SuperfluidActionProvider_update_flow,SuperfluidActionProvider_update_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
24
+ weth,WethActionProvider_wrap_eth,WethActionProvider_wrap_eth,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
25
+ wow,WowActionProvider_buy_token,WowActionProvider_buy_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
26
+ wow,WowActionProvider_create_token,WowActionProvider_create_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
27
+ wow,WowActionProvider_sell_token,WowActionProvider_sell_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
28
28
  chainlist,chain_lookup,chain-lookup,TRUE,1,5,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
29
29
  common,current_time,common_current_time,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
30
30
  cookiefun,get_account_details,cookiefun_get_account_details,TRUE,2,70,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
@@ -162,10 +162,11 @@ firecrawl,firecrawl_scrape,firecrawl_scrape,TRUE,3,100,5,,,0x3cdd051eeC909f94965
162
162
  firecrawl,firecrawl_crawl,firecrawl_crawl,TRUE,3,100,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
163
163
  firecrawl,firecrawl_query_indexed_content,firecrawl_query_indexed_content,TRUE,1,5,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
164
164
  firecrawl,firecrawl_clear_indexed_content,firecrawl_clear_indexed_content,TRUE,1,5,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
165
- xmtp,xmtp_transfer,xmtp_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
166
- xmtp,xmtp_swap,xmtp_swap,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
167
- xmtp,xmtp_get_swap_price,xmtp_get_swap_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
168
- x402,x402_ask_agent,x402_ask_agent,TRUE,1,1,1,,,0x445750026A4a1906b61302442E085f9cbAfe206a
169
- casino,deck_shuffle,casino_deck_shuffle,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
165
+ xmtp,xmtp_transfer,xmtp_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
166
+ xmtp,xmtp_swap,xmtp_swap,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
167
+ xmtp,xmtp_get_swap_price,xmtp_get_swap_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
168
+ x402,x402_ask_agent,x402_ask_agent,TRUE,1,1,1,,,0x445750026A4a1906b61302442E085f9cbAfe206a
169
+ x402,x402_http_request,x402_http_request,TRUE,1,1,1,,,0x445750026A4a1906b61302442E085f9cbAfe206a
170
+ casino,deck_shuffle,casino_deck_shuffle,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
170
171
  casino,deck_draw,casino_deck_draw,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
171
172
  casino,dice_roll,casino_dice_roll,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
intentkit/models/user.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import logging
2
- from datetime import datetime, timezone
2
+ from datetime import UTC, datetime
3
3
  from decimal import ROUND_HALF_UP, Decimal
4
- from typing import Annotated, Optional, Type, TypeVar
4
+ from typing import Annotated, TypeVar
5
5
 
6
6
  from intentkit.models.base import Base
7
7
  from intentkit.models.credit import CreditAccount
@@ -13,7 +13,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
13
13
 
14
14
  logger = logging.getLogger(__name__)
15
15
 
16
-
17
16
  # TypeVar for User model constraint
18
17
  UserModelType = TypeVar("UserModelType", bound="User")
19
18
  UserTableType = TypeVar("UserTableType", bound="UserTable")
@@ -23,10 +22,10 @@ class UserRegistry:
23
22
  """Registry for extended model classes."""
24
23
 
25
24
  def __init__(self):
26
- self._user_table_class: Optional[Type[UserTableType]] = None
27
- self._user_model_class: Optional[Type[UserModelType]] = None
25
+ self._user_table_class: type[UserTableType] | None = None
26
+ self._user_model_class: type[UserModelType] | None = None
28
27
 
29
- def register_user_table(self, user_table_class: Type[UserTableType]) -> None:
28
+ def register_user_table(self, user_table_class: type[UserTableType]) -> None:
30
29
  """Register extended UserTable class.
31
30
 
32
31
  Args:
@@ -34,11 +33,11 @@ class UserRegistry:
34
33
  """
35
34
  self._user_table_class = user_table_class
36
35
 
37
- def get_user_table_class(self) -> Type[UserTableType]:
36
+ def get_user_table_class(self) -> type[UserTableType]:
38
37
  """Get registered UserTable class or default."""
39
38
  return self._user_table_class or UserTable
40
39
 
41
- def register_user_model(self, user_model_class: Type[UserModelType]) -> None:
40
+ def register_user_model(self, user_model_class: type[UserModelType]) -> None:
42
41
  """Register extended UserModel class.
43
42
 
44
43
  Args:
@@ -46,7 +45,7 @@ class UserRegistry:
46
45
  """
47
46
  self._user_model_class = user_model_class
48
47
 
49
- def get_user_model_class(self) -> Type[UserModelType]:
48
+ def get_user_model_class(self) -> type[UserModelType]:
50
49
  """Get registered UserModel class or default."""
51
50
  return self._user_model_class or User
52
51
 
@@ -114,7 +113,7 @@ class UserTable(Base):
114
113
  DateTime(timezone=True),
115
114
  nullable=False,
116
115
  server_default=func.now(),
117
- onupdate=lambda: datetime.now(timezone.utc),
116
+ onupdate=lambda: datetime.now(UTC),
118
117
  )
119
118
 
120
119
 
@@ -131,27 +130,27 @@ class UserUpdate(BaseModel):
131
130
  nft_count: Annotated[
132
131
  int, Field(default=0, description="Number of NFTs owned by the user")
133
132
  ]
134
- email: Annotated[Optional[str], Field(None, description="User's email address")]
133
+ email: Annotated[str | None, Field(None, description="User's email address")]
135
134
  x_username: Annotated[
136
- Optional[str], Field(None, description="User's X (Twitter) username")
135
+ str | None, Field(None, description="User's X (Twitter) username")
137
136
  ]
138
137
  github_username: Annotated[
139
- Optional[str], Field(None, description="User's GitHub username")
138
+ str | None, Field(None, description="User's GitHub username")
140
139
  ]
141
140
  telegram_username: Annotated[
142
- Optional[str], Field(None, description="User's Telegram username")
141
+ str | None, Field(None, description="User's Telegram username")
143
142
  ]
144
143
  extra: Annotated[
145
- Optional[dict], Field(None, description="Additional user information")
144
+ dict | None, Field(None, description="Additional user information")
146
145
  ]
147
146
  evm_wallet_address: Annotated[
148
- Optional[str], Field(None, description="User's EVM wallet address")
147
+ str | None, Field(None, description="User's EVM wallet address")
149
148
  ]
150
149
  solana_wallet_address: Annotated[
151
- Optional[str], Field(None, description="User's Solana wallet address")
150
+ str | None, Field(None, description="User's Solana wallet address")
152
151
  ]
153
152
  linked_accounts: Annotated[
154
- Optional[dict], Field(None, description="User's linked accounts information")
153
+ dict | None, Field(None, description="User's linked accounts information")
155
154
  ]
156
155
 
157
156
  async def _update_quota_for_nft_count(
@@ -165,7 +164,7 @@ class UserUpdate(BaseModel):
165
164
  new_nft_count: Current NFT count
166
165
  """
167
166
  # Generate upstream_tx_id
168
- timestamp = datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
167
+ timestamp = datetime.now(UTC).strftime("%Y%m%d%H%M%S")
169
168
  upstream_tx_id = f"nft_{id}_{timestamp}"
170
169
 
171
170
  # Calculate new quota values based on nft_count
@@ -286,7 +285,7 @@ class User(UserUpdate):
286
285
  ]
287
286
 
288
287
  @classmethod
289
- async def get(cls, user_id: str) -> Optional[UserModelType]:
288
+ async def get(cls, user_id: str) -> UserModelType | None:
290
289
  """Get a user by ID.
291
290
 
292
291
  Args:
@@ -301,7 +300,7 @@ class User(UserUpdate):
301
300
  @classmethod
302
301
  async def get_in_session(
303
302
  cls, session: AsyncSession, user_id: str
304
- ) -> Optional[UserModelType]:
303
+ ) -> UserModelType | None:
305
304
  """Get a user by ID using the provided session.
306
305
 
307
306
  Args:
@@ -324,7 +323,7 @@ class User(UserUpdate):
324
323
  return user_model_class.model_validate(user)
325
324
 
326
325
  @classmethod
327
- async def get_by_tg(cls, telegram_username: str) -> Optional[UserModelType]:
326
+ async def get_by_tg(cls, telegram_username: str) -> UserModelType | None:
328
327
  """Get a user by telegram username.
329
328
 
330
329
  Args:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Dict, Literal, Type
2
+ from typing import Literal
3
3
 
4
4
  import httpx
5
5
  from pydantic import BaseModel, Field
@@ -48,7 +48,6 @@ class AcolytAskGpt(AcolytBaseTool):
48
48
  - DEX & Trading: Get the 24-hour trading volume for tokens, Identify which DEX has the highest liquidity for tokens, Obtain the buy/sell ratio for tokens over specific time periods. Compare price changes across different timeframes for tokens. List trading pairs with over a value in liquidity for tokens.
49
49
  - Overall Metrics: Identify projects with the highest smart engagement relative to their market cap, Determine which agents have the best mindshare relative to their market cap. Compare the percentage of smart followers across the top n AI agents by market cap
50
50
 
51
-
52
51
  Attributes:
53
52
  name (str): Name of the tool, specifically "acolyt_ask_gpt".
54
53
  description (str): Comprehensive description of the tool's purpose and functionality.
@@ -64,9 +63,9 @@ class AcolytAskGpt(AcolytBaseTool):
64
63
  DEX & Trading: 24h volume, top DEX liquidity, buy/sell ratio, price change comparison, high liquidity pairs.
65
64
  Overall: Smart engagement/market cap ratio, mindshare/market cap ratio, smart follower percentage comparison across top AI agents.
66
65
  """
67
- args_schema: Type[BaseModel] = AcolytAskGptInput
66
+ args_schema: type[BaseModel] = AcolytAskGptInput
68
67
 
69
- async def _arun(self, question: str, **kwargs) -> Dict:
68
+ async def _arun(self, question: str, **kwargs) -> dict:
70
69
  """Run the tool to get answer from Acolyt GPT.
71
70
 
72
71
  Args:
@@ -1,5 +1,3 @@
1
- from typing import Type
2
-
3
1
  from langchain_core.tools.base import ToolException
4
2
  from pydantic import BaseModel, Field
5
3
 
@@ -14,7 +12,7 @@ class AcolytBaseTool(IntentKitSkill):
14
12
 
15
13
  name: str = Field(description="The name of the tool")
16
14
  description: str = Field(description="A description of what the tool does")
17
- args_schema: Type[BaseModel]
15
+ args_schema: type[BaseModel]
18
16
 
19
17
  def get_api_key(self) -> str:
20
18
  context = self.get_context()
@@ -1,5 +1,3 @@
1
- from typing import Type
2
-
3
1
  from pydantic import BaseModel, Field
4
2
 
5
3
  from intentkit.skills.base import IntentKitSkill
@@ -10,7 +8,7 @@ class AIXBTBaseTool(IntentKitSkill):
10
8
 
11
9
  name: str = Field(description="The name of the tool")
12
10
  description: str = Field(description="A description of what the tool does")
13
- args_schema: Type[BaseModel]
11
+ args_schema: type[BaseModel]
14
12
 
15
13
  @property
16
14
  def category(self) -> str:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict, Optional, Type
2
+ from typing import Any
3
3
 
4
4
  import httpx
5
5
  from langchain_core.tools import ToolException
@@ -17,23 +17,23 @@ class ProjectsInput(BaseModel):
17
17
  default=10,
18
18
  description="Number of projects to return (max 50)",
19
19
  )
20
- name: Optional[str] = Field(
20
+ name: str | None = Field(
21
21
  default=None,
22
22
  description="Filter projects by name (case-insensitive regex match)",
23
23
  )
24
- ticker: Optional[str] = Field(
24
+ ticker: str | None = Field(
25
25
  default=None,
26
26
  description="Filter projects by ticker symbol (case-insensitive match)",
27
27
  )
28
- xHandle: Optional[str] = Field(
28
+ xHandle: str | None = Field(
29
29
  default=None,
30
30
  description="Filter projects by X/Twitter handle",
31
31
  )
32
- minScore: Optional[float] = Field(
32
+ minScore: float | None = Field(
33
33
  default=None,
34
34
  description="Minimum score threshold",
35
35
  )
36
- chain: Optional[str] = Field(
36
+ chain: str | None = Field(
37
37
  default=None,
38
38
  description="Filter projects by blockchain",
39
39
  )
@@ -53,18 +53,18 @@ class AIXBTProjects(AIXBTBaseTool):
53
53
  "detailed information on recent developments. The 'alpha' keyword is a trigger "
54
54
  "for accessing AIXBT's specific dataset for crypto research."
55
55
  )
56
- args_schema: Type[BaseModel] = ProjectsInput
56
+ args_schema: type[BaseModel] = ProjectsInput
57
57
 
58
58
  async def _arun(
59
59
  self,
60
60
  limit: int = 10,
61
- name: Optional[str] = None,
62
- ticker: Optional[str] = None,
63
- xHandle: Optional[str] = None,
64
- minScore: Optional[float] = None,
65
- chain: Optional[str] = None,
61
+ name: str | None = None,
62
+ ticker: str | None = None,
63
+ xHandle: str | None = None,
64
+ minScore: float | None = None,
65
+ chain: str | None = None,
66
66
  **kwargs,
67
- ) -> Dict[str, Any]:
67
+ ) -> dict[str, Any]:
68
68
  """
69
69
  Search for cryptocurrency projects using AIXBT API.
70
70
 
@@ -1,5 +1,3 @@
1
- from typing import Type
2
-
3
1
  from langchain_core.tools.base import ToolException
4
2
  from pydantic import BaseModel, Field
5
3
 
@@ -14,7 +12,7 @@ class AlloraBaseTool(IntentKitSkill):
14
12
 
15
13
  name: str = Field(description="The name of the tool")
16
14
  description: str = Field(description="A description of what the tool does")
17
- args_schema: Type[BaseModel]
15
+ args_schema: type[BaseModel]
18
16
 
19
17
  def get_api_key(self) -> str:
20
18
  context = self.get_context()
@@ -1,4 +1,4 @@
1
- from typing import Literal, Type
1
+ from typing import Literal
2
2
 
3
3
  import httpx
4
4
  from langchain_core.tools.base import ToolException
@@ -57,7 +57,6 @@ class AlloraGetPrice(AlloraBaseTool):
57
57
  The Allora Price Prediction Feed tool fetches the price prediction feed from the Allora API.
58
58
  Ethereum (ETH) or Bitcoin (BTC) price predictions (5-minute, 8-hour)
59
59
 
60
-
61
60
  Attributes:
62
61
  name (str): Name of the tool, specifically "get_price_prediction".
63
62
  description (str): Comprehensive description of the tool's purpose and functionality.
@@ -69,7 +68,7 @@ class AlloraGetPrice(AlloraBaseTool):
69
68
  The Allora Price Prediction Feed tool fetches the price prediction feed from the Allora API.
70
69
  Ethereum (ETH) or Bitcoin (BTC) price predictions (5-minute, 8-hour)
71
70
  """
72
- args_schema: Type[BaseModel] = AlloraGetPriceInput
71
+ args_schema: type[BaseModel] = AlloraGetPriceInput
73
72
 
74
73
  def _run(self, question: str) -> AlloraGetPriceOutput:
75
74
  """Run the tool to get the token price prediction from Allora API.
intentkit/skills/base.py CHANGED
@@ -1,15 +1,10 @@
1
1
  import logging
2
- from collections.abc import Sequence
2
+ from collections.abc import Callable, Sequence
3
3
  from typing import (
4
- TYPE_CHECKING,
5
4
  Any,
6
- Callable,
7
- Dict,
8
5
  Literal,
9
6
  NotRequired,
10
- Optional,
11
7
  TypedDict,
12
- Union,
13
8
  )
14
9
 
15
10
  from coinbase_agentkit import (
@@ -29,6 +24,7 @@ from redis.exceptions import RedisError
29
24
 
30
25
  from intentkit.abstracts.graph import AgentContext
31
26
  from intentkit.clients import get_wallet_provider
27
+ from intentkit.models.agent import Agent
32
28
  from intentkit.models.redis import get_redis
33
29
  from intentkit.models.skill import (
34
30
  AgentSkillData,
@@ -38,9 +34,6 @@ from intentkit.models.skill import (
38
34
  )
39
35
  from intentkit.utils.error import IntentKitAPIError, RateLimitExceeded
40
36
 
41
- if TYPE_CHECKING:
42
- from intentkit.models.agent import Agent
43
-
44
37
  SkillState = Literal["disabled", "public", "private"]
45
38
  SkillOwnerState = Literal["disabled", "private"]
46
39
  APIKeyProviderValue = Literal["platform", "agent_owner"]
@@ -50,9 +43,9 @@ class SkillConfig(TypedDict):
50
43
  """Abstract base class for skill configuration."""
51
44
 
52
45
  enabled: bool
53
- states: Dict[str, SkillState | SkillOwnerState]
46
+ states: dict[str, SkillState | SkillOwnerState]
54
47
  api_key_provider: NotRequired[APIKeyProviderValue]
55
- __extra__: NotRequired[Dict[str, Any]]
48
+ __extra__: NotRequired[dict[str, Any]]
56
49
 
57
50
 
58
51
  class IntentKitSkill(BaseTool):
@@ -61,15 +54,15 @@ class IntentKitSkill(BaseTool):
61
54
  """
62
55
 
63
56
  # overwrite the value of BaseTool
64
- handle_tool_error: Optional[Union[bool, str, Callable[[ToolException], str]]] = (
57
+ handle_tool_error: bool | str | Callable[[ToolException], str] | None = (
65
58
  lambda e: f"tool error: {e}"
66
59
  )
67
60
  """Handle the content of the ToolException thrown."""
68
61
 
69
62
  # overwrite the value of BaseTool
70
- handle_validation_error: Optional[
71
- Union[bool, str, Callable[[Union[ValidationError, ValidationErrorV1]], str]]
72
- ] = lambda e: f"validation error: {e}"
63
+ handle_validation_error: (
64
+ bool | str | Callable[[ValidationError | ValidationErrorV1], str] | None
65
+ ) = lambda e: f"validation error: {e}"
73
66
  """Handle the content of the ValidationError thrown."""
74
67
 
75
68
  # Logger for the class
@@ -258,7 +251,7 @@ class IntentKitSkill(BaseTool):
258
251
  async def get_agent_skill_data(
259
252
  self,
260
253
  key: str,
261
- ) -> Optional[Dict[str, Any]]:
254
+ ) -> dict[str, Any] | None:
262
255
  """Retrieve persisted data for this skill scoped to the active agent."""
263
256
  return await self.get_agent_skill_data_raw(self.name, key)
264
257
 
@@ -266,12 +259,12 @@ class IntentKitSkill(BaseTool):
266
259
  self,
267
260
  skill_name: str,
268
261
  key: str,
269
- ) -> Optional[Dict[str, Any]]:
262
+ ) -> dict[str, Any] | None:
270
263
  """Retrieve persisted data for a specific skill scoped to the active agent."""
271
264
  context = self.get_context()
272
265
  return await AgentSkillData.get(context.agent_id, skill_name, key)
273
266
 
274
- async def save_agent_skill_data(self, key: str, data: Dict[str, Any]) -> None:
267
+ async def save_agent_skill_data(self, key: str, data: dict[str, Any]) -> None:
275
268
  """Persist data for this skill scoped to the active agent."""
276
269
  await self.save_agent_skill_data_raw(self.name, key, data)
277
270
 
@@ -279,7 +272,7 @@ class IntentKitSkill(BaseTool):
279
272
  self,
280
273
  skill_name: str,
281
274
  key: str,
282
- data: Dict[str, Any],
275
+ data: dict[str, Any],
283
276
  ) -> None:
284
277
  """Persist data for a specific skill scoped to the active agent."""
285
278
  context = self.get_context()
@@ -299,12 +292,12 @@ class IntentKitSkill(BaseTool):
299
292
  async def get_thread_skill_data(
300
293
  self,
301
294
  key: str,
302
- ) -> Optional[Dict[str, Any]]:
295
+ ) -> dict[str, Any] | None:
303
296
  """Retrieve persisted data for this skill scoped to the active chat."""
304
297
  context = self.get_context()
305
298
  return await ChatSkillData.get(context.chat_id, self.name, key)
306
299
 
307
- async def save_thread_skill_data(self, key: str, data: Dict[str, Any]) -> None:
300
+ async def save_thread_skill_data(self, key: str, data: dict[str, Any]) -> None:
308
301
  """Persist data for this skill scoped to the active chat."""
309
302
  context = self.get_context()
310
303
  skill_data = ChatSkillDataCreate(
@@ -321,7 +314,7 @@ async def get_agentkit_actions(
321
314
  agent_id: str,
322
315
  provider_factories: Sequence[Callable[[], object]],
323
316
  *,
324
- agent: Optional["Agent"] = None,
317
+ agent: Agent | None = None,
325
318
  ) -> list[Action]:
326
319
  """Build an AgentKit instance and return its actions."""
327
320