intentkit 0.6.13.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 +14 -7
- intentkit/abstracts/skill.py +6 -144
- intentkit/abstracts/twitter.py +4 -5
- intentkit/clients/__init__.py +5 -2
- intentkit/clients/cdp.py +101 -141
- intentkit/clients/twitter.py +83 -62
- intentkit/clients/web3.py +29 -0
- intentkit/config/config.py +8 -5
- intentkit/core/agent.py +472 -195
- intentkit/core/asset.py +253 -0
- intentkit/core/chat.py +51 -0
- intentkit/core/client.py +1 -1
- intentkit/core/credit.py +460 -130
- intentkit/core/engine.py +262 -233
- intentkit/core/node.py +15 -16
- intentkit/core/prompt.py +62 -28
- intentkit/core/scheduler.py +92 -0
- intentkit/core/statistics.py +168 -0
- intentkit/models/agent.py +1096 -949
- intentkit/models/agent_data.py +68 -38
- intentkit/models/agent_public.json +98 -0
- intentkit/models/agent_schema.json +54 -439
- intentkit/models/app_setting.py +96 -33
- intentkit/models/chat.py +74 -27
- intentkit/models/conversation.py +8 -8
- intentkit/models/credit.py +362 -74
- intentkit/models/db.py +26 -8
- intentkit/models/db_mig.py +2 -2
- intentkit/models/llm.csv +28 -0
- intentkit/models/llm.py +185 -350
- intentkit/models/redis.py +6 -4
- intentkit/models/skill.py +186 -72
- intentkit/models/skills.csv +174 -0
- intentkit/models/user.py +82 -24
- intentkit/skills/acolyt/__init__.py +2 -9
- intentkit/skills/acolyt/ask.py +3 -4
- intentkit/skills/acolyt/base.py +4 -9
- intentkit/skills/acolyt/schema.json +4 -3
- intentkit/skills/aixbt/__init__.py +2 -13
- intentkit/skills/aixbt/base.py +1 -7
- intentkit/skills/aixbt/projects.py +14 -15
- intentkit/skills/aixbt/schema.json +4 -4
- intentkit/skills/allora/__init__.py +2 -9
- intentkit/skills/allora/base.py +4 -9
- intentkit/skills/allora/price.py +3 -4
- intentkit/skills/allora/schema.json +3 -2
- intentkit/skills/base.py +248 -85
- intentkit/skills/basename/__init__.py +51 -0
- intentkit/skills/basename/base.py +11 -0
- intentkit/skills/basename/basename.svg +11 -0
- intentkit/skills/basename/schema.json +58 -0
- 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/schema.json +134 -137
- intentkit/skills/carv/token_info_and_price.py +5 -5
- intentkit/skills/casino/README.md +254 -0
- intentkit/skills/casino/__init__.py +86 -0
- intentkit/skills/casino/base.py +17 -0
- intentkit/skills/casino/casino.png +0 -0
- intentkit/skills/casino/deck_draw.py +127 -0
- intentkit/skills/casino/deck_shuffle.py +118 -0
- intentkit/skills/casino/dice_roll.py +100 -0
- intentkit/skills/casino/schema.json +77 -0
- intentkit/skills/casino/utils.py +107 -0
- intentkit/skills/cdp/__init__.py +22 -84
- intentkit/skills/cdp/base.py +1 -7
- intentkit/skills/cdp/schema.json +11 -314
- intentkit/skills/chainlist/__init__.py +2 -7
- intentkit/skills/chainlist/base.py +1 -7
- intentkit/skills/chainlist/chain_lookup.py +18 -18
- intentkit/skills/chainlist/schema.json +3 -5
- intentkit/skills/common/__init__.py +2 -9
- intentkit/skills/common/base.py +1 -7
- intentkit/skills/common/current_time.py +1 -2
- intentkit/skills/common/schema.json +2 -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/schema.json +1 -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 +11 -25
- 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/cryptocompare/schema.json +3 -3
- 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/cryptopanic/schema.json +105 -103
- 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/dapplooker/schema.json +3 -5
- intentkit/skills/defillama/__init__.py +24 -74
- intentkit/skills/defillama/api.py +6 -9
- intentkit/skills/defillama/base.py +11 -21
- 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/schema.json +5 -1
- 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/README.md +154 -0
- intentkit/skills/dexscreener/__init__.py +97 -93
- intentkit/skills/dexscreener/base.py +125 -133
- intentkit/skills/dexscreener/get_pair_info.py +158 -0
- intentkit/skills/dexscreener/get_token_pairs.py +165 -0
- intentkit/skills/dexscreener/get_tokens_info.py +212 -0
- intentkit/skills/dexscreener/model/search_token_response.py +80 -82
- intentkit/skills/dexscreener/schema.json +91 -48
- intentkit/skills/dexscreener/search_token.py +182 -321
- intentkit/skills/dexscreener/utils.py +420 -0
- 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/dune_analytics/schema.json +104 -99
- intentkit/skills/elfa/__init__.py +5 -18
- intentkit/skills/elfa/base.py +10 -14
- intentkit/skills/elfa/mention.py +19 -21
- intentkit/skills/elfa/schema.json +3 -2
- 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 +50 -35
- intentkit/skills/enso/best_yield.py +16 -24
- intentkit/skills/enso/networks.py +6 -11
- intentkit/skills/enso/prices.py +11 -13
- intentkit/skills/enso/route.py +34 -38
- intentkit/skills/enso/schema.json +3 -2
- intentkit/skills/enso/tokens.py +29 -38
- intentkit/skills/enso/wallet.py +76 -191
- intentkit/skills/erc20/__init__.py +50 -0
- intentkit/skills/erc20/base.py +11 -0
- intentkit/skills/erc20/erc20.svg +5 -0
- intentkit/skills/erc20/schema.json +74 -0
- intentkit/skills/erc721/__init__.py +53 -0
- intentkit/skills/erc721/base.py +11 -0
- intentkit/skills/erc721/erc721.svg +5 -0
- intentkit/skills/erc721/schema.json +90 -0
- intentkit/skills/firecrawl/README.md +11 -5
- intentkit/skills/firecrawl/__init__.py +5 -18
- intentkit/skills/firecrawl/base.py +4 -11
- intentkit/skills/firecrawl/clear.py +4 -8
- intentkit/skills/firecrawl/crawl.py +19 -19
- intentkit/skills/firecrawl/query.py +4 -3
- intentkit/skills/firecrawl/schema.json +6 -8
- intentkit/skills/firecrawl/scrape.py +150 -40
- 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/github/schema.json +3 -4
- 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/heurist/schema.json +2 -2
- 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/http/schema.json +4 -5
- intentkit/skills/lifi/__init__.py +8 -13
- intentkit/skills/lifi/base.py +1 -7
- intentkit/skills/lifi/schema.json +17 -8
- intentkit/skills/lifi/token_execute.py +36 -30
- intentkit/skills/lifi/token_quote.py +8 -10
- intentkit/skills/lifi/utils.py +104 -51
- 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/moralis/schema.json +7 -2
- intentkit/skills/morpho/__init__.py +52 -0
- intentkit/skills/morpho/base.py +11 -0
- intentkit/skills/morpho/morpho.svg +12 -0
- intentkit/skills/morpho/schema.json +73 -0
- intentkit/skills/nation/__init__.py +4 -9
- intentkit/skills/nation/base.py +5 -10
- intentkit/skills/nation/nft_check.py +3 -4
- intentkit/skills/nation/schema.json +4 -3
- 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 +34 -3
- intentkit/skills/portfolio/__init__.py +11 -35
- intentkit/skills/portfolio/base.py +33 -19
- intentkit/skills/portfolio/schema.json +3 -5
- 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 +50 -0
- intentkit/skills/pyth/base.py +11 -0
- intentkit/skills/pyth/pyth.svg +6 -0
- intentkit/skills/pyth/schema.json +75 -0
- intentkit/skills/skills.toml +40 -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/schema.json +2 -2
- intentkit/skills/slack/send_message.py +3 -5
- intentkit/skills/supabase/__init__.py +7 -23
- intentkit/skills/supabase/base.py +9 -13
- intentkit/skills/supabase/delete_data.py +5 -6
- intentkit/skills/supabase/fetch_data.py +13 -14
- intentkit/skills/supabase/insert_data.py +5 -6
- intentkit/skills/supabase/invoke_function.py +7 -8
- intentkit/skills/supabase/schema.json +2 -3
- intentkit/skills/supabase/update_data.py +7 -8
- intentkit/skills/supabase/upsert_data.py +5 -6
- intentkit/skills/superfluid/__init__.py +53 -0
- intentkit/skills/superfluid/base.py +11 -0
- intentkit/skills/superfluid/schema.json +89 -0
- intentkit/skills/superfluid/superfluid.svg +6 -0
- 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/system/schema.json +6 -8
- intentkit/skills/tavily/__init__.py +3 -12
- intentkit/skills/tavily/base.py +4 -9
- intentkit/skills/tavily/schema.json +3 -5
- 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/schema.json +3 -6
- 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 +23 -35
- intentkit/skills/twitter/follow_user.py +3 -7
- intentkit/skills/twitter/get_mentions.py +6 -13
- intentkit/skills/twitter/get_timeline.py +5 -13
- intentkit/skills/twitter/get_user_by_username.py +3 -7
- intentkit/skills/twitter/get_user_tweets.py +6 -14
- intentkit/skills/twitter/like_tweet.py +3 -7
- intentkit/skills/twitter/post_tweet.py +23 -12
- intentkit/skills/twitter/reply_tweet.py +21 -12
- intentkit/skills/twitter/retweet.py +3 -7
- intentkit/skills/twitter/schema.json +1 -0
- intentkit/skills/twitter/search_tweets.py +5 -13
- intentkit/skills/unrealspeech/__init__.py +2 -7
- intentkit/skills/unrealspeech/base.py +2 -8
- intentkit/skills/unrealspeech/schema.json +2 -5
- 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/schema.json +151 -152
- intentkit/skills/venice_audio/venice_audio.py +38 -21
- 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/schema.json +267 -267
- 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/schema.json +2 -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 +49 -0
- intentkit/skills/weth/base.py +11 -0
- intentkit/skills/weth/schema.json +58 -0
- intentkit/skills/weth/weth.svg +6 -0
- intentkit/skills/wow/__init__.py +51 -0
- intentkit/skills/wow/base.py +11 -0
- intentkit/skills/wow/schema.json +89 -0
- intentkit/skills/wow/wow.svg +7 -0
- 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 +61 -2
- intentkit/skills/xmtp/price.py +18 -13
- intentkit/skills/xmtp/schema.json +69 -71
- intentkit/skills/xmtp/swap.py +22 -25
- intentkit/skills/xmtp/transfer.py +71 -32
- intentkit/utils/chain.py +3 -3
- intentkit/utils/error.py +14 -1
- intentkit/utils/logging.py +2 -4
- intentkit/utils/s3.py +59 -7
- intentkit/utils/schema.py +100 -0
- intentkit/utils/slack_alert.py +7 -8
- {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +14 -16
- intentkit-0.8.17.dist-info/RECORD +466 -0
- intentkit/abstracts/exception.py +0 -9
- intentkit/core/skill.py +0 -200
- intentkit/models/generator.py +0 -347
- intentkit/skills/cdp/get_balance.py +0 -110
- intentkit/skills/cdp/swap.py +0 -121
- intentkit/skills/moralis/tests/__init__.py +0 -0
- intentkit/skills/moralis/tests/test_wallet.py +0 -511
- intentkit-0.6.13.dev2.dist-info/RECORD +0 -409
- {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
- {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
intentkit/clients/twitter.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
3
|
import tempfile
|
|
4
|
-
from datetime import datetime, timedelta
|
|
5
|
-
from typing import Any,
|
|
4
|
+
from datetime import UTC, datetime, timedelta
|
|
5
|
+
from typing import Any, NotRequired, TypedDict
|
|
6
6
|
from urllib.parse import urlencode
|
|
7
7
|
|
|
8
8
|
import httpx
|
|
@@ -11,14 +11,17 @@ from requests.auth import HTTPBasicAuth
|
|
|
11
11
|
from requests_oauthlib import OAuth2Session
|
|
12
12
|
from tweepy.asynchronous import AsyncClient
|
|
13
13
|
|
|
14
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
15
14
|
from intentkit.abstracts.twitter import TwitterABC
|
|
16
15
|
from intentkit.models.agent_data import AgentData
|
|
16
|
+
from intentkit.models.redis import get_redis
|
|
17
17
|
|
|
18
18
|
logger = logging.getLogger(__name__)
|
|
19
19
|
|
|
20
|
-
_clients_linked:
|
|
21
|
-
_clients_self_key:
|
|
20
|
+
_clients_linked: dict[str, "TwitterClient"] = {}
|
|
21
|
+
_clients_self_key: dict[str, "TwitterClient"] = {}
|
|
22
|
+
|
|
23
|
+
_VERIFIER_KEY = "intentkit:twitter:code_verifier"
|
|
24
|
+
_CHALLENGE_KEY = "intentkit:twitter:code_challenge"
|
|
22
25
|
|
|
23
26
|
|
|
24
27
|
class TwitterMedia(BaseModel):
|
|
@@ -26,7 +29,7 @@ class TwitterMedia(BaseModel):
|
|
|
26
29
|
|
|
27
30
|
media_key: str
|
|
28
31
|
type: str
|
|
29
|
-
url:
|
|
32
|
+
url: str | None = None
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
class TwitterUser(BaseModel):
|
|
@@ -55,10 +58,10 @@ class Tweet(BaseModel):
|
|
|
55
58
|
id: str
|
|
56
59
|
text: str
|
|
57
60
|
author_id: str
|
|
58
|
-
author:
|
|
61
|
+
author: TwitterUser | None = None
|
|
59
62
|
created_at: datetime
|
|
60
|
-
referenced_tweets:
|
|
61
|
-
attachments:
|
|
63
|
+
referenced_tweets: list["Tweet"] | None = None
|
|
64
|
+
attachments: list[TwitterMedia] | None = None
|
|
62
65
|
|
|
63
66
|
|
|
64
67
|
class TwitterClientConfig(TypedDict):
|
|
@@ -76,33 +79,44 @@ class TwitterClient(TwitterABC):
|
|
|
76
79
|
|
|
77
80
|
Args:
|
|
78
81
|
agent_id: The ID of the agent
|
|
79
|
-
skill_store: The skill store for retrieving data
|
|
80
82
|
config: Configuration dictionary that may contain API keys
|
|
81
83
|
"""
|
|
82
84
|
|
|
83
|
-
def __init__(self, agent_id: str,
|
|
85
|
+
def __init__(self, agent_id: str, config: dict) -> None:
|
|
84
86
|
"""Initialize the Twitter client.
|
|
85
87
|
|
|
86
88
|
Args:
|
|
87
89
|
agent_id: The ID of the agent
|
|
88
|
-
skill_store: The skill store for retrieving data
|
|
89
90
|
config: Configuration dictionary that may contain API keys
|
|
90
91
|
"""
|
|
91
92
|
self.agent_id = agent_id
|
|
92
|
-
self._client:
|
|
93
|
-
self.
|
|
94
|
-
self._agent_data: Optional[AgentData] = None
|
|
93
|
+
self._client: AsyncClient | None = None
|
|
94
|
+
self._agent_data: AgentData | None = None
|
|
95
95
|
self.use_key = _is_self_key(config)
|
|
96
96
|
self._config = config
|
|
97
97
|
|
|
98
|
+
async def _get_agent_data(self) -> AgentData:
|
|
99
|
+
"""Retrieve cached agent data, loading from the database if needed."""
|
|
100
|
+
|
|
101
|
+
if not self._agent_data:
|
|
102
|
+
self._agent_data = await AgentData.get(self.agent_id)
|
|
103
|
+
return self._agent_data
|
|
104
|
+
|
|
105
|
+
async def _refresh_agent_data(self) -> AgentData:
|
|
106
|
+
"""Reload agent data from the database."""
|
|
107
|
+
|
|
108
|
+
self._agent_data = await AgentData.get(self.agent_id)
|
|
109
|
+
return self._agent_data
|
|
110
|
+
|
|
98
111
|
async def get_client(self) -> AsyncClient:
|
|
99
112
|
"""Get the initialized Twitter client.
|
|
100
113
|
|
|
101
114
|
Returns:
|
|
102
115
|
AsyncClient: The Twitter client if initialized
|
|
103
116
|
"""
|
|
104
|
-
|
|
105
|
-
|
|
117
|
+
|
|
118
|
+
agent_data = await self._get_agent_data()
|
|
119
|
+
|
|
106
120
|
if not self._client:
|
|
107
121
|
# Check if we have API keys in config
|
|
108
122
|
if self.use_key:
|
|
@@ -114,30 +128,26 @@ class TwitterClient(TwitterABC):
|
|
|
114
128
|
return_type=dict,
|
|
115
129
|
)
|
|
116
130
|
# refresh userinfo if needed
|
|
117
|
-
if not
|
|
118
|
-
|
|
119
|
-
< datetime.now(tz=
|
|
131
|
+
if not agent_data.twitter_self_key_refreshed_at or (
|
|
132
|
+
agent_data.twitter_self_key_refreshed_at
|
|
133
|
+
< datetime.now(tz=UTC) - timedelta(days=1)
|
|
120
134
|
):
|
|
121
135
|
me = await self._client.get_me(
|
|
122
136
|
user_auth=self.use_key,
|
|
123
137
|
user_fields="id,username,name,verified",
|
|
124
138
|
)
|
|
125
139
|
if me and "data" in me and "id" in me["data"]:
|
|
126
|
-
await
|
|
140
|
+
await AgentData.patch(
|
|
127
141
|
self.agent_id,
|
|
128
142
|
{
|
|
129
143
|
"twitter_id": me["data"]["id"],
|
|
130
144
|
"twitter_username": me["data"]["username"],
|
|
131
145
|
"twitter_name": me["data"]["name"],
|
|
132
146
|
"twitter_is_verified": me["data"]["verified"],
|
|
133
|
-
"twitter_self_key_refreshed_at": datetime.now(
|
|
134
|
-
tz=timezone.utc
|
|
135
|
-
),
|
|
147
|
+
"twitter_self_key_refreshed_at": datetime.now(tz=UTC),
|
|
136
148
|
},
|
|
137
149
|
)
|
|
138
|
-
|
|
139
|
-
self.agent_id
|
|
140
|
-
)
|
|
150
|
+
agent_data = await self._refresh_agent_data()
|
|
141
151
|
logger.info(
|
|
142
152
|
f"Twitter self key client initialized. "
|
|
143
153
|
f"Use API key: {self.use_key}, "
|
|
@@ -148,43 +158,38 @@ class TwitterClient(TwitterABC):
|
|
|
148
158
|
)
|
|
149
159
|
return self._client
|
|
150
160
|
# Otherwise try to get OAuth2 tokens from agent data
|
|
151
|
-
if not
|
|
161
|
+
if not agent_data.twitter_access_token:
|
|
152
162
|
raise Exception(f"[{self.agent_id}] Twitter access token not found")
|
|
153
|
-
if not
|
|
163
|
+
if not agent_data.twitter_access_token_expires_at:
|
|
154
164
|
raise Exception(
|
|
155
165
|
f"[{self.agent_id}] Twitter access token expiration not found"
|
|
156
166
|
)
|
|
157
|
-
if
|
|
158
|
-
tz=timezone.utc
|
|
159
|
-
):
|
|
167
|
+
if agent_data.twitter_access_token_expires_at <= datetime.now(tz=UTC):
|
|
160
168
|
raise Exception(f"[{self.agent_id}] Twitter access token has expired")
|
|
161
169
|
self._client = AsyncClient(
|
|
162
|
-
bearer_token=
|
|
170
|
+
bearer_token=agent_data.twitter_access_token,
|
|
163
171
|
return_type=dict,
|
|
164
172
|
)
|
|
165
173
|
return self._client
|
|
174
|
+
|
|
166
175
|
if not self.use_key:
|
|
167
176
|
# check if access token has expired
|
|
168
|
-
if
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
self._agent_data = await self._skill_store.get_agent_data(self.agent_id)
|
|
172
|
-
# check again
|
|
173
|
-
if self._agent_data.twitter_access_token_expires_at <= datetime.now(
|
|
174
|
-
tz=timezone.utc
|
|
175
|
-
):
|
|
177
|
+
if agent_data.twitter_access_token_expires_at <= datetime.now(tz=UTC):
|
|
178
|
+
agent_data = await self._refresh_agent_data()
|
|
179
|
+
if agent_data.twitter_access_token_expires_at <= datetime.now(tz=UTC):
|
|
176
180
|
raise Exception(
|
|
177
181
|
f"[{self.agent_id}] Twitter access token has expired"
|
|
178
182
|
)
|
|
179
183
|
self._client = AsyncClient(
|
|
180
|
-
bearer_token=
|
|
184
|
+
bearer_token=agent_data.twitter_access_token,
|
|
181
185
|
return_type=dict,
|
|
182
186
|
)
|
|
183
187
|
return self._client
|
|
188
|
+
|
|
184
189
|
return self._client
|
|
185
190
|
|
|
186
191
|
@property
|
|
187
|
-
def self_id(self) ->
|
|
192
|
+
def self_id(self) -> str | None:
|
|
188
193
|
"""Get the Twitter user ID.
|
|
189
194
|
|
|
190
195
|
Returns:
|
|
@@ -197,7 +202,7 @@ class TwitterClient(TwitterABC):
|
|
|
197
202
|
return self._agent_data.twitter_id
|
|
198
203
|
|
|
199
204
|
@property
|
|
200
|
-
def self_username(self) ->
|
|
205
|
+
def self_username(self) -> str | None:
|
|
201
206
|
"""Get the Twitter username.
|
|
202
207
|
|
|
203
208
|
Returns:
|
|
@@ -210,7 +215,7 @@ class TwitterClient(TwitterABC):
|
|
|
210
215
|
return self._agent_data.twitter_username
|
|
211
216
|
|
|
212
217
|
@property
|
|
213
|
-
def self_name(self) ->
|
|
218
|
+
def self_name(self) -> str | None:
|
|
214
219
|
"""Get the Twitter display name.
|
|
215
220
|
|
|
216
221
|
Returns:
|
|
@@ -223,7 +228,7 @@ class TwitterClient(TwitterABC):
|
|
|
223
228
|
return self._agent_data.twitter_name
|
|
224
229
|
|
|
225
230
|
@property
|
|
226
|
-
def self_is_verified(self) ->
|
|
231
|
+
def self_is_verified(self) -> bool | None:
|
|
227
232
|
"""Get the Twitter account verification status.
|
|
228
233
|
|
|
229
234
|
Returns:
|
|
@@ -235,14 +240,14 @@ class TwitterClient(TwitterABC):
|
|
|
235
240
|
return None
|
|
236
241
|
return self._agent_data.twitter_is_verified
|
|
237
242
|
|
|
238
|
-
def process_tweets_response(self, response:
|
|
243
|
+
def process_tweets_response(self, response: dict[str, Any]) -> list[Tweet]:
|
|
239
244
|
"""Process Twitter API response and convert it to a list of Tweet objects.
|
|
240
245
|
|
|
241
246
|
Args:
|
|
242
247
|
response: Raw Twitter API response containing tweets data and includes.
|
|
243
248
|
|
|
244
249
|
Returns:
|
|
245
|
-
|
|
250
|
+
list[Tweet]: List of processed Tweet objects.
|
|
246
251
|
"""
|
|
247
252
|
result = []
|
|
248
253
|
if not response.get("data"):
|
|
@@ -334,7 +339,7 @@ class TwitterClient(TwitterABC):
|
|
|
334
339
|
|
|
335
340
|
return result
|
|
336
341
|
|
|
337
|
-
async def upload_media(self, agent_id: str, image_url: str) ->
|
|
342
|
+
async def upload_media(self, agent_id: str, image_url: str) -> list[str]:
|
|
338
343
|
"""Upload media to Twitter and return the media IDs.
|
|
339
344
|
|
|
340
345
|
Args:
|
|
@@ -342,13 +347,13 @@ class TwitterClient(TwitterABC):
|
|
|
342
347
|
image_url: The URL of the image to upload.
|
|
343
348
|
|
|
344
349
|
Returns:
|
|
345
|
-
|
|
350
|
+
list[str]: A list of media IDs for the uploaded media.
|
|
346
351
|
|
|
347
352
|
Raises:
|
|
348
353
|
ValueError: If there's an error uploading the media.
|
|
349
354
|
"""
|
|
350
355
|
# Get agent data to access the token
|
|
351
|
-
agent_data = await
|
|
356
|
+
agent_data = await AgentData.get(agent_id)
|
|
352
357
|
if not agent_data.twitter_access_token:
|
|
353
358
|
raise ValueError("Only linked X account can post media")
|
|
354
359
|
|
|
@@ -415,19 +420,17 @@ class TwitterClient(TwitterABC):
|
|
|
415
420
|
return media_ids
|
|
416
421
|
|
|
417
422
|
|
|
418
|
-
def _is_self_key(config:
|
|
423
|
+
def _is_self_key(config: dict) -> bool:
|
|
419
424
|
return config.get("api_key_provider") == "agent_owner"
|
|
420
425
|
|
|
421
426
|
|
|
422
|
-
def get_twitter_client(
|
|
423
|
-
agent_id: str, skill_store: SkillStoreABC, config: Dict
|
|
424
|
-
) -> "TwitterClient":
|
|
427
|
+
def get_twitter_client(agent_id: str, config: dict) -> "TwitterClient":
|
|
425
428
|
if _is_self_key(config):
|
|
426
429
|
if agent_id not in _clients_self_key:
|
|
427
|
-
_clients_self_key[agent_id] = TwitterClient(agent_id,
|
|
430
|
+
_clients_self_key[agent_id] = TwitterClient(agent_id, config)
|
|
428
431
|
return _clients_self_key[agent_id]
|
|
429
432
|
if agent_id not in _clients_linked:
|
|
430
|
-
_clients_linked[agent_id] = TwitterClient(agent_id,
|
|
433
|
+
_clients_linked[agent_id] = TwitterClient(agent_id, config)
|
|
431
434
|
return _clients_linked[agent_id]
|
|
432
435
|
|
|
433
436
|
|
|
@@ -460,17 +463,33 @@ class OAuth2UserHandler(OAuth2Session):
|
|
|
460
463
|
self.auth = HTTPBasicAuth(client_id, client_secret)
|
|
461
464
|
else:
|
|
462
465
|
self.auth = None
|
|
463
|
-
self.
|
|
464
|
-
|
|
465
|
-
)
|
|
466
|
+
self.code_verifier = None
|
|
467
|
+
self.code_challenge = None
|
|
466
468
|
|
|
467
|
-
def get_authorization_url(self, agent_id: str, redirect_uri: str):
|
|
469
|
+
async def get_authorization_url(self, agent_id: str, redirect_uri: str):
|
|
468
470
|
"""Get the authorization URL to redirect the user to
|
|
469
471
|
|
|
470
472
|
Args:
|
|
471
473
|
agent_id: ID of the agent to authenticate
|
|
472
474
|
redirect_uri: URI to redirect to after authorization
|
|
473
475
|
"""
|
|
476
|
+
if not self.code_challenge:
|
|
477
|
+
try:
|
|
478
|
+
kv = await get_redis()
|
|
479
|
+
self.code_verifier = await kv.get(_VERIFIER_KEY)
|
|
480
|
+
self.code_challenge = await kv.get(_CHALLENGE_KEY)
|
|
481
|
+
if not self.code_verifier or not self.code_challenge:
|
|
482
|
+
self.code_verifier = self._client.create_code_verifier(128)
|
|
483
|
+
self.code_challenge = self._client.create_code_challenge(
|
|
484
|
+
self.code_verifier, "S256"
|
|
485
|
+
)
|
|
486
|
+
await kv.set(_VERIFIER_KEY, self.code_verifier)
|
|
487
|
+
await kv.set(_CHALLENGE_KEY, self.code_challenge)
|
|
488
|
+
except Exception:
|
|
489
|
+
self.code_verifier = self._client.create_code_verifier(128)
|
|
490
|
+
self.code_challenge = self._client.create_code_challenge(
|
|
491
|
+
self.code_verifier, "S256"
|
|
492
|
+
)
|
|
474
493
|
state_params = {"agent_id": agent_id, "redirect_uri": redirect_uri}
|
|
475
494
|
authorization_url, _ = self.authorization_url(
|
|
476
495
|
"https://x.com/i/oauth2/authorize",
|
|
@@ -484,12 +503,14 @@ class OAuth2UserHandler(OAuth2Session):
|
|
|
484
503
|
"""After user has authorized the app, fetch access token with
|
|
485
504
|
authorization response URL
|
|
486
505
|
"""
|
|
506
|
+
if not self.code_verifier or not self.code_challenge:
|
|
507
|
+
raise ValueError("Code verifier or challenge not init")
|
|
487
508
|
return super().fetch_token(
|
|
488
509
|
"https://api.x.com/2/oauth2/token",
|
|
489
510
|
authorization_response=authorization_response,
|
|
490
511
|
auth=self.auth,
|
|
491
512
|
include_client_id=True,
|
|
492
|
-
code_verifier=self.
|
|
513
|
+
code_verifier=self.code_verifier,
|
|
493
514
|
)
|
|
494
515
|
|
|
495
516
|
def refresh(self, refresh_token: str):
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from web3 import Web3
|
|
2
|
+
|
|
3
|
+
from intentkit.config.config import config
|
|
4
|
+
from intentkit.utils.chain import ChainProvider
|
|
5
|
+
|
|
6
|
+
# Global cache for Web3 clients by network_id
|
|
7
|
+
_web3_client_cache: dict[str, Web3] = {}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_web3_client(network_id: str) -> Web3:
|
|
11
|
+
"""Get a Web3 client for the specified network.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
network_id: The network ID to get the Web3 client for
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
Web3: A Web3 client instance for the specified network
|
|
18
|
+
"""
|
|
19
|
+
# Check global cache first
|
|
20
|
+
if network_id in _web3_client_cache:
|
|
21
|
+
return _web3_client_cache[network_id]
|
|
22
|
+
|
|
23
|
+
# Create new Web3 client and cache it
|
|
24
|
+
chain_provider: ChainProvider = config.chain_provider
|
|
25
|
+
chain = chain_provider.get_chain_config(network_id)
|
|
26
|
+
web3_client = Web3(Web3.HTTPProvider(chain.rpc_url))
|
|
27
|
+
_web3_client_cache[network_id] = web3_client
|
|
28
|
+
|
|
29
|
+
return web3_client
|
intentkit/config/config.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# app/config.py
|
|
2
1
|
import json
|
|
3
2
|
import logging
|
|
4
3
|
import os
|
|
@@ -78,14 +77,12 @@ class Config:
|
|
|
78
77
|
self.debug_auth_enabled = self.load("DEBUG_AUTH_ENABLED", "false") == "true"
|
|
79
78
|
self.debug_username = self.load("DEBUG_USERNAME")
|
|
80
79
|
self.debug_password = self.load("DEBUG_PASSWORD")
|
|
81
|
-
self.admin_llm_skill_control = (
|
|
82
|
-
self.load("ADMIN_LLM_SKILL_CONTROL", "false") == "true"
|
|
83
|
-
)
|
|
84
80
|
# Payment
|
|
85
81
|
self.payment_enabled = self.load("PAYMENT_ENABLED", "false") == "true"
|
|
82
|
+
self.x402_fee_address = self.load("X402_FEE_ADDRESS")
|
|
86
83
|
# Open API for agent
|
|
87
84
|
self.open_api_base_url = self.load("OPEN_API_BASE_URL", "http://localhost:8000")
|
|
88
|
-
# CDP - AgentKit 0.
|
|
85
|
+
# CDP - AgentKit 0.7.x Configuration
|
|
89
86
|
self.cdp_api_key_id = self.load("CDP_API_KEY_ID")
|
|
90
87
|
self.cdp_api_key_secret = self.load("CDP_API_KEY_SECRET")
|
|
91
88
|
self.cdp_wallet_secret = self.load("CDP_WALLET_SECRET")
|
|
@@ -96,8 +93,10 @@ class Config:
|
|
|
96
93
|
self.eternal_api_key = self.load("ETERNAL_API_KEY")
|
|
97
94
|
self.reigent_api_key = self.load("REIGENT_API_KEY")
|
|
98
95
|
self.venice_api_key = self.load("VENICE_API_KEY")
|
|
96
|
+
self.gatewayz_api_key = self.load("GATEWAYZ_API_KEY")
|
|
99
97
|
# LLM Config
|
|
100
98
|
self.system_prompt = self.load("SYSTEM_PROMPT")
|
|
99
|
+
self.intentkit_prompt = self.load("INTENTKIT_PROMPT")
|
|
101
100
|
self.input_token_limit = self.load_int("INPUT_TOKEN_LIMIT", 60000)
|
|
102
101
|
# XMTP
|
|
103
102
|
self.xmtp_system_prompt = self.load(
|
|
@@ -110,6 +109,10 @@ class Config:
|
|
|
110
109
|
self.tg_server_host = self.load("TG_SERVER_HOST", "127.0.0.1")
|
|
111
110
|
self.tg_server_port = self.load("TG_SERVER_PORT", "8081")
|
|
112
111
|
self.tg_new_agent_poll_interval = self.load("TG_NEW_AGENT_POLL_INTERVAL", "60")
|
|
112
|
+
# Discord server settings
|
|
113
|
+
self.discord_new_agent_poll_interval = self.load(
|
|
114
|
+
"DISCORD_NEW_AGENT_POLL_INTERVAL", "30"
|
|
115
|
+
)
|
|
113
116
|
# Twitter
|
|
114
117
|
self.twitter_oauth2_client_id = self.load("TWITTER_OAUTH2_CLIENT_ID")
|
|
115
118
|
self.twitter_oauth2_client_secret = self.load("TWITTER_OAUTH2_CLIENT_SECRET")
|