intentkit 0.8.11.dev1__py3-none-any.whl → 0.8.12__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.
- intentkit/__init__.py +1 -1
- intentkit/abstracts/graph.py +4 -0
- intentkit/abstracts/skill.py +2 -140
- intentkit/clients/twitter.py +35 -28
- intentkit/core/agent.py +2 -374
- intentkit/core/asset.py +63 -16
- intentkit/core/engine.py +16 -7
- intentkit/core/scheduler.py +8 -8
- intentkit/models/agent.py +109 -94
- intentkit/models/agent_schema.json +6 -9
- intentkit/models/llm.csv +15 -12
- intentkit/models/skill.py +38 -40
- intentkit/skills/acolyt/__init__.py +2 -9
- intentkit/skills/acolyt/base.py +2 -5
- intentkit/skills/aixbt/__init__.py +2 -13
- intentkit/skills/aixbt/base.py +0 -4
- intentkit/skills/aixbt/projects.py +1 -2
- intentkit/skills/allora/__init__.py +2 -9
- intentkit/skills/allora/base.py +2 -5
- intentkit/skills/base.py +168 -27
- intentkit/skills/basename/__init__.py +1 -3
- intentkit/skills/carv/__init__.py +116 -121
- intentkit/skills/carv/base.py +184 -185
- intentkit/skills/casino/__init__.py +4 -15
- intentkit/skills/casino/base.py +0 -4
- intentkit/skills/casino/deck_draw.py +4 -6
- intentkit/skills/casino/deck_shuffle.py +5 -4
- intentkit/skills/casino/dice_roll.py +1 -2
- intentkit/skills/cdp/__init__.py +0 -5
- intentkit/skills/cdp/base.py +0 -4
- intentkit/skills/cdp/schema.json +1 -17
- intentkit/skills/chainlist/__init__.py +2 -7
- intentkit/skills/chainlist/base.py +0 -4
- intentkit/skills/common/__init__.py +2 -9
- intentkit/skills/common/base.py +0 -4
- intentkit/skills/cookiefun/__init__.py +6 -9
- intentkit/skills/cookiefun/base.py +0 -4
- intentkit/skills/cryptocompare/__init__.py +7 -24
- intentkit/skills/cryptocompare/base.py +4 -18
- intentkit/skills/cryptocompare/fetch_news.py +1 -1
- intentkit/skills/cryptocompare/fetch_price.py +1 -1
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +1 -1
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +1 -1
- intentkit/skills/cryptocompare/fetch_top_volume.py +1 -1
- intentkit/skills/cryptocompare/fetch_trading_signals.py +1 -1
- intentkit/skills/cryptopanic/__init__.py +3 -6
- intentkit/skills/cryptopanic/base.py +53 -55
- intentkit/skills/cryptopanic/fetch_crypto_news.py +0 -2
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +1 -3
- intentkit/skills/dapplooker/__init__.py +2 -9
- intentkit/skills/dapplooker/base.py +2 -5
- intentkit/skills/defillama/__init__.py +24 -74
- intentkit/skills/defillama/base.py +3 -13
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +2 -2
- intentkit/skills/defillama/coins/fetch_block.py +2 -2
- intentkit/skills/defillama/coins/fetch_current_prices.py +2 -2
- intentkit/skills/defillama/coins/fetch_first_price.py +2 -2
- intentkit/skills/defillama/coins/fetch_historical_prices.py +2 -2
- intentkit/skills/defillama/coins/fetch_price_chart.py +2 -2
- intentkit/skills/defillama/coins/fetch_price_percentage.py +2 -2
- intentkit/skills/defillama/fees/fetch_fees_overview.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +2 -2
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +2 -2
- intentkit/skills/defillama/tvl/fetch_chains.py +2 -2
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +2 -2
- intentkit/skills/defillama/tvl/fetch_protocol.py +2 -2
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +2 -2
- intentkit/skills/defillama/tvl/fetch_protocols.py +2 -2
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +2 -2
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +2 -2
- intentkit/skills/defillama/volumes/fetch_options_overview.py +2 -2
- intentkit/skills/defillama/yields/fetch_pool_chart.py +2 -2
- intentkit/skills/defillama/yields/fetch_pools.py +2 -2
- intentkit/skills/dexscreener/__init__.py +97 -102
- intentkit/skills/dexscreener/base.py +125 -130
- intentkit/skills/dexscreener/get_pair_info.py +2 -3
- intentkit/skills/dexscreener/get_token_pairs.py +2 -3
- intentkit/skills/dexscreener/get_tokens_info.py +2 -3
- intentkit/skills/dexscreener/search_token.py +2 -4
- intentkit/skills/dune_analytics/__init__.py +4 -6
- intentkit/skills/dune_analytics/base.py +50 -52
- intentkit/skills/dune_analytics/fetch_kol_buys.py +0 -2
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +0 -2
- intentkit/skills/elfa/__init__.py +5 -18
- intentkit/skills/elfa/base.py +8 -10
- intentkit/skills/enso/__init__.py +9 -29
- intentkit/skills/enso/base.py +3 -6
- intentkit/skills/enso/networks.py +1 -6
- intentkit/skills/enso/route.py +4 -8
- intentkit/skills/enso/tokens.py +2 -12
- intentkit/skills/erc20/__init__.py +1 -5
- intentkit/skills/erc721/__init__.py +1 -3
- intentkit/skills/firecrawl/__init__.py +5 -18
- intentkit/skills/firecrawl/base.py +2 -5
- intentkit/skills/firecrawl/clear.py +3 -6
- intentkit/skills/firecrawl/crawl.py +10 -9
- intentkit/skills/firecrawl/query.py +3 -1
- intentkit/skills/firecrawl/scrape.py +10 -14
- intentkit/skills/firecrawl/utils.py +39 -31
- intentkit/skills/github/__init__.py +2 -7
- intentkit/skills/github/base.py +0 -4
- intentkit/skills/heurist/__init__.py +8 -27
- intentkit/skills/heurist/base.py +2 -5
- intentkit/skills/heurist/image_generation_animagine_xl.py +5 -5
- intentkit/skills/heurist/image_generation_arthemy_comics.py +5 -5
- intentkit/skills/heurist/image_generation_arthemy_real.py +5 -5
- intentkit/skills/heurist/image_generation_braindance.py +5 -5
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +5 -5
- intentkit/skills/heurist/image_generation_flux_1_dev.py +5 -5
- intentkit/skills/heurist/image_generation_sdxl.py +5 -5
- intentkit/skills/http/__init__.py +4 -15
- intentkit/skills/http/base.py +0 -4
- intentkit/skills/lifi/__init__.py +1 -6
- intentkit/skills/lifi/base.py +0 -4
- intentkit/skills/lifi/token_execute.py +1 -4
- intentkit/skills/lifi/token_quote.py +1 -3
- intentkit/skills/moralis/__init__.py +3 -7
- intentkit/skills/moralis/base.py +2 -5
- intentkit/skills/morpho/__init__.py +1 -3
- intentkit/skills/nation/__init__.py +2 -7
- intentkit/skills/nation/base.py +4 -7
- intentkit/skills/openai/__init__.py +5 -18
- intentkit/skills/openai/base.py +8 -10
- intentkit/skills/openai/dalle_image_generation.py +2 -5
- intentkit/skills/openai/gpt_image_generation.py +2 -5
- intentkit/skills/openai/gpt_image_to_image.py +2 -5
- intentkit/skills/openai/image_to_text.py +2 -5
- intentkit/skills/portfolio/__init__.py +11 -35
- intentkit/skills/portfolio/base.py +2 -5
- intentkit/skills/pyth/__init__.py +1 -5
- intentkit/skills/slack/__init__.py +5 -17
- intentkit/skills/slack/base.py +0 -4
- intentkit/skills/supabase/__init__.py +7 -23
- intentkit/skills/supabase/base.py +0 -4
- intentkit/skills/superfluid/__init__.py +1 -3
- intentkit/skills/system/__init__.py +7 -24
- intentkit/skills/system/add_autonomous_task.py +2 -2
- intentkit/skills/system/delete_autonomous_task.py +2 -2
- intentkit/skills/system/edit_autonomous_task.py +2 -4
- intentkit/skills/system/list_autonomous_tasks.py +2 -2
- intentkit/skills/system/read_agent_api_key.py +6 -4
- intentkit/skills/system/regenerate_agent_api_key.py +6 -4
- intentkit/skills/tavily/__init__.py +3 -12
- intentkit/skills/tavily/base.py +2 -5
- intentkit/skills/tavily/tavily_extract.py +1 -2
- intentkit/skills/tavily/tavily_search.py +3 -3
- intentkit/skills/token/__init__.py +5 -10
- intentkit/skills/token/base.py +2 -6
- intentkit/skills/twitter/__init__.py +11 -35
- intentkit/skills/twitter/base.py +18 -29
- intentkit/skills/twitter/follow_user.py +1 -4
- intentkit/skills/twitter/get_mentions.py +2 -8
- intentkit/skills/twitter/get_timeline.py +3 -10
- intentkit/skills/twitter/get_user_by_username.py +1 -4
- intentkit/skills/twitter/get_user_tweets.py +3 -10
- intentkit/skills/twitter/like_tweet.py +1 -4
- intentkit/skills/twitter/post_tweet.py +3 -5
- intentkit/skills/twitter/reply_tweet.py +3 -5
- intentkit/skills/twitter/retweet.py +1 -4
- intentkit/skills/twitter/search_tweets.py +3 -10
- intentkit/skills/unrealspeech/__init__.py +2 -7
- intentkit/skills/unrealspeech/base.py +0 -4
- intentkit/skills/venice_audio/__init__.py +99 -106
- intentkit/skills/venice_audio/base.py +118 -121
- intentkit/skills/venice_audio/venice_audio.py +1 -5
- intentkit/skills/venice_image/__init__.py +147 -154
- intentkit/skills/venice_image/base.py +185 -192
- intentkit/skills/web_scraper/__init__.py +5 -18
- intentkit/skills/web_scraper/base.py +20 -4
- intentkit/skills/web_scraper/document_indexer.py +6 -4
- intentkit/skills/web_scraper/scrape_and_index.py +11 -10
- intentkit/skills/web_scraper/utils.py +38 -38
- intentkit/skills/web_scraper/website_indexer.py +7 -8
- intentkit/skills/weth/__init__.py +1 -5
- intentkit/skills/wow/__init__.py +1 -5
- intentkit/skills/xmtp/__init__.py +4 -15
- {intentkit-0.8.11.dev1.dist-info → intentkit-0.8.12.dist-info}/METADATA +1 -1
- {intentkit-0.8.11.dev1.dist-info → intentkit-0.8.12.dist-info}/RECORD +183 -183
- {intentkit-0.8.11.dev1.dist-info → intentkit-0.8.12.dist-info}/WHEEL +0 -0
- {intentkit-0.8.11.dev1.dist-info → intentkit-0.8.12.dist-info}/licenses/LICENSE +0 -0
|
@@ -50,10 +50,9 @@ class GetPairInfo(DexScreenerBaseTool):
|
|
|
50
50
|
"""Implementation to get specific pair information."""
|
|
51
51
|
|
|
52
52
|
# Apply rate limiting
|
|
53
|
-
await self.
|
|
54
|
-
user_id=f"{self.category}{self.name}",
|
|
53
|
+
await self.global_rate_limit_by_skill(
|
|
55
54
|
limit=RATE_LIMITS["pairs"],
|
|
56
|
-
|
|
55
|
+
seconds=60,
|
|
57
56
|
)
|
|
58
57
|
|
|
59
58
|
logger.info(
|
|
@@ -55,10 +55,9 @@ class GetTokenPairs(DexScreenerBaseTool):
|
|
|
55
55
|
"""Implementation to get all pairs for a specific token."""
|
|
56
56
|
|
|
57
57
|
# Apply rate limiting
|
|
58
|
-
await self.
|
|
59
|
-
user_id=f"{self.category}{self.name}",
|
|
58
|
+
await self.global_rate_limit_by_skill(
|
|
60
59
|
limit=RATE_LIMITS["token_pairs"],
|
|
61
|
-
|
|
60
|
+
seconds=60,
|
|
62
61
|
)
|
|
63
62
|
|
|
64
63
|
logger.info(
|
|
@@ -75,10 +75,9 @@ class GetTokensInfo(DexScreenerBaseTool):
|
|
|
75
75
|
"""Implementation to get information for multiple tokens."""
|
|
76
76
|
|
|
77
77
|
# Apply rate limiting
|
|
78
|
-
await self.
|
|
79
|
-
user_id=f"{self.category}{self.name}",
|
|
78
|
+
await self.global_rate_limit_by_skill(
|
|
80
79
|
limit=RATE_LIMITS["tokens"],
|
|
81
|
-
|
|
80
|
+
seconds=60,
|
|
82
81
|
)
|
|
83
82
|
|
|
84
83
|
logger.info(
|
|
@@ -72,11 +72,9 @@ class SearchToken(DexScreenerBaseTool):
|
|
|
72
72
|
|
|
73
73
|
# dexscreener 300 request per minute (across all user) based on dexscreener docs
|
|
74
74
|
# https://docs.dexscreener.com/api/reference#get-latest-dex-search
|
|
75
|
-
await self.
|
|
76
|
-
# using hardcoded user_id to make sure it limit across all users
|
|
77
|
-
user_id=f"{self.category}{self.name}",
|
|
75
|
+
await self.global_rate_limit_by_skill(
|
|
78
76
|
limit=300,
|
|
79
|
-
|
|
77
|
+
seconds=60,
|
|
80
78
|
)
|
|
81
79
|
|
|
82
80
|
sort_by = sort_by or SortBy.LIQUIDITY
|
|
@@ -6,7 +6,6 @@ Loads and initializes skills for fetching data from Dune Analytics API.
|
|
|
6
6
|
import logging
|
|
7
7
|
from typing import Dict, List, Optional, TypedDict
|
|
8
8
|
|
|
9
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
10
9
|
from intentkit.skills.base import SkillConfig, SkillState
|
|
11
10
|
from intentkit.skills.dune_analytics.base import DuneBaseTool
|
|
12
11
|
|
|
@@ -33,7 +32,6 @@ class Config(SkillConfig):
|
|
|
33
32
|
async def get_skills(
|
|
34
33
|
config: Config,
|
|
35
34
|
is_private: bool,
|
|
36
|
-
store: SkillStoreABC,
|
|
37
35
|
**kwargs,
|
|
38
36
|
) -> List[DuneBaseTool]:
|
|
39
37
|
"""Load Dune Analytics skills based on configuration.
|
|
@@ -59,7 +57,7 @@ async def get_skills(
|
|
|
59
57
|
|
|
60
58
|
loaded_skills = []
|
|
61
59
|
for name in available_skills:
|
|
62
|
-
skill = get_dune_skill(name
|
|
60
|
+
skill = get_dune_skill(name)
|
|
63
61
|
if skill:
|
|
64
62
|
logger.info("Successfully loaded skill: %s", name)
|
|
65
63
|
loaded_skills.append(skill)
|
|
@@ -69,7 +67,7 @@ async def get_skills(
|
|
|
69
67
|
return loaded_skills
|
|
70
68
|
|
|
71
69
|
|
|
72
|
-
def get_dune_skill(name: str
|
|
70
|
+
def get_dune_skill(name: str) -> Optional[DuneBaseTool]:
|
|
73
71
|
"""Retrieve a Dune Analytics skill instance by name.
|
|
74
72
|
|
|
75
73
|
Args:
|
|
@@ -87,11 +85,11 @@ def get_dune_skill(name: str, store: SkillStoreABC) -> Optional[DuneBaseTool]:
|
|
|
87
85
|
if name == "fetch_nation_metrics":
|
|
88
86
|
from .fetch_nation_metrics import FetchNationMetrics
|
|
89
87
|
|
|
90
|
-
_skill_cache[name] = FetchNationMetrics(
|
|
88
|
+
_skill_cache[name] = FetchNationMetrics()
|
|
91
89
|
elif name == "fetch_kol_buys":
|
|
92
90
|
from .fetch_kol_buys import FetchKOLBuys
|
|
93
91
|
|
|
94
|
-
_skill_cache[name] = FetchKOLBuys(
|
|
92
|
+
_skill_cache[name] = FetchKOLBuys()
|
|
95
93
|
else:
|
|
96
94
|
logger.warning("Unknown Dune Analytics skill: %s", name)
|
|
97
95
|
return None
|
|
@@ -1,52 +1,50 @@
|
|
|
1
|
-
"""Base module for Dune Analytics skills.
|
|
2
|
-
|
|
3
|
-
Provides shared functionality for interacting with the Dune Analytics API.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from typing import Type
|
|
7
|
-
|
|
8
|
-
from langchain_core.tools.base import ToolException
|
|
9
|
-
from pydantic import BaseModel, Field
|
|
10
|
-
|
|
11
|
-
from intentkit.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"""Category of the skill."""
|
|
52
|
-
return "dune_analytics"
|
|
1
|
+
"""Base module for Dune Analytics skills.
|
|
2
|
+
|
|
3
|
+
Provides shared functionality for interacting with the Dune Analytics API.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Type
|
|
7
|
+
|
|
8
|
+
from langchain_core.tools.base import ToolException
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
from intentkit.skills.base import IntentKitSkill
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class DuneBaseTool(IntentKitSkill):
|
|
15
|
+
"""Base class for Dune Analytics skills.
|
|
16
|
+
|
|
17
|
+
Offers common functionality like API key retrieval and Dune API interaction.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
name: str = Field(description="Tool name")
|
|
21
|
+
description: str = Field(description="Tool description")
|
|
22
|
+
args_schema: Type[BaseModel]
|
|
23
|
+
|
|
24
|
+
def get_api_key(self) -> str:
|
|
25
|
+
"""Retrieve the Dune Analytics API key from context.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
API key string.
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
ToolException: If the API key is not found.
|
|
32
|
+
"""
|
|
33
|
+
context = self.get_context()
|
|
34
|
+
skill_config = context.agent.skill_config(self.category)
|
|
35
|
+
api_key_provider = skill_config.get("api_key_provider")
|
|
36
|
+
if api_key_provider == "agent_owner":
|
|
37
|
+
api_key = skill_config.get("api_key")
|
|
38
|
+
if api_key:
|
|
39
|
+
return api_key
|
|
40
|
+
else:
|
|
41
|
+
raise ToolException("No api_key found in agent_owner configuration")
|
|
42
|
+
else:
|
|
43
|
+
raise ToolException(
|
|
44
|
+
f"Invalid API key provider: {api_key_provider}. Only 'agent_owner' is supported for Dune Analytics."
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def category(self) -> str:
|
|
49
|
+
"""Category of the skill."""
|
|
50
|
+
return "dune_analytics"
|
|
@@ -9,7 +9,6 @@ import httpx
|
|
|
9
9
|
from pydantic import BaseModel, Field
|
|
10
10
|
from tenacity import retry, stop_after_attempt, wait_exponential
|
|
11
11
|
|
|
12
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
13
12
|
from intentkit.skills.dune_analytics.base import DuneBaseTool
|
|
14
13
|
|
|
15
14
|
BASE_URL = "https://api.dune.com/api/v1/query"
|
|
@@ -49,7 +48,6 @@ class FetchKOLBuys(DuneBaseTool):
|
|
|
49
48
|
"Supports a configurable limit for the number of results. Handles rate limits with retries."
|
|
50
49
|
)
|
|
51
50
|
args_schema: Type[BaseModel] = KOLBuysInput
|
|
52
|
-
skill_store: SkillStoreABC = Field(description="Skill store for data persistence")
|
|
53
51
|
|
|
54
52
|
@retry(
|
|
55
53
|
stop=stop_after_attempt(3), wait=wait_exponential(multiplier=5, min=5, max=60)
|
|
@@ -11,7 +11,6 @@ import httpx
|
|
|
11
11
|
from pydantic import BaseModel, Field
|
|
12
12
|
from tenacity import retry, stop_after_attempt, wait_exponential
|
|
13
13
|
|
|
14
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
15
14
|
from intentkit.skills.dune_analytics.base import DuneBaseTool
|
|
16
15
|
|
|
17
16
|
SUPPORTED_QUERIES = {
|
|
@@ -86,7 +85,6 @@ class FetchNationMetrics(DuneBaseTool):
|
|
|
86
85
|
"Handles rate limits with retries."
|
|
87
86
|
)
|
|
88
87
|
args_schema: Type[BaseModel] = NationMetricsInput
|
|
89
|
-
skill_store: SkillStoreABC = Field(description="Skill store for data persistence")
|
|
90
88
|
|
|
91
89
|
def normalize_metric(self, metric: str) -> str:
|
|
92
90
|
"""Normalize a metric string for matching.
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
from typing import NotRequired, TypedDict
|
|
5
5
|
|
|
6
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
7
6
|
from intentkit.skills.base import SkillConfig, SkillState
|
|
8
7
|
from intentkit.skills.elfa.base import ElfaBaseTool
|
|
9
8
|
from intentkit.skills.elfa.mention import (
|
|
@@ -36,7 +35,6 @@ class Config(SkillConfig):
|
|
|
36
35
|
async def get_skills(
|
|
37
36
|
config: "Config",
|
|
38
37
|
is_private: bool,
|
|
39
|
-
store: SkillStoreABC,
|
|
40
38
|
**_,
|
|
41
39
|
) -> list[ElfaBaseTool]:
|
|
42
40
|
"""Get all Elfa skills.
|
|
@@ -44,7 +42,6 @@ async def get_skills(
|
|
|
44
42
|
Args:
|
|
45
43
|
config: The configuration for Elfa skills.
|
|
46
44
|
is_private: Whether to include private skills.
|
|
47
|
-
store: The skill store for persisting data.
|
|
48
45
|
|
|
49
46
|
Returns:
|
|
50
47
|
A list of Elfa skills.
|
|
@@ -61,7 +58,7 @@ async def get_skills(
|
|
|
61
58
|
# Get each skill using the cached getter
|
|
62
59
|
result = []
|
|
63
60
|
for name in available_skills:
|
|
64
|
-
skill = get_elfa_skill(name
|
|
61
|
+
skill = get_elfa_skill(name)
|
|
65
62
|
if skill:
|
|
66
63
|
result.append(skill)
|
|
67
64
|
return result
|
|
@@ -69,13 +66,11 @@ async def get_skills(
|
|
|
69
66
|
|
|
70
67
|
def get_elfa_skill(
|
|
71
68
|
name: str,
|
|
72
|
-
store: SkillStoreABC,
|
|
73
69
|
) -> ElfaBaseTool:
|
|
74
70
|
"""Get an Elfa skill by name.
|
|
75
71
|
|
|
76
72
|
Args:
|
|
77
73
|
name: The name of the skill to get
|
|
78
|
-
store: The skill store for persisting data
|
|
79
74
|
|
|
80
75
|
Returns:
|
|
81
76
|
The requested Elfa skill
|
|
@@ -83,30 +78,22 @@ def get_elfa_skill(
|
|
|
83
78
|
|
|
84
79
|
if name == "get_top_mentions":
|
|
85
80
|
if name not in _cache:
|
|
86
|
-
_cache[name] = ElfaGetTopMentions(
|
|
87
|
-
skill_store=store,
|
|
88
|
-
)
|
|
81
|
+
_cache[name] = ElfaGetTopMentions()
|
|
89
82
|
return _cache[name]
|
|
90
83
|
|
|
91
84
|
elif name == "search_mentions":
|
|
92
85
|
if name not in _cache:
|
|
93
|
-
_cache[name] = ElfaSearchMentions(
|
|
94
|
-
skill_store=store,
|
|
95
|
-
)
|
|
86
|
+
_cache[name] = ElfaSearchMentions()
|
|
96
87
|
return _cache[name]
|
|
97
88
|
|
|
98
89
|
elif name == "get_trending_tokens":
|
|
99
90
|
if name not in _cache:
|
|
100
|
-
_cache[name] = ElfaGetTrendingTokens(
|
|
101
|
-
skill_store=store,
|
|
102
|
-
)
|
|
91
|
+
_cache[name] = ElfaGetTrendingTokens()
|
|
103
92
|
return _cache[name]
|
|
104
93
|
|
|
105
94
|
elif name == "get_smart_stats":
|
|
106
95
|
if name not in _cache:
|
|
107
|
-
_cache[name] = ElfaGetSmartStats(
|
|
108
|
-
skill_store=store,
|
|
109
|
-
)
|
|
96
|
+
_cache[name] = ElfaGetSmartStats()
|
|
110
97
|
return _cache[name]
|
|
111
98
|
|
|
112
99
|
else:
|
intentkit/skills/elfa/base.py
CHANGED
|
@@ -3,7 +3,7 @@ from typing import Type
|
|
|
3
3
|
from langchain_core.tools.base import ToolException
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
6
|
-
from intentkit.
|
|
6
|
+
from intentkit.config.config import config
|
|
7
7
|
from intentkit.skills.base import IntentKitSkill
|
|
8
8
|
|
|
9
9
|
base_url = "https://api.elfa.ai/v2"
|
|
@@ -15,23 +15,21 @@ class ElfaBaseTool(IntentKitSkill):
|
|
|
15
15
|
name: str = Field(description="The name of the tool")
|
|
16
16
|
description: str = Field(description="A description of what the tool does")
|
|
17
17
|
args_schema: Type[BaseModel]
|
|
18
|
-
skill_store: SkillStoreABC = Field(
|
|
19
|
-
description="The skill store for persisting data"
|
|
20
|
-
)
|
|
21
18
|
|
|
22
19
|
def get_api_key(self) -> str:
|
|
23
20
|
context = self.get_context()
|
|
24
21
|
skill_config = context.agent.skill_config(self.category)
|
|
25
22
|
api_key_provider = skill_config.get("api_key_provider")
|
|
26
23
|
if api_key_provider == "platform":
|
|
27
|
-
|
|
24
|
+
if not config.elfa_api_key:
|
|
25
|
+
raise ToolException("Elfa API key is not configured")
|
|
26
|
+
return config.elfa_api_key
|
|
28
27
|
# for backward compatibility, may only have api_key in skill_config
|
|
29
|
-
|
|
28
|
+
if skill_config.get("api_key"):
|
|
30
29
|
return skill_config.get("api_key")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
30
|
+
raise ToolException(
|
|
31
|
+
f"Invalid API key provider: {api_key_provider}, or no api_key in config"
|
|
32
|
+
)
|
|
35
33
|
|
|
36
34
|
@property
|
|
37
35
|
def category(self) -> str:
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
from typing import List, NotRequired, TypedDict
|
|
5
5
|
|
|
6
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
7
6
|
from intentkit.skills.base import SkillConfig, SkillState
|
|
8
7
|
from intentkit.skills.enso.base import EnsoBaseTool
|
|
9
8
|
from intentkit.skills.enso.best_yield import EnsoGetBestYield
|
|
@@ -42,7 +41,6 @@ class Config(SkillConfig):
|
|
|
42
41
|
async def get_skills(
|
|
43
42
|
config: Config,
|
|
44
43
|
is_private: bool,
|
|
45
|
-
store: SkillStoreABC,
|
|
46
44
|
**_,
|
|
47
45
|
) -> list[EnsoBaseTool]:
|
|
48
46
|
"""Get all Enso skills."""
|
|
@@ -58,7 +56,7 @@ async def get_skills(
|
|
|
58
56
|
# Get each skill using the cached getter
|
|
59
57
|
result = []
|
|
60
58
|
for name in available_skills:
|
|
61
|
-
skill = get_enso_skill(name
|
|
59
|
+
skill = get_enso_skill(name)
|
|
62
60
|
if skill:
|
|
63
61
|
result.append(skill)
|
|
64
62
|
return result
|
|
@@ -66,49 +64,31 @@ async def get_skills(
|
|
|
66
64
|
|
|
67
65
|
def get_enso_skill(
|
|
68
66
|
name: str,
|
|
69
|
-
skill_store: SkillStoreABC,
|
|
70
67
|
) -> EnsoBaseTool:
|
|
71
68
|
"""Get an Enso skill by name.
|
|
72
69
|
|
|
73
70
|
Args:
|
|
74
71
|
name: The name of the skill to get
|
|
75
|
-
skill_store: The skill store for persisting data
|
|
76
72
|
|
|
77
73
|
Returns:
|
|
78
74
|
The requested Enso skill
|
|
79
75
|
"""
|
|
80
76
|
if name == "get_networks":
|
|
81
|
-
return EnsoGetNetworks(
|
|
82
|
-
skill_store=skill_store,
|
|
83
|
-
)
|
|
77
|
+
return EnsoGetNetworks()
|
|
84
78
|
if name == "get_tokens":
|
|
85
|
-
return EnsoGetTokens(
|
|
86
|
-
skill_store=skill_store,
|
|
87
|
-
)
|
|
79
|
+
return EnsoGetTokens()
|
|
88
80
|
if name == "get_prices":
|
|
89
|
-
return EnsoGetPrices(
|
|
90
|
-
skill_store=skill_store,
|
|
91
|
-
)
|
|
81
|
+
return EnsoGetPrices()
|
|
92
82
|
if name == "get_wallet_approvals":
|
|
93
|
-
return EnsoGetWalletApprovals(
|
|
94
|
-
skill_store=skill_store,
|
|
95
|
-
)
|
|
83
|
+
return EnsoGetWalletApprovals()
|
|
96
84
|
if name == "get_wallet_balances":
|
|
97
|
-
return EnsoGetWalletBalances(
|
|
98
|
-
skill_store=skill_store,
|
|
99
|
-
)
|
|
85
|
+
return EnsoGetWalletBalances()
|
|
100
86
|
if name == "wallet_approve":
|
|
101
|
-
return EnsoWalletApprove(
|
|
102
|
-
skill_store=skill_store,
|
|
103
|
-
)
|
|
87
|
+
return EnsoWalletApprove()
|
|
104
88
|
if name == "route_shortcut":
|
|
105
|
-
return EnsoRouteShortcut(
|
|
106
|
-
skill_store=skill_store,
|
|
107
|
-
)
|
|
89
|
+
return EnsoRouteShortcut()
|
|
108
90
|
if name == "get_best_yield":
|
|
109
|
-
return EnsoGetBestYield(
|
|
110
|
-
skill_store=skill_store,
|
|
111
|
-
)
|
|
91
|
+
return EnsoGetBestYield()
|
|
112
92
|
else:
|
|
113
93
|
logger.warning(f"Unknown Enso skill: {name}")
|
|
114
94
|
return None
|
intentkit/skills/enso/base.py
CHANGED
|
@@ -6,8 +6,8 @@ from langchain_core.tools.base import ToolException
|
|
|
6
6
|
from pydantic import BaseModel, Field
|
|
7
7
|
|
|
8
8
|
from intentkit.abstracts.graph import AgentContext
|
|
9
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
10
9
|
from intentkit.clients import get_wallet_provider as get_agent_wallet_provider
|
|
10
|
+
from intentkit.config.config import config
|
|
11
11
|
from intentkit.skills.base import IntentKitSkill
|
|
12
12
|
from intentkit.utils.chain import ChainProvider, Network, network_to_id
|
|
13
13
|
|
|
@@ -20,9 +20,6 @@ class EnsoBaseTool(IntentKitSkill):
|
|
|
20
20
|
name: str = Field(description="The name of the tool")
|
|
21
21
|
description: str = Field(description="A description of what the tool does")
|
|
22
22
|
args_schema: Type[BaseModel]
|
|
23
|
-
skill_store: SkillStoreABC = Field(
|
|
24
|
-
description="The skill store for persisting data"
|
|
25
|
-
)
|
|
26
23
|
|
|
27
24
|
async def get_wallet_provider(self, context: AgentContext) -> CdpEvmWalletProvider:
|
|
28
25
|
"""Get the wallet provider from the CDP client.
|
|
@@ -40,7 +37,7 @@ class EnsoBaseTool(IntentKitSkill):
|
|
|
40
37
|
return provider.get_address()
|
|
41
38
|
|
|
42
39
|
def get_chain_provider(self, context: AgentContext) -> Optional[ChainProvider]:
|
|
43
|
-
return
|
|
40
|
+
return config.chain_provider
|
|
44
41
|
|
|
45
42
|
def get_main_tokens(self, context: AgentContext) -> list[str]:
|
|
46
43
|
skill_config = context.agent.skill_config(self.category)
|
|
@@ -52,7 +49,7 @@ class EnsoBaseTool(IntentKitSkill):
|
|
|
52
49
|
skill_config = context.agent.skill_config(self.category)
|
|
53
50
|
api_key_provider = skill_config.get("api_key_provider")
|
|
54
51
|
if api_key_provider == "platform":
|
|
55
|
-
return
|
|
52
|
+
return config.enso_api_token
|
|
56
53
|
# for backward compatibility, may only have api_token in skill_config
|
|
57
54
|
elif skill_config.get("api_token"):
|
|
58
55
|
return skill_config.get("api_token")
|
|
@@ -83,12 +83,7 @@ class EnsoGetNetworks(EnsoBaseTool):
|
|
|
83
83
|
exclude_none=True
|
|
84
84
|
)
|
|
85
85
|
|
|
86
|
-
await self.
|
|
87
|
-
context.agent_id,
|
|
88
|
-
"enso_get_networks",
|
|
89
|
-
"networks",
|
|
90
|
-
networks_memory,
|
|
91
|
-
)
|
|
86
|
+
await self.save_agent_skill_data("networks", networks_memory)
|
|
92
87
|
|
|
93
88
|
return EnsoGetNetworksOutput(res=networks)
|
|
94
89
|
except httpx.RequestError as req_err:
|
intentkit/skills/enso/route.py
CHANGED
|
@@ -181,7 +181,6 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
181
181
|
"""
|
|
182
182
|
|
|
183
183
|
context = self.get_context()
|
|
184
|
-
agent_id = context.agent_id
|
|
185
184
|
resolved_chain_id = self.resolve_chain_id(context, chainId)
|
|
186
185
|
api_token = self.get_api_token(context)
|
|
187
186
|
# Use the wallet provider to send the transaction
|
|
@@ -191,8 +190,8 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
191
190
|
async with httpx.AsyncClient() as client:
|
|
192
191
|
try:
|
|
193
192
|
network_name = None
|
|
194
|
-
networks = await self.
|
|
195
|
-
|
|
193
|
+
networks = await self.get_agent_skill_data_raw(
|
|
194
|
+
"enso_get_networks", "networks"
|
|
196
195
|
)
|
|
197
196
|
|
|
198
197
|
if networks:
|
|
@@ -203,9 +202,7 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
203
202
|
else None
|
|
204
203
|
)
|
|
205
204
|
if network_name is None:
|
|
206
|
-
networks = await EnsoGetNetworks(
|
|
207
|
-
skill_store=self.skill_store,
|
|
208
|
-
).arun()
|
|
205
|
+
networks = await EnsoGetNetworks().arun()
|
|
209
206
|
|
|
210
207
|
for network in networks.res:
|
|
211
208
|
if network.id == resolved_chain_id:
|
|
@@ -221,8 +218,7 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
221
218
|
"Authorization": f"Bearer {api_token}",
|
|
222
219
|
}
|
|
223
220
|
|
|
224
|
-
token_decimals = await self.
|
|
225
|
-
agent_id,
|
|
221
|
+
token_decimals = await self.get_agent_skill_data_raw(
|
|
226
222
|
"enso_get_tokens",
|
|
227
223
|
"decimals",
|
|
228
224
|
)
|
intentkit/skills/enso/tokens.py
CHANGED
|
@@ -154,7 +154,6 @@ class EnsoGetTokens(EnsoBaseTool):
|
|
|
154
154
|
url = f"{base_url}/api/v1/tokens"
|
|
155
155
|
|
|
156
156
|
context = self.get_context()
|
|
157
|
-
agent_id = context.agent_id
|
|
158
157
|
resolved_chain_id = self.resolve_chain_id(context, chainId)
|
|
159
158
|
api_token = self.get_api_token(context)
|
|
160
159
|
main_tokens = self.get_main_tokens(context)
|
|
@@ -178,11 +177,7 @@ class EnsoGetTokens(EnsoBaseTool):
|
|
|
178
177
|
response.raise_for_status()
|
|
179
178
|
json_dict = response.json()
|
|
180
179
|
|
|
181
|
-
token_decimals = await self.
|
|
182
|
-
agent_id,
|
|
183
|
-
"enso_get_tokens",
|
|
184
|
-
"decimals",
|
|
185
|
-
)
|
|
180
|
+
token_decimals = await self.get_agent_skill_data("decimals")
|
|
186
181
|
if not token_decimals:
|
|
187
182
|
token_decimals = {}
|
|
188
183
|
|
|
@@ -203,12 +198,7 @@ class EnsoGetTokens(EnsoBaseTool):
|
|
|
203
198
|
if u_token.address:
|
|
204
199
|
token_decimals[u_token.address] = u_token.decimals
|
|
205
200
|
|
|
206
|
-
await self.
|
|
207
|
-
agent_id,
|
|
208
|
-
"enso_get_tokens",
|
|
209
|
-
"decimals",
|
|
210
|
-
token_decimals,
|
|
211
|
-
)
|
|
201
|
+
await self.save_agent_skill_data("decimals", token_decimals)
|
|
212
202
|
|
|
213
203
|
return res
|
|
214
204
|
except httpx.RequestError as req_err:
|
|
@@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, Optional, TypedDict
|
|
|
4
4
|
|
|
5
5
|
from coinbase_agentkit import erc20_action_provider
|
|
6
6
|
|
|
7
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
8
7
|
from intentkit.skills.base import (
|
|
9
8
|
SkillConfig,
|
|
10
9
|
SkillState,
|
|
@@ -31,7 +30,6 @@ class Config(SkillConfig):
|
|
|
31
30
|
async def get_skills(
|
|
32
31
|
config: "Config",
|
|
33
32
|
is_private: bool,
|
|
34
|
-
store: SkillStoreABC,
|
|
35
33
|
agent_id: str,
|
|
36
34
|
agent: Optional["Agent"] = None,
|
|
37
35
|
**_,
|
|
@@ -45,9 +43,7 @@ async def get_skills(
|
|
|
45
43
|
if state == "public" or (state == "private" and is_private):
|
|
46
44
|
available_skills.append(skill_name)
|
|
47
45
|
|
|
48
|
-
actions = await get_agentkit_actions(
|
|
49
|
-
agent_id, store, [erc20_action_provider], agent=agent
|
|
50
|
-
)
|
|
46
|
+
actions = await get_agentkit_actions(agent_id, [erc20_action_provider], agent=agent)
|
|
51
47
|
tools: list[ERC20BaseTool] = []
|
|
52
48
|
for skill in available_skills:
|
|
53
49
|
for action in actions:
|
|
@@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, Optional, TypedDict
|
|
|
4
4
|
|
|
5
5
|
from coinbase_agentkit import erc721_action_provider
|
|
6
6
|
|
|
7
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
8
7
|
from intentkit.skills.base import (
|
|
9
8
|
SkillConfig,
|
|
10
9
|
SkillState,
|
|
@@ -32,7 +31,6 @@ class Config(SkillConfig):
|
|
|
32
31
|
async def get_skills(
|
|
33
32
|
config: "Config",
|
|
34
33
|
is_private: bool,
|
|
35
|
-
store: SkillStoreABC,
|
|
36
34
|
agent_id: str,
|
|
37
35
|
agent: Optional["Agent"] = None,
|
|
38
36
|
**_,
|
|
@@ -47,7 +45,7 @@ async def get_skills(
|
|
|
47
45
|
available_skills.append(skill_name)
|
|
48
46
|
|
|
49
47
|
actions = await get_agentkit_actions(
|
|
50
|
-
agent_id,
|
|
48
|
+
agent_id, [erc721_action_provider], agent=agent
|
|
51
49
|
)
|
|
52
50
|
tools: list[ERC721BaseTool] = []
|
|
53
51
|
for skill in available_skills:
|