intentkit 0.6.9.dev2__py3-none-any.whl → 0.6.10__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 (170) hide show
  1. intentkit/__init__.py +1 -1
  2. intentkit/abstracts/graph.py +17 -2
  3. intentkit/core/engine.py +49 -30
  4. intentkit/core/node.py +10 -20
  5. intentkit/models/agent.py +215 -11
  6. intentkit/models/agent_schema.json +4 -0
  7. intentkit/models/chat.py +9 -1
  8. intentkit/models/llm.py +53 -0
  9. intentkit/skills/acolyt/ask.py +2 -5
  10. intentkit/skills/acolyt/base.py +16 -6
  11. intentkit/skills/aixbt/__init__.py +3 -7
  12. intentkit/skills/aixbt/projects.py +12 -36
  13. intentkit/skills/allora/base.py +16 -6
  14. intentkit/skills/allora/price.py +2 -4
  15. intentkit/skills/base.py +8 -1
  16. intentkit/skills/carv/base.py +12 -10
  17. intentkit/skills/carv/fetch_news.py +90 -92
  18. intentkit/skills/carv/onchain_query.py +162 -164
  19. intentkit/skills/carv/token_info_and_price.py +108 -110
  20. intentkit/skills/chainlist/chain_lookup.py +1 -2
  21. intentkit/skills/common/current_time.py +1 -2
  22. intentkit/skills/cookiefun/base.py +20 -12
  23. intentkit/skills/cookiefun/get_account_details.py +1 -3
  24. intentkit/skills/cookiefun/get_account_feed.py +1 -3
  25. intentkit/skills/cookiefun/get_account_smart_followers.py +1 -3
  26. intentkit/skills/cookiefun/get_sectors.py +2 -3
  27. intentkit/skills/cookiefun/search_accounts.py +1 -3
  28. intentkit/skills/cryptocompare/fetch_news.py +3 -4
  29. intentkit/skills/cryptocompare/fetch_price.py +3 -4
  30. intentkit/skills/cryptocompare/fetch_top_exchanges.py +3 -4
  31. intentkit/skills/cryptocompare/fetch_top_market_cap.py +3 -4
  32. intentkit/skills/cryptocompare/fetch_top_volume.py +3 -4
  33. intentkit/skills/cryptocompare/fetch_trading_signals.py +3 -4
  34. intentkit/skills/cryptopanic/base.py +13 -9
  35. intentkit/skills/cryptopanic/fetch_crypto_news.py +150 -153
  36. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +133 -136
  37. intentkit/skills/dapplooker/base.py +16 -6
  38. intentkit/skills/dapplooker/dapplooker_token_data.py +2 -4
  39. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +2 -3
  40. intentkit/skills/defillama/coins/fetch_block.py +2 -3
  41. intentkit/skills/defillama/coins/fetch_current_prices.py +2 -5
  42. intentkit/skills/defillama/coins/fetch_first_price.py +2 -5
  43. intentkit/skills/defillama/coins/fetch_historical_prices.py +2 -3
  44. intentkit/skills/defillama/coins/fetch_price_chart.py +2 -5
  45. intentkit/skills/defillama/coins/fetch_price_percentage.py +2 -5
  46. intentkit/skills/defillama/fees/fetch_fees_overview.py +2 -3
  47. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +2 -3
  48. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +2 -3
  49. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +2 -3
  50. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +2 -3
  51. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +2 -5
  52. intentkit/skills/defillama/tvl/fetch_chains.py +2 -3
  53. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +2 -3
  54. intentkit/skills/defillama/tvl/fetch_protocol.py +2 -5
  55. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +2 -5
  56. intentkit/skills/defillama/tvl/fetch_protocols.py +2 -3
  57. intentkit/skills/defillama/volumes/fetch_dex_overview.py +2 -3
  58. intentkit/skills/defillama/volumes/fetch_dex_summary.py +2 -5
  59. intentkit/skills/defillama/volumes/fetch_options_overview.py +2 -3
  60. intentkit/skills/defillama/yields/fetch_pool_chart.py +2 -5
  61. intentkit/skills/defillama/yields/fetch_pools.py +2 -3
  62. intentkit/skills/dune_analytics/base.py +15 -9
  63. intentkit/skills/dune_analytics/fetch_kol_buys.py +125 -128
  64. intentkit/skills/dune_analytics/fetch_nation_metrics.py +234 -237
  65. intentkit/skills/elfa/base.py +16 -6
  66. intentkit/skills/elfa/mention.py +2 -7
  67. intentkit/skills/elfa/stats.py +2 -6
  68. intentkit/skills/elfa/tokens.py +1 -4
  69. intentkit/skills/enso/base.py +25 -13
  70. intentkit/skills/enso/best_yield.py +1 -4
  71. intentkit/skills/enso/networks.py +2 -5
  72. intentkit/skills/enso/prices.py +1 -5
  73. intentkit/skills/enso/route.py +2 -5
  74. intentkit/skills/enso/tokens.py +1 -4
  75. intentkit/skills/enso/wallet.py +3 -9
  76. intentkit/skills/firecrawl/base.py +16 -6
  77. intentkit/skills/firecrawl/clear.py +1 -3
  78. intentkit/skills/firecrawl/crawl.py +7 -8
  79. intentkit/skills/firecrawl/query.py +7 -9
  80. intentkit/skills/firecrawl/scrape.py +7 -8
  81. intentkit/skills/github/github_search.py +1 -3
  82. intentkit/skills/heurist/base.py +15 -0
  83. intentkit/skills/heurist/image_generation_animagine_xl.py +3 -4
  84. intentkit/skills/heurist/image_generation_arthemy_comics.py +3 -4
  85. intentkit/skills/heurist/image_generation_arthemy_real.py +3 -4
  86. intentkit/skills/heurist/image_generation_braindance.py +3 -4
  87. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +3 -4
  88. intentkit/skills/heurist/image_generation_flux_1_dev.py +3 -4
  89. intentkit/skills/heurist/image_generation_sdxl.py +3 -4
  90. intentkit/skills/http/get.py +0 -2
  91. intentkit/skills/http/post.py +0 -2
  92. intentkit/skills/http/put.py +0 -2
  93. intentkit/skills/lifi/token_execute.py +1 -3
  94. intentkit/skills/lifi/token_quote.py +0 -2
  95. intentkit/skills/moralis/base.py +15 -1
  96. intentkit/skills/nation/nft_check.py +2 -5
  97. intentkit/skills/openai/base.py +14 -5
  98. intentkit/skills/openai/dalle_image_generation.py +6 -5
  99. intentkit/skills/openai/gpt_image_generation.py +6 -5
  100. intentkit/skills/openai/gpt_image_to_image.py +6 -5
  101. intentkit/skills/openai/image_to_text.py +6 -6
  102. intentkit/skills/portfolio/base.py +4 -3
  103. intentkit/skills/portfolio/token_balances.py +2 -4
  104. intentkit/skills/portfolio/wallet_approvals.py +2 -4
  105. intentkit/skills/portfolio/wallet_defi_positions.py +3 -4
  106. intentkit/skills/portfolio/wallet_history.py +2 -4
  107. intentkit/skills/portfolio/wallet_net_worth.py +2 -4
  108. intentkit/skills/portfolio/wallet_nfts.py +2 -4
  109. intentkit/skills/portfolio/wallet_profitability.py +2 -4
  110. intentkit/skills/portfolio/wallet_profitability_summary.py +2 -4
  111. intentkit/skills/portfolio/wallet_stats.py +2 -4
  112. intentkit/skills/portfolio/wallet_swaps.py +2 -4
  113. intentkit/skills/slack/base.py +18 -0
  114. intentkit/skills/slack/get_channel.py +3 -4
  115. intentkit/skills/slack/get_message.py +3 -4
  116. intentkit/skills/slack/schedule_message.py +3 -4
  117. intentkit/skills/slack/send_message.py +3 -4
  118. intentkit/skills/supabase/delete_data.py +3 -6
  119. intentkit/skills/supabase/fetch_data.py +3 -6
  120. intentkit/skills/supabase/insert_data.py +3 -6
  121. intentkit/skills/supabase/invoke_function.py +3 -6
  122. intentkit/skills/supabase/update_data.py +3 -6
  123. intentkit/skills/supabase/upsert_data.py +3 -6
  124. intentkit/skills/system/add_autonomous_task.py +1 -3
  125. intentkit/skills/system/delete_autonomous_task.py +1 -3
  126. intentkit/skills/system/edit_autonomous_task.py +1 -3
  127. intentkit/skills/system/list_autonomous_tasks.py +1 -3
  128. intentkit/skills/system/read_agent_api_key.py +2 -3
  129. intentkit/skills/system/regenerate_agent_api_key.py +2 -5
  130. intentkit/skills/tavily/base.py +14 -5
  131. intentkit/skills/tavily/tavily_extract.py +7 -8
  132. intentkit/skills/tavily/tavily_search.py +11 -9
  133. intentkit/skills/token/base.py +4 -6
  134. intentkit/skills/token/erc20_transfers.py +2 -4
  135. intentkit/skills/token/token_analytics.py +2 -4
  136. intentkit/skills/token/token_price.py +2 -4
  137. intentkit/skills/token/token_search.py +2 -4
  138. intentkit/skills/twitter/base.py +41 -0
  139. intentkit/skills/twitter/follow_user.py +4 -4
  140. intentkit/skills/twitter/get_mentions.py +4 -4
  141. intentkit/skills/twitter/get_timeline.py +4 -4
  142. intentkit/skills/twitter/get_user_by_username.py +4 -4
  143. intentkit/skills/twitter/get_user_tweets.py +4 -4
  144. intentkit/skills/twitter/like_tweet.py +4 -4
  145. intentkit/skills/twitter/post_tweet.py +3 -4
  146. intentkit/skills/twitter/reply_tweet.py +3 -4
  147. intentkit/skills/twitter/retweet.py +4 -4
  148. intentkit/skills/twitter/search_tweets.py +4 -4
  149. intentkit/skills/unrealspeech/base.py +16 -0
  150. intentkit/skills/unrealspeech/text_to_speech.py +4 -4
  151. intentkit/skills/venice_audio/base.py +11 -9
  152. intentkit/skills/venice_audio/venice_audio.py +238 -240
  153. intentkit/skills/venice_image/base.py +23 -19
  154. intentkit/skills/venice_image/image_enhance/image_enhance.py +78 -80
  155. intentkit/skills/venice_image/image_generation/image_generation_base.py +115 -117
  156. intentkit/skills/venice_image/image_upscale/image_upscale.py +88 -90
  157. intentkit/skills/venice_image/image_vision/image_vision.py +98 -100
  158. intentkit/skills/web_scraper/document_indexer.py +3 -5
  159. intentkit/skills/web_scraper/scrape_and_index.py +14 -17
  160. intentkit/skills/web_scraper/website_indexer.py +8 -10
  161. intentkit/skills/xmtp/README.md +110 -0
  162. intentkit/skills/xmtp/__init__.py +82 -0
  163. intentkit/skills/xmtp/base.py +15 -0
  164. intentkit/skills/xmtp/schema.json +43 -0
  165. intentkit/skills/xmtp/transfer.py +155 -0
  166. intentkit/skills/xmtp/xmtp.png +0 -0
  167. {intentkit-0.6.9.dev2.dist-info → intentkit-0.6.10.dist-info}/METADATA +4 -3
  168. {intentkit-0.6.9.dev2.dist-info → intentkit-0.6.10.dist-info}/RECORD +170 -164
  169. {intentkit-0.6.9.dev2.dist-info → intentkit-0.6.10.dist-info}/WHEEL +0 -0
  170. {intentkit-0.6.9.dev2.dist-info → intentkit-0.6.10.dist-info}/licenses/LICENSE +0 -0
@@ -2,7 +2,6 @@ import logging
2
2
  from typing import Type
3
3
 
4
4
  import httpx
5
- from langchain_core.runnables import RunnableConfig
6
5
  from pydantic import BaseModel, Field
7
6
 
8
7
  from intentkit.skills.tavily.base import TavilyBaseTool
@@ -58,7 +57,6 @@ class TavilySearch(TavilyBaseTool):
58
57
  max_results: int = 5,
59
58
  include_images: bool = False,
60
59
  include_raw_content: bool = False,
61
- config: RunnableConfig = None,
62
60
  **kwargs,
63
61
  ) -> str:
64
62
  """Implementation of the Tavily search tool.
@@ -68,26 +66,30 @@ class TavilySearch(TavilyBaseTool):
68
66
  max_results: Maximum number of search results to return (1-10).
69
67
  include_images: Whether to include image URLs in the results.
70
68
  include_raw_content: Whether to include raw HTML content in the results.
71
- config: The configuration for the tool call.
69
+
72
70
 
73
71
  Returns:
74
72
  str: Formatted search results with titles, snippets, and URLs.
75
73
  """
76
- context = self.context_from_config(config)
74
+ context = self.get_context()
75
+ skill_config = context.agent.skill_config(self.category)
77
76
  logger.debug(f"tavily.py: Running web search with context {context}")
78
77
 
79
- if context.config.get("api_key_provider") == "agent_owner":
80
- if context.config.get("rate_limit_number") and context.config.get(
78
+ if skill_config.get("api_key_provider") == "agent_owner":
79
+ if skill_config.get("rate_limit_number") and skill_config.get(
81
80
  "rate_limit_minutes"
82
81
  ):
83
82
  await self.user_rate_limit_by_category(
84
83
  context.user_id,
85
- context.config["rate_limit_number"],
86
- context.config["rate_limit_minutes"],
84
+ skill_config["rate_limit_number"],
85
+ skill_config["rate_limit_minutes"],
87
86
  )
88
87
 
89
88
  # Get the API key from the agent's configuration
90
- api_key = self.get_api_key(context)
89
+ if skill_config.get("api_key_provider") == "agent_owner":
90
+ api_key = skill_config.get("api_key")
91
+ else:
92
+ api_key = self.skill_store.get_system_config("tavily_api_key")
91
93
  if not api_key:
92
94
  return "Error: No Tavily API key provided in the configuration."
93
95
 
@@ -6,7 +6,7 @@ from typing import Any, Dict
6
6
  import aiohttp
7
7
 
8
8
  from intentkit.abstracts.skill import SkillStoreABC
9
- from intentkit.skills.base import IntentKitSkill, SkillContext
9
+ from intentkit.skills.base import IntentKitSkill
10
10
  from intentkit.skills.token.constants import MORALIS_API_BASE_URL
11
11
 
12
12
  logger = logging.getLogger(__name__)
@@ -27,16 +27,14 @@ class TokenBaseTool(IntentKitSkill):
27
27
  def category(self) -> str:
28
28
  return "token"
29
29
 
30
- def get_api_key(self, context: SkillContext) -> str:
30
+ def get_api_key(self) -> str:
31
31
  """Get API key from agent config or system config.
32
32
 
33
- Args:
34
- context: The skill context containing the agent config
35
-
36
33
  Returns:
37
34
  The API key to use for API requests
38
35
  """
39
- skill_config = context.config
36
+ context = self.get_context()
37
+ skill_config = context.agent.skill_config(self.category)
40
38
  if skill_config.get("api_key_provider") == "agent_owner":
41
39
  return skill_config.get("api_key")
42
40
  return self.skill_store.get_system_config("moralis_api_key")
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Any, Dict, List, Optional, Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from pydantic import BaseModel, Field
6
5
 
7
6
  from intentkit.skills.token.base import TokenBaseTool
@@ -80,7 +79,6 @@ class ERC20Transfers(TokenBaseTool):
80
79
  limit: Optional[int] = DEFAULT_LIMIT,
81
80
  order: Optional[str] = DEFAULT_ORDER,
82
81
  cursor: Optional[str] = None,
83
- config: RunnableConfig = None,
84
82
  **kwargs,
85
83
  ) -> Dict[str, Any]:
86
84
  """Fetch ERC20 token transfers for a wallet from Moralis.
@@ -101,7 +99,7 @@ class ERC20Transfers(TokenBaseTool):
101
99
  Returns:
102
100
  Dict containing ERC20 transfer data
103
101
  """
104
- context = self.context_from_config(config)
102
+ context = self.get_context()
105
103
  if context is None:
106
104
  logger.error("Context is None, cannot retrieve API key")
107
105
  return {
@@ -109,7 +107,7 @@ class ERC20Transfers(TokenBaseTool):
109
107
  }
110
108
 
111
109
  # Get the API key
112
- api_key = self.get_api_key(context)
110
+ api_key = self.get_api_key()
113
111
 
114
112
  if not api_key:
115
113
  logger.error("No Moralis API key available")
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Any, Dict, Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from pydantic import BaseModel, Field
6
5
 
7
6
  from intentkit.skills.token.base import TokenBaseTool
@@ -38,7 +37,6 @@ class TokenAnalytics(TokenBaseTool):
38
37
  self,
39
38
  address: str,
40
39
  chain: str = DEFAULT_CHAIN,
41
- config: RunnableConfig = None,
42
40
  **kwargs,
43
41
  ) -> Dict[str, Any]:
44
42
  """Fetch token analytics from Moralis.
@@ -51,7 +49,7 @@ class TokenAnalytics(TokenBaseTool):
51
49
  Returns:
52
50
  Dict containing token analytics data
53
51
  """
54
- context = self.context_from_config(config)
52
+ context = self.get_context()
55
53
  if context is None:
56
54
  logger.error("Context is None, cannot retrieve API key")
57
55
  return {
@@ -59,7 +57,7 @@ class TokenAnalytics(TokenBaseTool):
59
57
  }
60
58
 
61
59
  # Get the API key
62
- api_key = self.get_api_key(context)
60
+ api_key = self.get_api_key()
63
61
 
64
62
  if not api_key:
65
63
  logger.error("No Moralis API key available")
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Any, Dict, Optional, Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from pydantic import BaseModel, Field
6
5
 
7
6
  from intentkit.skills.token.base import TokenBaseTool
@@ -65,7 +64,6 @@ class TokenPrice(TokenBaseTool):
65
64
  to_block: Optional[int] = None,
66
65
  max_token_inactivity: Optional[int] = None,
67
66
  min_pair_side_liquidity_usd: Optional[int] = None,
68
- config: RunnableConfig = None,
69
67
  **kwargs,
70
68
  ) -> Dict[str, Any]:
71
69
  """Fetch token price from Moralis.
@@ -84,7 +82,7 @@ class TokenPrice(TokenBaseTool):
84
82
  Dict containing token price data
85
83
  """
86
84
  # Extract context from config
87
- context = self.context_from_config(config)
85
+ context = self.get_context()
88
86
 
89
87
  if context is None:
90
88
  logger.error("Context is None, cannot retrieve API key")
@@ -93,7 +91,7 @@ class TokenPrice(TokenBaseTool):
93
91
  }
94
92
 
95
93
  # Get the API key
96
- api_key = self.get_api_key(context)
94
+ api_key = self.get_api_key()
97
95
 
98
96
  if not api_key:
99
97
  logger.error("No Moralis API key available")
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Any, Dict, List, Optional, Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from pydantic import BaseModel, Field
6
5
 
7
6
  from intentkit.skills.token.base import TokenBaseTool
@@ -53,7 +52,6 @@ class TokenSearch(TokenBaseTool):
53
52
  chains: Optional[List[str]] = None,
54
53
  limit: Optional[int] = None,
55
54
  is_verified_contract: Optional[bool] = None,
56
- config: RunnableConfig = None,
57
55
  **kwargs,
58
56
  ) -> Dict[str, Any]:
59
57
  """Search for tokens using Moralis.
@@ -69,7 +67,7 @@ class TokenSearch(TokenBaseTool):
69
67
  Dict containing token search results
70
68
  """
71
69
  # Extract context from config
72
- context = self.context_from_config(config)
70
+ context = self.get_context()
73
71
  if context is None:
74
72
  logger.error("Context is None, cannot retrieve API key")
75
73
  return {
@@ -77,7 +75,7 @@ class TokenSearch(TokenBaseTool):
77
75
  }
78
76
 
79
77
  # Get the API key
80
- api_key = self.get_api_key(context)
78
+ api_key = self.get_api_key()
81
79
 
82
80
  if not api_key:
83
81
  logger.error("No Moralis API key available")
@@ -1,6 +1,7 @@
1
1
  from datetime import datetime, timedelta, timezone
2
2
  from typing import Type
3
3
 
4
+ from langchain.tools.base import ToolException
4
5
  from pydantic import BaseModel, Field
5
6
 
6
7
  from intentkit.abstracts.exception import RateLimitExceeded
@@ -18,6 +19,46 @@ class TwitterBaseTool(IntentKitSkill):
18
19
  description="The skill store for persisting data"
19
20
  )
20
21
 
22
+ def get_api_key(self) -> dict:
23
+ context = self.get_context()
24
+ skill_config = context.agent.skill_config(self.category)
25
+ api_key_provider = skill_config.get("api_key_provider")
26
+ if api_key_provider == "platform":
27
+ # Return platform keys (these need to be added to config.py)
28
+ return {
29
+ "consumer_key": self.skill_store.get_system_config(
30
+ "twitter_consumer_key"
31
+ ),
32
+ "consumer_secret": self.skill_store.get_system_config(
33
+ "twitter_consumer_secret"
34
+ ),
35
+ "access_token": self.skill_store.get_system_config(
36
+ "twitter_access_token"
37
+ ),
38
+ "access_token_secret": self.skill_store.get_system_config(
39
+ "twitter_access_token_secret"
40
+ ),
41
+ }
42
+ # for backward compatibility or agent_owner provider
43
+ elif api_key_provider == "agent_owner":
44
+ required_keys = [
45
+ "consumer_key",
46
+ "consumer_secret",
47
+ "access_token",
48
+ "access_token_secret",
49
+ ]
50
+ api_keys = {}
51
+ for key in required_keys:
52
+ if skill_config.get(key):
53
+ api_keys[key] = skill_config.get(key)
54
+ else:
55
+ raise ToolException(
56
+ f"Missing required {key} in agent_owner configuration"
57
+ )
58
+ return api_keys
59
+ else:
60
+ raise ToolException(f"Invalid API key provider: {api_key_provider}")
61
+
21
62
  @property
22
63
  def category(self) -> str:
23
64
  return "twitter"
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from langchain_core.tools import ToolException
6
5
  from pydantic import BaseModel, Field
7
6
 
@@ -37,13 +36,14 @@ class TwitterFollowUser(TwitterBaseTool):
37
36
  description: str = PROMPT
38
37
  args_schema: Type[BaseModel] = TwitterFollowUserInput
39
38
 
40
- async def _arun(self, user_id: str, config: RunnableConfig, **kwargs) -> bool:
39
+ async def _arun(self, user_id: str, **kwargs) -> bool:
41
40
  try:
42
- context = self.context_from_config(config)
41
+ context = self.get_context()
42
+ skill_config = context.agent.skill_config(self.category)
43
43
  twitter = get_twitter_client(
44
44
  agent_id=context.agent_id,
45
45
  skill_store=self.skill_store,
46
- config=context.config,
46
+ config=skill_config,
47
47
  )
48
48
  client = await twitter.get_client()
49
49
 
@@ -2,7 +2,6 @@ import logging
2
2
  from datetime import datetime, timedelta, timezone
3
3
  from typing import Type
4
4
 
5
- from langchain_core.runnables import RunnableConfig
6
5
  from langchain_core.tools import ToolException
7
6
  from pydantic import BaseModel
8
7
 
@@ -41,13 +40,14 @@ class TwitterGetMentions(TwitterBaseTool):
41
40
  description: str = PROMPT
42
41
  args_schema: Type[BaseModel] = TwitterGetMentionsInput
43
42
 
44
- async def _arun(self, config: RunnableConfig, **kwargs) -> list[Tweet]:
43
+ async def _arun(self, **kwargs) -> list[Tweet]:
45
44
  try:
46
- context = self.context_from_config(config)
45
+ context = self.get_context()
46
+ skill_config = context.agent.skill_config(self.category)
47
47
  twitter = get_twitter_client(
48
48
  agent_id=context.agent_id,
49
49
  skill_store=self.skill_store,
50
- config=context.config,
50
+ config=skill_config,
51
51
  )
52
52
  client = await twitter.get_client()
53
53
 
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from pydantic import BaseModel
6
5
 
7
6
  from intentkit.clients import get_twitter_client
@@ -37,16 +36,17 @@ class TwitterGetTimeline(TwitterBaseTool):
37
36
  description: str = PROMPT
38
37
  args_schema: Type[BaseModel] = TwitterGetTimelineInput
39
38
 
40
- async def _arun(self, config: RunnableConfig, **kwargs):
39
+ async def _arun(self, **kwargs):
41
40
  try:
42
41
  # Ensure max_results is an integer
43
42
  max_results = 10
44
43
 
45
- context = self.context_from_config(config)
44
+ context = self.get_context()
45
+ skill_config = context.agent.skill_config(self.category)
46
46
  twitter = get_twitter_client(
47
47
  agent_id=context.agent_id,
48
48
  skill_store=self.skill_store,
49
- config=context.config,
49
+ config=skill_config,
50
50
  )
51
51
  client = await twitter.get_client()
52
52
 
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from pydantic import BaseModel, Field
6
5
 
7
6
  from intentkit.clients import get_twitter_client
@@ -38,13 +37,14 @@ class TwitterGetUserByUsername(TwitterBaseTool):
38
37
  description: str = PROMPT
39
38
  args_schema: Type[BaseModel] = TwitterGetUserByUsernameInput
40
39
 
41
- async def _arun(self, username: str, config: RunnableConfig, **kwargs):
40
+ async def _arun(self, username: str, **kwargs):
42
41
  try:
43
- context = self.context_from_config(config)
42
+ context = self.get_context()
43
+ skill_config = context.agent.skill_config(self.category)
44
44
  twitter = get_twitter_client(
45
45
  agent_id=context.agent_id,
46
46
  skill_store=self.skill_store,
47
- config=context.config,
47
+ config=skill_config,
48
48
  )
49
49
  client = await twitter.get_client()
50
50
 
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import List, Optional, Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from pydantic import BaseModel, Field
6
5
 
7
6
  from intentkit.clients import get_twitter_client
@@ -44,7 +43,7 @@ class TwitterGetUserTweets(TwitterBaseTool):
44
43
  description: str = PROMPT
45
44
  args_schema: Type[BaseModel] = TwitterGetUserTweetsInput
46
45
 
47
- async def _arun(self, config: RunnableConfig, **kwargs):
46
+ async def _arun(self, **kwargs):
48
47
  try:
49
48
  user_id = kwargs.get("user_id")
50
49
  if not user_id:
@@ -56,11 +55,12 @@ class TwitterGetUserTweets(TwitterBaseTool):
56
55
  # Get exclude parameter with default
57
56
  exclude = kwargs.get("exclude", ["replies", "retweets"])
58
57
 
59
- context = self.context_from_config(config)
58
+ context = self.get_context()
59
+ skill_config = context.agent.skill_config(self.category)
60
60
  twitter = get_twitter_client(
61
61
  agent_id=context.agent_id,
62
62
  skill_store=self.skill_store,
63
- config=context.config,
63
+ config=skill_config,
64
64
  )
65
65
  client = await twitter.get_client()
66
66
 
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from langchain_core.tools import ToolException
6
5
  from pydantic import BaseModel, Field
7
6
 
@@ -35,13 +34,14 @@ class TwitterLikeTweet(TwitterBaseTool):
35
34
  description: str = PROMPT
36
35
  args_schema: Type[BaseModel] = TwitterLikeTweetInput
37
36
 
38
- async def _arun(self, tweet_id: str, config: RunnableConfig, **kwargs):
37
+ async def _arun(self, tweet_id: str, **kwargs):
39
38
  try:
40
- context = self.context_from_config(config)
39
+ context = self.get_context()
40
+ skill_config = context.agent.skill_config(self.category)
41
41
  twitter = get_twitter_client(
42
42
  agent_id=context.agent_id,
43
43
  skill_store=self.skill_store,
44
- config=context.config,
44
+ config=skill_config,
45
45
  )
46
46
  client = await twitter.get_client()
47
47
 
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Optional, Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from langchain_core.tools import ToolException
6
5
  from pydantic import BaseModel, Field
7
6
 
@@ -48,15 +47,15 @@ class TwitterPostTweet(TwitterBaseTool):
48
47
  self,
49
48
  text: str,
50
49
  image: Optional[str] = None,
51
- config: RunnableConfig = None,
52
50
  **kwargs,
53
51
  ):
54
52
  try:
55
- context = self.context_from_config(config)
53
+ context = self.get_context()
54
+ skill_config = context.agent.skill_config(self.category)
56
55
  twitter = get_twitter_client(
57
56
  agent_id=context.agent_id,
58
57
  skill_store=self.skill_store,
59
- config=context.config,
58
+ config=skill_config,
60
59
  )
61
60
  client = await twitter.get_client()
62
61
 
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Optional, Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from langchain_core.tools import ToolException
6
5
  from pydantic import BaseModel, Field
7
6
 
@@ -50,15 +49,15 @@ class TwitterReplyTweet(TwitterBaseTool):
50
49
  tweet_id: str,
51
50
  text: str,
52
51
  image: Optional[str] = None,
53
- config: RunnableConfig = None,
54
52
  **kwargs,
55
53
  ):
56
54
  try:
57
- context = self.context_from_config(config)
55
+ context = self.get_context()
56
+ skill_config = context.agent.skill_config(self.category)
58
57
  twitter = get_twitter_client(
59
58
  agent_id=context.agent_id,
60
59
  skill_store=self.skill_store,
61
- config=context.config,
60
+ config=skill_config,
62
61
  )
63
62
  client = await twitter.get_client()
64
63
 
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Type
3
3
 
4
- from langchain_core.runnables import RunnableConfig
5
4
  from langchain_core.tools import ToolException
6
5
  from pydantic import BaseModel, Field
7
6
 
@@ -35,13 +34,14 @@ class TwitterRetweet(TwitterBaseTool):
35
34
  description: str = PROMPT
36
35
  args_schema: Type[BaseModel] = TwitterRetweetInput
37
36
 
38
- async def _arun(self, tweet_id: str, config: RunnableConfig, **kwargs):
37
+ async def _arun(self, tweet_id: str, **kwargs):
39
38
  try:
40
- context = self.context_from_config(config)
39
+ context = self.get_context()
40
+ skill_config = context.agent.skill_config(self.category)
41
41
  twitter = get_twitter_client(
42
42
  agent_id=context.agent_id,
43
43
  skill_store=self.skill_store,
44
- config=context.config,
44
+ config=skill_config,
45
45
  )
46
46
  client = await twitter.get_client()
47
47
 
@@ -2,7 +2,6 @@ import datetime
2
2
  import logging
3
3
  from typing import Type
4
4
 
5
- from langchain_core.runnables import RunnableConfig
6
5
  from pydantic import BaseModel, Field
7
6
 
8
7
  from intentkit.clients import get_twitter_client
@@ -36,14 +35,15 @@ class TwitterSearchTweets(TwitterBaseTool):
36
35
  description: str = PROMPT
37
36
  args_schema: Type[BaseModel] = TwitterSearchTweetsInput
38
37
 
39
- async def _arun(self, query: str, config: RunnableConfig, **kwargs):
38
+ async def _arun(self, query: str, **kwargs):
40
39
  max_results = 10
41
40
  try:
42
- context = self.context_from_config(config)
41
+ context = self.get_context()
42
+ skill_config = context.agent.skill_config(self.category)
43
43
  twitter = get_twitter_client(
44
44
  agent_id=context.agent_id,
45
45
  skill_store=self.skill_store,
46
- config=context.config,
46
+ config=skill_config,
47
47
  )
48
48
  client = await twitter.get_client()
49
49
 
@@ -1,5 +1,6 @@
1
1
  from typing import Type
2
2
 
3
+ from langchain.tools.base import ToolException
3
4
  from pydantic import BaseModel, Field
4
5
 
5
6
  from intentkit.abstracts.skill import SkillStoreABC
@@ -16,6 +17,21 @@ class UnrealSpeechBaseTool(IntentKitSkill):
16
17
  description="The skill store for persisting data"
17
18
  )
18
19
 
20
+ def get_api_key(self) -> str:
21
+ context = self.get_context()
22
+ skill_config = context.agent.skill_config(self.category)
23
+ api_key_provider = skill_config.get("api_key_provider")
24
+ if api_key_provider == "agent_owner":
25
+ api_key = skill_config.get("api_key")
26
+ if api_key:
27
+ return api_key
28
+ else:
29
+ raise ToolException("No api_key found in agent_owner configuration")
30
+ else:
31
+ raise ToolException(
32
+ f"Invalid API key provider: {api_key_provider}. Only 'agent_owner' is supported for UnrealSpeech."
33
+ )
34
+
19
35
  @property
20
36
  def category(self) -> str:
21
37
  return "unrealspeech"
@@ -4,7 +4,6 @@ from typing import Any, Dict, Literal, Optional, Type
4
4
 
5
5
  import httpx
6
6
  from langchain_core.callbacks.manager import CallbackManagerForToolRun
7
- from langchain_core.runnables import RunnableConfig
8
7
  from pydantic import BaseModel, Field
9
8
 
10
9
  from intentkit.skills.unrealspeech.base import UnrealSpeechBaseTool
@@ -66,16 +65,17 @@ class TextToSpeech(UnrealSpeechBaseTool):
66
65
  bitrate: str = "192k",
67
66
  speed: float = 0.0,
68
67
  timestamp_type: Optional[Literal["word", "sentence"]] = "word",
69
- config: Optional[RunnableConfig] = None,
68
+ config: Optional[Any] = None,
70
69
  run_manager: Optional[CallbackManagerForToolRun] = None,
71
70
  **kwargs,
72
71
  ) -> Dict[str, Any]:
73
72
  """Run the tool to convert text to speech."""
74
73
 
75
74
  # Get the API key from context config if available
76
- context = self.context_from_config(config) if config else None
75
+ context = self.get_context()
76
+ skill_config = context.agent.skill_config(self.category) if config else None
77
77
  api_key = (
78
- context.config.get("api_key", None) if context and context.config else None
78
+ skill_config.get("api_key", None) if context and skill_config else None
79
79
  )
80
80
 
81
81
  # Clean up and validate input
@@ -1,10 +1,11 @@
1
1
  import logging
2
2
  from typing import Dict, List, Optional, Tuple, Type
3
3
 
4
+ from langchain.tools.base import ToolException
4
5
  from pydantic import BaseModel, Field
5
6
 
6
7
  from intentkit.abstracts.skill import SkillStoreABC
7
- from intentkit.skills.base import IntentKitSkill, SkillContext, ToolException
8
+ from intentkit.skills.base import IntentKitSkill
8
9
 
9
10
  logger = logging.getLogger(__name__)
10
11
 
@@ -24,7 +25,7 @@ class VeniceAudioBaseTool(IntentKitSkill):
24
25
  return "venice_audio"
25
26
 
26
27
  def validate_voice_model(
27
- self, context: SkillContext, voice_model: str
28
+ self, context, voice_model: str
28
29
  ) -> Tuple[bool, Optional[Dict[str, object]]]:
29
30
  config = context.config
30
31
 
@@ -47,7 +48,7 @@ class VeniceAudioBaseTool(IntentKitSkill):
47
48
 
48
49
  return True, None
49
50
 
50
- def get_api_key(self, context: SkillContext) -> str:
51
+ def get_api_key(self) -> str:
51
52
  """
52
53
  Retrieves the Venice AI API key based on the api_key_provider setting.
53
54
 
@@ -58,10 +59,11 @@ class VeniceAudioBaseTool(IntentKitSkill):
58
59
  ToolException: If the API key is not found or provider is invalid.
59
60
  """
60
61
  try:
61
- skillConfig = context.config
62
- api_key_provider = skillConfig.get("api_key_provider")
62
+ context = self.get_context()
63
+ skill_config = context.agent.skill_config(self.category)
64
+ api_key_provider = skill_config.get("api_key_provider")
63
65
  if api_key_provider == "agent_owner":
64
- agent_api_key = context.config.get("api_key")
66
+ agent_api_key = skill_config.get("api_key")
65
67
  if agent_api_key:
66
68
  logger.debug(
67
69
  f"Using agent-specific Venice API key for skill {self.name} in category {self.category}"
@@ -90,15 +92,15 @@ class VeniceAudioBaseTool(IntentKitSkill):
90
92
  except Exception as e:
91
93
  raise ToolException(f"Failed to retrieve Venice API key: {str(e)}") from e
92
94
 
93
- async def apply_rate_limit(self, context: SkillContext) -> None:
95
+ async def apply_rate_limit(self, context) -> None:
94
96
  """
95
97
  Applies rate limiting ONLY if specified in the agent's config ('skill_config').
96
98
  Checks for 'rate_limit_number' and 'rate_limit_minutes'.
97
99
  If not configured, NO rate limiting is applied.
98
100
  Raises ConnectionAbortedError if the configured limit is exceeded.
99
101
  """
100
- skill_config = context.config
101
- user_id = context.user_id
102
+ skill_config = context.agent.skill_config(self.category)
103
+ user_id = context.agent.id
102
104
 
103
105
  # Get agent-specific limits safely
104
106
  limit_num = skill_config.get("rate_limit_number")