intentkit 0.8.6.dev2__py3-none-any.whl → 0.8.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of intentkit might be problematic. Click here for more details.
- intentkit/__init__.py +1 -1
- intentkit/abstracts/agent.py +4 -5
- intentkit/abstracts/engine.py +5 -5
- intentkit/abstracts/graph.py +10 -5
- intentkit/abstracts/skill.py +6 -144
- intentkit/abstracts/twitter.py +4 -5
- intentkit/clients/__init__.py +3 -2
- intentkit/clients/cdp.py +53 -92
- intentkit/clients/twitter.py +56 -57
- intentkit/clients/web3.py +1 -3
- intentkit/config/config.py +5 -0
- intentkit/core/agent.py +16 -388
- intentkit/core/asset.py +64 -18
- intentkit/core/client.py +1 -1
- intentkit/core/credit.py +19 -20
- intentkit/core/engine.py +26 -11
- intentkit/core/node.py +2 -1
- intentkit/core/prompt.py +53 -15
- intentkit/core/scheduler.py +9 -9
- intentkit/core/statistics.py +6 -7
- intentkit/models/agent.py +256 -176
- intentkit/models/agent_data.py +62 -36
- intentkit/models/agent_schema.json +6 -9
- intentkit/models/app_setting.py +6 -6
- intentkit/models/chat.py +28 -24
- intentkit/models/conversation.py +8 -8
- intentkit/models/credit.py +62 -64
- intentkit/models/db.py +8 -7
- intentkit/models/db_mig.py +2 -2
- intentkit/models/llm.csv +15 -12
- intentkit/models/llm.py +18 -16
- intentkit/models/redis.py +2 -3
- intentkit/models/skill.py +62 -66
- intentkit/models/skills.csv +30 -26
- intentkit/models/user.py +46 -21
- intentkit/skills/acolyt/__init__.py +2 -9
- intentkit/skills/acolyt/ask.py +3 -4
- intentkit/skills/acolyt/base.py +4 -9
- intentkit/skills/aixbt/__init__.py +2 -13
- intentkit/skills/aixbt/base.py +1 -7
- intentkit/skills/aixbt/projects.py +14 -15
- intentkit/skills/allora/__init__.py +2 -9
- intentkit/skills/allora/base.py +4 -9
- intentkit/skills/allora/price.py +3 -4
- intentkit/skills/base.py +175 -52
- intentkit/skills/basename/__init__.py +4 -8
- intentkit/skills/carv/__init__.py +115 -121
- intentkit/skills/carv/base.py +184 -185
- intentkit/skills/carv/fetch_news.py +3 -3
- intentkit/skills/carv/onchain_query.py +4 -4
- intentkit/skills/carv/token_info_and_price.py +5 -5
- intentkit/skills/casino/__init__.py +4 -15
- intentkit/skills/casino/base.py +1 -7
- intentkit/skills/casino/deck_draw.py +5 -8
- intentkit/skills/casino/deck_shuffle.py +6 -6
- intentkit/skills/casino/dice_roll.py +2 -4
- intentkit/skills/cdp/__init__.py +3 -10
- intentkit/skills/cdp/base.py +1 -7
- intentkit/skills/cdp/schema.json +1 -17
- intentkit/skills/chainlist/__init__.py +2 -7
- intentkit/skills/chainlist/base.py +1 -7
- intentkit/skills/chainlist/chain_lookup.py +18 -18
- intentkit/skills/common/__init__.py +2 -9
- intentkit/skills/common/base.py +1 -7
- intentkit/skills/common/current_time.py +1 -2
- intentkit/skills/cookiefun/__init__.py +6 -9
- intentkit/skills/cookiefun/base.py +2 -7
- intentkit/skills/cookiefun/get_account_details.py +7 -7
- intentkit/skills/cookiefun/get_account_feed.py +19 -19
- intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
- intentkit/skills/cookiefun/get_sectors.py +3 -3
- intentkit/skills/cookiefun/search_accounts.py +9 -9
- intentkit/skills/cryptocompare/__init__.py +7 -24
- intentkit/skills/cryptocompare/api.py +2 -3
- intentkit/skills/cryptocompare/base.py +10 -24
- intentkit/skills/cryptocompare/fetch_news.py +4 -5
- intentkit/skills/cryptocompare/fetch_price.py +6 -7
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
- intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
- intentkit/skills/cryptopanic/__init__.py +7 -10
- intentkit/skills/cryptopanic/base.py +51 -55
- intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
- intentkit/skills/dapplooker/__init__.py +2 -9
- intentkit/skills/dapplooker/base.py +4 -9
- intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
- intentkit/skills/defillama/__init__.py +24 -74
- intentkit/skills/defillama/api.py +6 -9
- intentkit/skills/defillama/base.py +8 -19
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_block.py +6 -8
- intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
- intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
- intentkit/skills/defillama/config/chains.py +1 -3
- intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
- intentkit/skills/defillama/tests/api_integration.test.py +1 -1
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
- intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
- intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
- intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
- intentkit/skills/defillama/yields/fetch_pools.py +26 -30
- intentkit/skills/dexscreener/__init__.py +97 -102
- intentkit/skills/dexscreener/base.py +125 -130
- intentkit/skills/dexscreener/get_pair_info.py +4 -5
- intentkit/skills/dexscreener/get_token_pairs.py +4 -5
- intentkit/skills/dexscreener/get_tokens_info.py +7 -8
- intentkit/skills/dexscreener/model/search_token_response.py +80 -82
- intentkit/skills/dexscreener/search_token.py +182 -184
- intentkit/skills/dexscreener/utils.py +15 -14
- intentkit/skills/dune_analytics/__init__.py +7 -9
- intentkit/skills/dune_analytics/base.py +48 -52
- intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
- intentkit/skills/elfa/__init__.py +5 -18
- intentkit/skills/elfa/base.py +10 -14
- intentkit/skills/elfa/mention.py +19 -21
- intentkit/skills/elfa/stats.py +4 -4
- intentkit/skills/elfa/tokens.py +12 -12
- intentkit/skills/elfa/utils.py +26 -28
- intentkit/skills/enso/__init__.py +11 -31
- intentkit/skills/enso/base.py +9 -15
- intentkit/skills/enso/best_yield.py +5 -7
- intentkit/skills/enso/networks.py +3 -9
- intentkit/skills/enso/prices.py +2 -4
- intentkit/skills/enso/route.py +6 -12
- intentkit/skills/enso/tokens.py +4 -16
- intentkit/skills/enso/wallet.py +6 -6
- intentkit/skills/erc20/__init__.py +5 -11
- intentkit/skills/erc721/__init__.py +5 -9
- intentkit/skills/firecrawl/__init__.py +5 -18
- intentkit/skills/firecrawl/base.py +4 -9
- intentkit/skills/firecrawl/clear.py +4 -8
- intentkit/skills/firecrawl/crawl.py +19 -19
- intentkit/skills/firecrawl/query.py +4 -3
- intentkit/skills/firecrawl/scrape.py +17 -22
- intentkit/skills/firecrawl/utils.py +50 -42
- intentkit/skills/github/__init__.py +2 -7
- intentkit/skills/github/base.py +1 -7
- intentkit/skills/github/github_search.py +1 -2
- intentkit/skills/heurist/__init__.py +8 -27
- intentkit/skills/heurist/base.py +4 -9
- intentkit/skills/heurist/image_generation_animagine_xl.py +12 -13
- intentkit/skills/heurist/image_generation_arthemy_comics.py +12 -13
- intentkit/skills/heurist/image_generation_arthemy_real.py +12 -13
- intentkit/skills/heurist/image_generation_braindance.py +12 -13
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +12 -13
- intentkit/skills/heurist/image_generation_flux_1_dev.py +12 -13
- intentkit/skills/heurist/image_generation_sdxl.py +12 -13
- intentkit/skills/http/__init__.py +4 -15
- intentkit/skills/http/base.py +1 -7
- intentkit/skills/http/get.py +21 -16
- intentkit/skills/http/post.py +23 -18
- intentkit/skills/http/put.py +23 -18
- intentkit/skills/lifi/__init__.py +5 -10
- intentkit/skills/lifi/base.py +1 -7
- intentkit/skills/lifi/token_execute.py +14 -17
- intentkit/skills/lifi/token_quote.py +7 -9
- intentkit/skills/lifi/utils.py +16 -16
- intentkit/skills/moralis/__init__.py +6 -10
- intentkit/skills/moralis/api.py +6 -7
- intentkit/skills/moralis/base.py +5 -10
- intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
- intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
- intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
- intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
- intentkit/skills/morpho/__init__.py +5 -9
- intentkit/skills/nation/__init__.py +4 -9
- intentkit/skills/nation/base.py +5 -10
- intentkit/skills/nation/nft_check.py +3 -4
- intentkit/skills/onchain.py +23 -0
- intentkit/skills/openai/__init__.py +17 -18
- intentkit/skills/openai/base.py +10 -14
- intentkit/skills/openai/dalle_image_generation.py +3 -8
- intentkit/skills/openai/gpt_avatar_generator.py +102 -0
- intentkit/skills/openai/gpt_image_generation.py +4 -8
- intentkit/skills/openai/gpt_image_mini_generator.py +91 -0
- intentkit/skills/openai/gpt_image_to_image.py +4 -8
- intentkit/skills/openai/image_to_text.py +3 -7
- intentkit/skills/openai/schema.json +32 -0
- intentkit/skills/portfolio/__init__.py +11 -35
- intentkit/skills/portfolio/base.py +33 -19
- intentkit/skills/portfolio/token_balances.py +21 -21
- intentkit/skills/portfolio/wallet_approvals.py +17 -18
- intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
- intentkit/skills/portfolio/wallet_history.py +31 -31
- intentkit/skills/portfolio/wallet_net_worth.py +13 -13
- intentkit/skills/portfolio/wallet_nfts.py +19 -19
- intentkit/skills/portfolio/wallet_profitability.py +18 -18
- intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
- intentkit/skills/portfolio/wallet_stats.py +3 -3
- intentkit/skills/portfolio/wallet_swaps.py +19 -19
- intentkit/skills/pyth/__init__.py +4 -10
- intentkit/skills/skills.toml +4 -0
- intentkit/skills/slack/__init__.py +5 -17
- intentkit/skills/slack/base.py +3 -9
- intentkit/skills/slack/get_channel.py +8 -8
- intentkit/skills/slack/get_message.py +9 -9
- intentkit/skills/slack/schedule_message.py +5 -5
- intentkit/skills/slack/send_message.py +3 -5
- intentkit/skills/supabase/__init__.py +7 -23
- intentkit/skills/supabase/base.py +1 -7
- intentkit/skills/supabase/delete_data.py +4 -4
- intentkit/skills/supabase/fetch_data.py +12 -12
- intentkit/skills/supabase/insert_data.py +4 -4
- intentkit/skills/supabase/invoke_function.py +6 -6
- intentkit/skills/supabase/update_data.py +6 -6
- intentkit/skills/supabase/upsert_data.py +4 -4
- intentkit/skills/superfluid/__init__.py +5 -9
- intentkit/skills/system/__init__.py +7 -24
- intentkit/skills/system/add_autonomous_task.py +10 -12
- intentkit/skills/system/delete_autonomous_task.py +2 -2
- intentkit/skills/system/edit_autonomous_task.py +14 -18
- intentkit/skills/system/list_autonomous_tasks.py +3 -5
- 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 +4 -9
- intentkit/skills/tavily/tavily_extract.py +2 -4
- intentkit/skills/tavily/tavily_search.py +4 -6
- intentkit/skills/token/__init__.py +5 -10
- intentkit/skills/token/base.py +7 -11
- intentkit/skills/token/erc20_transfers.py +19 -19
- intentkit/skills/token/token_analytics.py +3 -3
- intentkit/skills/token/token_price.py +13 -13
- intentkit/skills/token/token_search.py +9 -9
- intentkit/skills/twitter/__init__.py +11 -35
- intentkit/skills/twitter/base.py +22 -34
- intentkit/skills/twitter/follow_user.py +2 -6
- intentkit/skills/twitter/get_mentions.py +5 -12
- intentkit/skills/twitter/get_timeline.py +4 -12
- intentkit/skills/twitter/get_user_by_username.py +2 -6
- intentkit/skills/twitter/get_user_tweets.py +5 -13
- intentkit/skills/twitter/like_tweet.py +2 -6
- intentkit/skills/twitter/post_tweet.py +6 -9
- intentkit/skills/twitter/reply_tweet.py +6 -9
- intentkit/skills/twitter/retweet.py +2 -6
- intentkit/skills/twitter/search_tweets.py +4 -12
- intentkit/skills/unrealspeech/__init__.py +2 -7
- intentkit/skills/unrealspeech/base.py +2 -8
- intentkit/skills/unrealspeech/text_to_speech.py +8 -8
- intentkit/skills/venice_audio/__init__.py +98 -106
- intentkit/skills/venice_audio/base.py +117 -121
- intentkit/skills/venice_audio/input.py +41 -41
- intentkit/skills/venice_audio/venice_audio.py +7 -11
- intentkit/skills/venice_image/__init__.py +147 -154
- intentkit/skills/venice_image/api.py +138 -138
- intentkit/skills/venice_image/base.py +185 -192
- intentkit/skills/venice_image/config.py +33 -35
- intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
- intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
- intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
- intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
- intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
- intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
- intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
- intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
- intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
- intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
- intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
- intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
- intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
- intentkit/skills/venice_image/utils.py +77 -78
- intentkit/skills/web_scraper/__init__.py +5 -18
- intentkit/skills/web_scraper/base.py +21 -7
- intentkit/skills/web_scraper/document_indexer.py +7 -6
- intentkit/skills/web_scraper/scrape_and_index.py +15 -15
- intentkit/skills/web_scraper/utils.py +62 -63
- intentkit/skills/web_scraper/website_indexer.py +17 -19
- intentkit/skills/weth/__init__.py +5 -11
- intentkit/skills/wow/__init__.py +5 -11
- intentkit/skills/x402/__init__.py +61 -0
- intentkit/skills/x402/ask_agent.py +98 -0
- intentkit/skills/x402/base.py +99 -0
- intentkit/skills/x402/http_request.py +117 -0
- intentkit/skills/x402/schema.json +45 -0
- intentkit/skills/x402/x402.webp +0 -0
- intentkit/skills/xmtp/__init__.py +4 -15
- intentkit/skills/xmtp/base.py +5 -5
- intentkit/skills/xmtp/price.py +6 -6
- intentkit/skills/xmtp/swap.py +6 -8
- intentkit/skills/xmtp/transfer.py +4 -6
- intentkit/utils/error.py +2 -2
- intentkit/utils/logging.py +2 -4
- intentkit/utils/s3.py +8 -9
- intentkit/utils/schema.py +100 -0
- intentkit/utils/slack_alert.py +7 -8
- {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +3 -4
- intentkit-0.8.17.dist-info/RECORD +466 -0
- intentkit/models/generator.py +0 -347
- intentkit-0.8.6.dev2.dist-info/RECORD +0 -457
- {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
- {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
@@ -19,35 +19,35 @@ class ERC20TransfersInput(BaseModel):
|
|
|
19
19
|
description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
|
|
20
20
|
default=DEFAULT_CHAIN,
|
|
21
21
|
)
|
|
22
|
-
contract_addresses:
|
|
22
|
+
contract_addresses: list[str] | None = Field(
|
|
23
23
|
description="List of contract addresses of transfers to filter by.",
|
|
24
24
|
default=None,
|
|
25
25
|
)
|
|
26
|
-
from_block:
|
|
26
|
+
from_block: int | None = Field(
|
|
27
27
|
description="The minimum block number from which to get the transactions.",
|
|
28
28
|
default=None,
|
|
29
29
|
)
|
|
30
|
-
to_block:
|
|
30
|
+
to_block: int | None = Field(
|
|
31
31
|
description="The maximum block number from which to get the transactions.",
|
|
32
32
|
default=None,
|
|
33
33
|
)
|
|
34
|
-
from_date:
|
|
34
|
+
from_date: str | None = Field(
|
|
35
35
|
description="The start date from which to get the transactions (any format accepted by momentjs).",
|
|
36
36
|
default=None,
|
|
37
37
|
)
|
|
38
|
-
to_date:
|
|
38
|
+
to_date: str | None = Field(
|
|
39
39
|
description="Get the transactions up to this date (any format accepted by momentjs).",
|
|
40
40
|
default=None,
|
|
41
41
|
)
|
|
42
|
-
limit:
|
|
42
|
+
limit: int | None = Field(
|
|
43
43
|
description="The desired page size of the result.",
|
|
44
44
|
default=DEFAULT_LIMIT,
|
|
45
45
|
)
|
|
46
|
-
order:
|
|
46
|
+
order: str | None = Field(
|
|
47
47
|
description="The order of the result, in ascending (ASC) or descending (DESC).",
|
|
48
48
|
default=DEFAULT_ORDER,
|
|
49
49
|
)
|
|
50
|
-
cursor:
|
|
50
|
+
cursor: str | None = Field(
|
|
51
51
|
description="The cursor returned in the previous response (for pagination).",
|
|
52
52
|
default=None,
|
|
53
53
|
)
|
|
@@ -65,22 +65,22 @@ class ERC20Transfers(TokenBaseTool):
|
|
|
65
65
|
"Get ERC20 token transactions for a wallet address, ordered by block number. "
|
|
66
66
|
"Returns transaction details, token information, and wallet interactions."
|
|
67
67
|
)
|
|
68
|
-
args_schema:
|
|
68
|
+
args_schema: type[BaseModel] = ERC20TransfersInput
|
|
69
69
|
|
|
70
70
|
async def _arun(
|
|
71
71
|
self,
|
|
72
72
|
address: str,
|
|
73
73
|
chain: str = DEFAULT_CHAIN,
|
|
74
|
-
contract_addresses:
|
|
75
|
-
from_block:
|
|
76
|
-
to_block:
|
|
77
|
-
from_date:
|
|
78
|
-
to_date:
|
|
79
|
-
limit:
|
|
80
|
-
order:
|
|
81
|
-
cursor:
|
|
74
|
+
contract_addresses: list[str] | None = None,
|
|
75
|
+
from_block: int | None = None,
|
|
76
|
+
to_block: int | None = None,
|
|
77
|
+
from_date: str | None = None,
|
|
78
|
+
to_date: str | None = None,
|
|
79
|
+
limit: int | None = DEFAULT_LIMIT,
|
|
80
|
+
order: str | None = DEFAULT_ORDER,
|
|
81
|
+
cursor: str | None = None,
|
|
82
82
|
**kwargs,
|
|
83
|
-
) ->
|
|
83
|
+
) -> dict[str, Any]:
|
|
84
84
|
"""Fetch ERC20 token transfers for a wallet from Moralis.
|
|
85
85
|
|
|
86
86
|
Args:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
@@ -31,14 +31,14 @@ class TokenAnalytics(TokenBaseTool):
|
|
|
31
31
|
"Get analytics for a token by token address. "
|
|
32
32
|
"Returns trading volumes, number of buyers/sellers, and liquidity information over various time periods."
|
|
33
33
|
)
|
|
34
|
-
args_schema:
|
|
34
|
+
args_schema: type[BaseModel] = TokenAnalyticsInput
|
|
35
35
|
|
|
36
36
|
async def _arun(
|
|
37
37
|
self,
|
|
38
38
|
address: str,
|
|
39
39
|
chain: str = DEFAULT_CHAIN,
|
|
40
40
|
**kwargs,
|
|
41
|
-
) ->
|
|
41
|
+
) -> dict[str, Any]:
|
|
42
42
|
"""Fetch token analytics from Moralis.
|
|
43
43
|
|
|
44
44
|
Args:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
@@ -19,23 +19,23 @@ class TokenPriceInput(BaseModel):
|
|
|
19
19
|
description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
|
|
20
20
|
default=DEFAULT_CHAIN,
|
|
21
21
|
)
|
|
22
|
-
include:
|
|
22
|
+
include: str | None = Field(
|
|
23
23
|
description="If the result should contain the 24hr percent change (use 'percent_change').",
|
|
24
24
|
default=None,
|
|
25
25
|
)
|
|
26
|
-
exchange:
|
|
26
|
+
exchange: str | None = Field(
|
|
27
27
|
description="The factory name or address of the token exchange.",
|
|
28
28
|
default=None,
|
|
29
29
|
)
|
|
30
|
-
to_block:
|
|
30
|
+
to_block: int | None = Field(
|
|
31
31
|
description="The block number from which the token price should be checked.",
|
|
32
32
|
default=None,
|
|
33
33
|
)
|
|
34
|
-
max_token_inactivity:
|
|
34
|
+
max_token_inactivity: int | None = Field(
|
|
35
35
|
description="Exclude tokens inactive for more than the given amount of days.",
|
|
36
36
|
default=None,
|
|
37
37
|
)
|
|
38
|
-
min_pair_side_liquidity_usd:
|
|
38
|
+
min_pair_side_liquidity_usd: int | None = Field(
|
|
39
39
|
description="Exclude tokens with liquidity less than the specified amount in USD.",
|
|
40
40
|
default=None,
|
|
41
41
|
)
|
|
@@ -53,19 +53,19 @@ class TokenPrice(TokenBaseTool):
|
|
|
53
53
|
"Get the token price denominated in the blockchain's native token and USD for a given token contract address. "
|
|
54
54
|
"Returns price, token information and exchange data."
|
|
55
55
|
)
|
|
56
|
-
args_schema:
|
|
56
|
+
args_schema: type[BaseModel] = TokenPriceInput
|
|
57
57
|
|
|
58
58
|
async def _arun(
|
|
59
59
|
self,
|
|
60
60
|
address: str,
|
|
61
61
|
chain: str = DEFAULT_CHAIN,
|
|
62
|
-
include:
|
|
63
|
-
exchange:
|
|
64
|
-
to_block:
|
|
65
|
-
max_token_inactivity:
|
|
66
|
-
min_pair_side_liquidity_usd:
|
|
62
|
+
include: str | None = None,
|
|
63
|
+
exchange: str | None = None,
|
|
64
|
+
to_block: int | None = None,
|
|
65
|
+
max_token_inactivity: int | None = None,
|
|
66
|
+
min_pair_side_liquidity_usd: int | None = None,
|
|
67
67
|
**kwargs,
|
|
68
|
-
) ->
|
|
68
|
+
) -> dict[str, Any]:
|
|
69
69
|
"""Fetch token price from Moralis.
|
|
70
70
|
|
|
71
71
|
Args:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
@@ -14,15 +14,15 @@ class TokenSearchInput(BaseModel):
|
|
|
14
14
|
query: str = Field(
|
|
15
15
|
description="Search query - can be token address, token name or token symbol."
|
|
16
16
|
)
|
|
17
|
-
chains:
|
|
17
|
+
chains: list[str] | None = Field(
|
|
18
18
|
description="The chain(s) to query (e.g., 'eth', 'bsc', 'polygon').",
|
|
19
19
|
default=None,
|
|
20
20
|
)
|
|
21
|
-
limit:
|
|
21
|
+
limit: int | None = Field(
|
|
22
22
|
description="The desired page size of the result.",
|
|
23
23
|
default=None,
|
|
24
24
|
)
|
|
25
|
-
is_verified_contract:
|
|
25
|
+
is_verified_contract: bool | None = Field(
|
|
26
26
|
description="Whether the contract is verified.",
|
|
27
27
|
default=None,
|
|
28
28
|
)
|
|
@@ -44,16 +44,16 @@ class TokenSearch(TokenBaseTool):
|
|
|
44
44
|
"Returns token information including price, market cap, and security information. "
|
|
45
45
|
"NOTE: This is a premium endpoint that requires a Moralis Business plan."
|
|
46
46
|
)
|
|
47
|
-
args_schema:
|
|
47
|
+
args_schema: type[BaseModel] = TokenSearchInput
|
|
48
48
|
|
|
49
49
|
async def _arun(
|
|
50
50
|
self,
|
|
51
51
|
query: str,
|
|
52
|
-
chains:
|
|
53
|
-
limit:
|
|
54
|
-
is_verified_contract:
|
|
52
|
+
chains: list[str] | None = None,
|
|
53
|
+
limit: int | None = None,
|
|
54
|
+
is_verified_contract: bool | None = None,
|
|
55
55
|
**kwargs,
|
|
56
|
-
) ->
|
|
56
|
+
) -> dict[str, Any]:
|
|
57
57
|
"""Search for tokens using Moralis.
|
|
58
58
|
|
|
59
59
|
Args:
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
from typing import TypedDict
|
|
5
5
|
|
|
6
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
7
6
|
from intentkit.clients import TwitterClientConfig
|
|
8
7
|
from intentkit.skills.base import SkillConfig, SkillState
|
|
9
8
|
from intentkit.skills.twitter.base import TwitterBaseTool
|
|
@@ -46,7 +45,6 @@ class Config(SkillConfig, TwitterClientConfig):
|
|
|
46
45
|
async def get_skills(
|
|
47
46
|
config: "Config",
|
|
48
47
|
is_private: bool,
|
|
49
|
-
store: SkillStoreABC,
|
|
50
48
|
**_,
|
|
51
49
|
) -> list[TwitterBaseTool]:
|
|
52
50
|
"""Get all Twitter skills."""
|
|
@@ -62,7 +60,7 @@ async def get_skills(
|
|
|
62
60
|
# Get each skill using the cached getter
|
|
63
61
|
result = []
|
|
64
62
|
for name in available_skills:
|
|
65
|
-
skill = get_twitter_skill(name
|
|
63
|
+
skill = get_twitter_skill(name)
|
|
66
64
|
if skill:
|
|
67
65
|
result.append(skill)
|
|
68
66
|
return result
|
|
@@ -70,76 +68,54 @@ async def get_skills(
|
|
|
70
68
|
|
|
71
69
|
def get_twitter_skill(
|
|
72
70
|
name: str,
|
|
73
|
-
store: SkillStoreABC,
|
|
74
71
|
) -> TwitterBaseTool:
|
|
75
72
|
"""Get a Twitter skill by name.
|
|
76
73
|
|
|
77
74
|
Args:
|
|
78
75
|
name: The name of the skill to get
|
|
79
|
-
store: The skill store for persisting data
|
|
80
76
|
|
|
81
77
|
Returns:
|
|
82
78
|
The requested Twitter skill
|
|
83
79
|
"""
|
|
84
80
|
if name == "get_mentions":
|
|
85
81
|
if name not in _cache:
|
|
86
|
-
_cache[name] = TwitterGetMentions(
|
|
87
|
-
skill_store=store,
|
|
88
|
-
)
|
|
82
|
+
_cache[name] = TwitterGetMentions()
|
|
89
83
|
return _cache[name]
|
|
90
84
|
elif name == "post_tweet":
|
|
91
85
|
if name not in _cache:
|
|
92
|
-
_cache[name] = TwitterPostTweet(
|
|
93
|
-
skill_store=store,
|
|
94
|
-
)
|
|
86
|
+
_cache[name] = TwitterPostTweet()
|
|
95
87
|
return _cache[name]
|
|
96
88
|
elif name == "reply_tweet":
|
|
97
89
|
if name not in _cache:
|
|
98
|
-
_cache[name] = TwitterReplyTweet(
|
|
99
|
-
skill_store=store,
|
|
100
|
-
)
|
|
90
|
+
_cache[name] = TwitterReplyTweet()
|
|
101
91
|
return _cache[name]
|
|
102
92
|
elif name == "get_timeline":
|
|
103
93
|
if name not in _cache:
|
|
104
|
-
_cache[name] = TwitterGetTimeline(
|
|
105
|
-
skill_store=store,
|
|
106
|
-
)
|
|
94
|
+
_cache[name] = TwitterGetTimeline()
|
|
107
95
|
return _cache[name]
|
|
108
96
|
elif name == "follow_user":
|
|
109
97
|
if name not in _cache:
|
|
110
|
-
_cache[name] = TwitterFollowUser(
|
|
111
|
-
skill_store=store,
|
|
112
|
-
)
|
|
98
|
+
_cache[name] = TwitterFollowUser()
|
|
113
99
|
return _cache[name]
|
|
114
100
|
elif name == "like_tweet":
|
|
115
101
|
if name not in _cache:
|
|
116
|
-
_cache[name] = TwitterLikeTweet(
|
|
117
|
-
skill_store=store,
|
|
118
|
-
)
|
|
102
|
+
_cache[name] = TwitterLikeTweet()
|
|
119
103
|
return _cache[name]
|
|
120
104
|
elif name == "retweet":
|
|
121
105
|
if name not in _cache:
|
|
122
|
-
_cache[name] = TwitterRetweet(
|
|
123
|
-
skill_store=store,
|
|
124
|
-
)
|
|
106
|
+
_cache[name] = TwitterRetweet()
|
|
125
107
|
return _cache[name]
|
|
126
108
|
elif name == "search_tweets":
|
|
127
109
|
if name not in _cache:
|
|
128
|
-
_cache[name] = TwitterSearchTweets(
|
|
129
|
-
skill_store=store,
|
|
130
|
-
)
|
|
110
|
+
_cache[name] = TwitterSearchTweets()
|
|
131
111
|
return _cache[name]
|
|
132
112
|
elif name == "get_user_by_username":
|
|
133
113
|
if name not in _cache:
|
|
134
|
-
_cache[name] = TwitterGetUserByUsername(
|
|
135
|
-
skill_store=store,
|
|
136
|
-
)
|
|
114
|
+
_cache[name] = TwitterGetUserByUsername()
|
|
137
115
|
return _cache[name]
|
|
138
116
|
elif name == "get_user_tweets":
|
|
139
117
|
if name not in _cache:
|
|
140
|
-
_cache[name] = TwitterGetUserTweets(
|
|
141
|
-
skill_store=store,
|
|
142
|
-
)
|
|
118
|
+
_cache[name] = TwitterGetUserTweets()
|
|
143
119
|
return _cache[name]
|
|
144
120
|
else:
|
|
145
121
|
logger.warning(f"Unknown Twitter skill: {name}")
|
intentkit/skills/twitter/base.py
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
from datetime import datetime, timedelta
|
|
2
|
-
from typing import Type
|
|
1
|
+
from datetime import UTC, datetime, timedelta
|
|
3
2
|
|
|
4
|
-
from
|
|
3
|
+
from langchain_core.tools.base import ToolException
|
|
5
4
|
from pydantic import BaseModel, Field
|
|
6
5
|
|
|
7
|
-
from intentkit.
|
|
6
|
+
from intentkit.config.config import config
|
|
8
7
|
from intentkit.skills.base import IntentKitSkill
|
|
9
8
|
from intentkit.utils.error import RateLimitExceeded
|
|
10
9
|
|
|
@@ -14,10 +13,7 @@ class TwitterBaseTool(IntentKitSkill):
|
|
|
14
13
|
|
|
15
14
|
name: str = Field(description="The name of the tool")
|
|
16
15
|
description: str = Field(description="A description of what the tool does")
|
|
17
|
-
args_schema:
|
|
18
|
-
skill_store: SkillStoreABC = Field(
|
|
19
|
-
description="The skill store for persisting data"
|
|
20
|
-
)
|
|
16
|
+
args_schema: type[BaseModel]
|
|
21
17
|
|
|
22
18
|
def get_api_key(self) -> dict:
|
|
23
19
|
context = self.get_context()
|
|
@@ -25,20 +21,21 @@ class TwitterBaseTool(IntentKitSkill):
|
|
|
25
21
|
api_key_provider = skill_config.get("api_key_provider")
|
|
26
22
|
if api_key_provider == "platform":
|
|
27
23
|
# Return platform keys (these need to be added to config.py)
|
|
28
|
-
|
|
29
|
-
"consumer_key":
|
|
30
|
-
|
|
31
|
-
),
|
|
32
|
-
"
|
|
33
|
-
"
|
|
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"
|
|
24
|
+
platform_keys = {
|
|
25
|
+
"consumer_key": getattr(config, "twitter_consumer_key", None),
|
|
26
|
+
"consumer_secret": getattr(config, "twitter_consumer_secret", None),
|
|
27
|
+
"access_token": getattr(config, "twitter_access_token", None),
|
|
28
|
+
"access_token_secret": getattr(
|
|
29
|
+
config, "twitter_access_token_secret", None
|
|
40
30
|
),
|
|
41
31
|
}
|
|
32
|
+
missing = [key for key, value in platform_keys.items() if not value]
|
|
33
|
+
if missing:
|
|
34
|
+
raise ToolException(
|
|
35
|
+
"Twitter platform API keys are not configured: "
|
|
36
|
+
+ ", ".join(missing)
|
|
37
|
+
)
|
|
38
|
+
return platform_keys
|
|
42
39
|
# for backward compatibility or agent_owner provider
|
|
43
40
|
elif api_key_provider == "agent_owner":
|
|
44
41
|
required_keys = [
|
|
@@ -63,24 +60,19 @@ class TwitterBaseTool(IntentKitSkill):
|
|
|
63
60
|
def category(self) -> str:
|
|
64
61
|
return "twitter"
|
|
65
62
|
|
|
66
|
-
async def check_rate_limit(
|
|
67
|
-
self, agent_id: str, max_requests: int = 1, interval: int = 15
|
|
68
|
-
) -> None:
|
|
63
|
+
async def check_rate_limit(self, max_requests: int = 1, interval: int = 15) -> None:
|
|
69
64
|
"""Check if the rate limit has been exceeded.
|
|
70
65
|
|
|
71
66
|
Args:
|
|
72
|
-
agent_id: The ID of the agent.
|
|
73
67
|
max_requests: Maximum number of requests allowed within the rate limit window.
|
|
74
68
|
interval: Time interval in minutes for the rate limit window.
|
|
75
69
|
|
|
76
70
|
Raises:
|
|
77
71
|
RateLimitExceeded: If the rate limit has been exceeded.
|
|
78
72
|
"""
|
|
79
|
-
rate_limit = await self.
|
|
80
|
-
agent_id, self.name, "rate_limit"
|
|
81
|
-
)
|
|
73
|
+
rate_limit = await self.get_agent_skill_data("rate_limit")
|
|
82
74
|
|
|
83
|
-
current_time = datetime.now(tz=
|
|
75
|
+
current_time = datetime.now(tz=UTC)
|
|
84
76
|
|
|
85
77
|
if (
|
|
86
78
|
rate_limit
|
|
@@ -92,9 +84,7 @@ class TwitterBaseTool(IntentKitSkill):
|
|
|
92
84
|
raise RateLimitExceeded("Rate limit exceeded")
|
|
93
85
|
|
|
94
86
|
rate_limit["count"] += 1
|
|
95
|
-
await self.
|
|
96
|
-
agent_id, self.name, "rate_limit", rate_limit
|
|
97
|
-
)
|
|
87
|
+
await self.save_agent_skill_data("rate_limit", rate_limit)
|
|
98
88
|
|
|
99
89
|
return
|
|
100
90
|
|
|
@@ -103,7 +93,5 @@ class TwitterBaseTool(IntentKitSkill):
|
|
|
103
93
|
"count": 1,
|
|
104
94
|
"reset_time": (current_time + timedelta(minutes=interval)).isoformat(),
|
|
105
95
|
}
|
|
106
|
-
await self.
|
|
107
|
-
agent_id, self.name, "rate_limit", new_rate_limit
|
|
108
|
-
)
|
|
96
|
+
await self.save_agent_skill_data("rate_limit", new_rate_limit)
|
|
109
97
|
return
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Type
|
|
3
2
|
|
|
4
3
|
from langchain_core.tools import ToolException
|
|
5
4
|
from pydantic import BaseModel, Field
|
|
@@ -34,7 +33,7 @@ class TwitterFollowUser(TwitterBaseTool):
|
|
|
34
33
|
|
|
35
34
|
name: str = NAME
|
|
36
35
|
description: str = PROMPT
|
|
37
|
-
args_schema:
|
|
36
|
+
args_schema: type[BaseModel] = TwitterFollowUserInput
|
|
38
37
|
|
|
39
38
|
async def _arun(self, user_id: str, **kwargs) -> bool:
|
|
40
39
|
context = self.get_context()
|
|
@@ -42,16 +41,13 @@ class TwitterFollowUser(TwitterBaseTool):
|
|
|
42
41
|
skill_config = context.agent.skill_config(self.category)
|
|
43
42
|
twitter = get_twitter_client(
|
|
44
43
|
agent_id=context.agent_id,
|
|
45
|
-
skill_store=self.skill_store,
|
|
46
44
|
config=skill_config,
|
|
47
45
|
)
|
|
48
46
|
client = await twitter.get_client()
|
|
49
47
|
|
|
50
48
|
# Check rate limit only when not using OAuth
|
|
51
49
|
if not twitter.use_key:
|
|
52
|
-
await self.check_rate_limit(
|
|
53
|
-
context.agent_id, max_requests=5, interval=15
|
|
54
|
-
)
|
|
50
|
+
await self.check_rate_limit(max_requests=5, interval=15)
|
|
55
51
|
|
|
56
52
|
# Follow the user using tweepy client
|
|
57
53
|
response = await client.follow_user(
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from datetime import datetime, timedelta
|
|
3
|
-
from typing import Type
|
|
2
|
+
from datetime import UTC, datetime, timedelta
|
|
4
3
|
|
|
5
4
|
from langchain_core.tools import ToolException
|
|
6
5
|
from pydantic import BaseModel
|
|
@@ -38,7 +37,7 @@ class TwitterGetMentions(TwitterBaseTool):
|
|
|
38
37
|
|
|
39
38
|
name: str = NAME
|
|
40
39
|
description: str = PROMPT
|
|
41
|
-
args_schema:
|
|
40
|
+
args_schema: type[BaseModel] = TwitterGetMentionsInput
|
|
42
41
|
|
|
43
42
|
async def _arun(self, **kwargs) -> list[Tweet]:
|
|
44
43
|
context = self.get_context()
|
|
@@ -46,7 +45,6 @@ class TwitterGetMentions(TwitterBaseTool):
|
|
|
46
45
|
skill_config = context.agent.skill_config(self.category)
|
|
47
46
|
twitter = get_twitter_client(
|
|
48
47
|
agent_id=context.agent_id,
|
|
49
|
-
skill_store=self.skill_store,
|
|
50
48
|
config=skill_config,
|
|
51
49
|
)
|
|
52
50
|
client = await twitter.get_client()
|
|
@@ -56,15 +54,12 @@ class TwitterGetMentions(TwitterBaseTool):
|
|
|
56
54
|
# Check rate limit only when not using OAuth
|
|
57
55
|
if not twitter.use_key:
|
|
58
56
|
await self.check_rate_limit(
|
|
59
|
-
context.agent_id,
|
|
60
57
|
max_requests=1,
|
|
61
58
|
interval=15,
|
|
62
59
|
)
|
|
63
60
|
|
|
64
61
|
# get since id from store
|
|
65
|
-
last = await self.
|
|
66
|
-
context.agent_id, self.name, "last"
|
|
67
|
-
)
|
|
62
|
+
last = await self.get_agent_skill_data("last")
|
|
68
63
|
last = last or {}
|
|
69
64
|
max_results = 10
|
|
70
65
|
since_id = last.get("since_id")
|
|
@@ -72,7 +67,7 @@ class TwitterGetMentions(TwitterBaseTool):
|
|
|
72
67
|
max_results = 30
|
|
73
68
|
|
|
74
69
|
# Always get mentions for the last day
|
|
75
|
-
start_time = datetime.now(tz=
|
|
70
|
+
start_time = datetime.now(tz=UTC) - timedelta(days=1)
|
|
76
71
|
|
|
77
72
|
user_id = twitter.self_id
|
|
78
73
|
if not user_id:
|
|
@@ -113,9 +108,7 @@ class TwitterGetMentions(TwitterBaseTool):
|
|
|
113
108
|
# Update since_id in store
|
|
114
109
|
if mentions.get("meta") and mentions["meta"].get("newest_id"):
|
|
115
110
|
last["since_id"] = mentions["meta"].get("newest_id")
|
|
116
|
-
await self.
|
|
117
|
-
context.agent_id, self.name, "last", last
|
|
118
|
-
)
|
|
111
|
+
await self.save_agent_skill_data("last", last)
|
|
119
112
|
|
|
120
113
|
return mentions
|
|
121
114
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Type
|
|
3
2
|
|
|
4
3
|
from pydantic import BaseModel
|
|
5
4
|
|
|
@@ -34,7 +33,7 @@ class TwitterGetTimeline(TwitterBaseTool):
|
|
|
34
33
|
|
|
35
34
|
name: str = NAME
|
|
36
35
|
description: str = PROMPT
|
|
37
|
-
args_schema:
|
|
36
|
+
args_schema: type[BaseModel] = TwitterGetTimelineInput
|
|
38
37
|
|
|
39
38
|
async def _arun(self, **kwargs):
|
|
40
39
|
context = self.get_context()
|
|
@@ -45,21 +44,16 @@ class TwitterGetTimeline(TwitterBaseTool):
|
|
|
45
44
|
skill_config = context.agent.skill_config(self.category)
|
|
46
45
|
twitter = get_twitter_client(
|
|
47
46
|
agent_id=context.agent_id,
|
|
48
|
-
skill_store=self.skill_store,
|
|
49
47
|
config=skill_config,
|
|
50
48
|
)
|
|
51
49
|
client = await twitter.get_client()
|
|
52
50
|
|
|
53
51
|
# Check rate limit only when not using OAuth
|
|
54
52
|
if not twitter.use_key:
|
|
55
|
-
await self.check_rate_limit(
|
|
56
|
-
context.agent_id, max_requests=1, interval=15
|
|
57
|
-
)
|
|
53
|
+
await self.check_rate_limit(max_requests=1, interval=15)
|
|
58
54
|
|
|
59
55
|
# get since id from store
|
|
60
|
-
last = await self.
|
|
61
|
-
context.agent_id, self.name, "last"
|
|
62
|
-
)
|
|
56
|
+
last = await self.get_agent_skill_data("last")
|
|
63
57
|
last = last or {}
|
|
64
58
|
since_id = last.get("since_id")
|
|
65
59
|
|
|
@@ -101,9 +95,7 @@ class TwitterGetTimeline(TwitterBaseTool):
|
|
|
101
95
|
# Update the since_id in store for the next request
|
|
102
96
|
if timeline.get("meta") and timeline["meta"].get("newest_id"):
|
|
103
97
|
last["since_id"] = timeline["meta"]["newest_id"]
|
|
104
|
-
await self.
|
|
105
|
-
context.agent_id, self.name, "last", last
|
|
106
|
-
)
|
|
98
|
+
await self.save_agent_skill_data("last", last)
|
|
107
99
|
|
|
108
100
|
return timeline
|
|
109
101
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Type
|
|
3
2
|
|
|
4
3
|
from pydantic import BaseModel, Field
|
|
5
4
|
|
|
@@ -35,7 +34,7 @@ class TwitterGetUserByUsername(TwitterBaseTool):
|
|
|
35
34
|
|
|
36
35
|
name: str = NAME
|
|
37
36
|
description: str = PROMPT
|
|
38
|
-
args_schema:
|
|
37
|
+
args_schema: type[BaseModel] = TwitterGetUserByUsernameInput
|
|
39
38
|
|
|
40
39
|
async def _arun(self, username: str, **kwargs):
|
|
41
40
|
context = self.get_context()
|
|
@@ -43,16 +42,13 @@ class TwitterGetUserByUsername(TwitterBaseTool):
|
|
|
43
42
|
skill_config = context.agent.skill_config(self.category)
|
|
44
43
|
twitter = get_twitter_client(
|
|
45
44
|
agent_id=context.agent_id,
|
|
46
|
-
skill_store=self.skill_store,
|
|
47
45
|
config=skill_config,
|
|
48
46
|
)
|
|
49
47
|
client = await twitter.get_client()
|
|
50
48
|
|
|
51
49
|
# Check rate limit only when not using OAuth
|
|
52
50
|
if not twitter.use_key:
|
|
53
|
-
await self.check_rate_limit(
|
|
54
|
-
context.agent_id, max_requests=5, interval=60 * 24
|
|
55
|
-
)
|
|
51
|
+
await self.check_rate_limit(max_requests=5, interval=60 * 24)
|
|
56
52
|
|
|
57
53
|
user_data = await client.get_user(
|
|
58
54
|
username=username,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import List, Optional, Type
|
|
3
2
|
|
|
4
3
|
from pydantic import BaseModel, Field
|
|
5
4
|
|
|
@@ -21,7 +20,7 @@ class TwitterGetUserTweetsInput(BaseModel):
|
|
|
21
20
|
"""Input for TwitterGetUserTweets tool."""
|
|
22
21
|
|
|
23
22
|
user_id: str = Field(description="The Twitter user ID to fetch tweets from")
|
|
24
|
-
exclude:
|
|
23
|
+
exclude: list[str] | None = Field(
|
|
25
24
|
default=["replies", "retweets"],
|
|
26
25
|
description="Types of tweets to exclude (e.g., 'replies', 'retweets')",
|
|
27
26
|
)
|
|
@@ -41,7 +40,7 @@ class TwitterGetUserTweets(TwitterBaseTool):
|
|
|
41
40
|
|
|
42
41
|
name: str = NAME
|
|
43
42
|
description: str = PROMPT
|
|
44
|
-
args_schema:
|
|
43
|
+
args_schema: type[BaseModel] = TwitterGetUserTweetsInput
|
|
45
44
|
|
|
46
45
|
async def _arun(self, **kwargs):
|
|
47
46
|
context = self.get_context()
|
|
@@ -59,21 +58,16 @@ class TwitterGetUserTweets(TwitterBaseTool):
|
|
|
59
58
|
skill_config = context.agent.skill_config(self.category)
|
|
60
59
|
twitter = get_twitter_client(
|
|
61
60
|
agent_id=context.agent_id,
|
|
62
|
-
skill_store=self.skill_store,
|
|
63
61
|
config=skill_config,
|
|
64
62
|
)
|
|
65
63
|
client = await twitter.get_client()
|
|
66
64
|
|
|
67
65
|
# Check rate limit only when not using OAuth
|
|
68
66
|
if not twitter.use_key:
|
|
69
|
-
await self.check_rate_limit(
|
|
70
|
-
context.agent_id, max_requests=1, interval=15
|
|
71
|
-
)
|
|
67
|
+
await self.check_rate_limit(max_requests=1, interval=15)
|
|
72
68
|
|
|
73
69
|
# get since id from store
|
|
74
|
-
last = await self.
|
|
75
|
-
context.agent_id, self.name, user_id
|
|
76
|
-
)
|
|
70
|
+
last = await self.get_agent_skill_data(user_id)
|
|
77
71
|
last = last or {}
|
|
78
72
|
since_id = last.get("since_id")
|
|
79
73
|
|
|
@@ -112,9 +106,7 @@ class TwitterGetUserTweets(TwitterBaseTool):
|
|
|
112
106
|
# Update the since_id in store for the next request
|
|
113
107
|
if tweets.get("meta") and tweets["meta"].get("newest_id"):
|
|
114
108
|
last["since_id"] = tweets["meta"]["newest_id"]
|
|
115
|
-
await self.
|
|
116
|
-
context.agent_id, self.name, user_id, last
|
|
117
|
-
)
|
|
109
|
+
await self.save_agent_skill_data(user_id, last)
|
|
118
110
|
|
|
119
111
|
return tweets
|
|
120
112
|
|