intentkit 0.7.5.dev3__py3-none-any.whl → 0.8.34.dev7__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.
- intentkit/MANIFEST.in +14 -0
- intentkit/README.md +88 -0
- intentkit/__init__.py +6 -4
- intentkit/abstracts/agent.py +4 -5
- intentkit/abstracts/engine.py +5 -5
- intentkit/abstracts/graph.py +15 -8
- intentkit/abstracts/skill.py +6 -144
- intentkit/abstracts/twitter.py +4 -5
- intentkit/clients/__init__.py +9 -2
- intentkit/clients/cdp.py +129 -153
- intentkit/{utils → clients}/s3.py +109 -34
- intentkit/clients/twitter.py +83 -62
- intentkit/clients/web3.py +4 -7
- intentkit/config/config.py +123 -90
- intentkit/core/account_checking.py +802 -0
- intentkit/core/agent.py +313 -498
- intentkit/core/asset.py +267 -0
- intentkit/core/chat.py +5 -3
- intentkit/core/client.py +1 -1
- intentkit/core/credit.py +49 -41
- intentkit/core/draft.py +201 -0
- intentkit/core/draft_chat.py +118 -0
- intentkit/core/engine.py +378 -287
- intentkit/core/manager/__init__.py +25 -0
- intentkit/core/manager/engine.py +220 -0
- intentkit/core/manager/service.py +172 -0
- intentkit/core/manager/skills.py +178 -0
- intentkit/core/middleware.py +231 -0
- intentkit/core/prompt.py +74 -114
- intentkit/core/scheduler.py +143 -0
- intentkit/core/statistics.py +168 -0
- intentkit/models/agent.py +931 -518
- intentkit/models/agent_data.py +165 -106
- intentkit/models/agent_schema.json +38 -251
- intentkit/models/app_setting.py +15 -13
- intentkit/models/chat.py +86 -140
- intentkit/models/credit.py +182 -162
- intentkit/models/db.py +42 -23
- intentkit/models/db_mig.py +120 -3
- intentkit/models/draft.py +222 -0
- intentkit/models/llm.csv +31 -0
- intentkit/models/llm.py +262 -370
- intentkit/models/redis.py +6 -4
- intentkit/models/skill.py +222 -101
- intentkit/models/skills.csv +173 -0
- intentkit/models/team.py +189 -0
- intentkit/models/user.py +103 -31
- 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 +241 -41
- 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 +6 -6
- 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/casino/schema.json +0 -1
- 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 +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/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 +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/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/__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/schema.json +91 -93
- 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/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 +54 -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/__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/schema.json +2 -6
- 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/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 +13 -15
- intentkit/skills/heurist/image_generation_arthemy_comics.py +13 -15
- intentkit/skills/heurist/image_generation_arthemy_real.py +13 -15
- intentkit/skills/heurist/image_generation_braindance.py +13 -15
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +13 -15
- intentkit/skills/heurist/image_generation_flux_1_dev.py +13 -15
- intentkit/skills/heurist/image_generation_sdxl.py +13 -15
- 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 +3 -9
- intentkit/skills/lifi/schema.json +17 -8
- intentkit/skills/lifi/token_execute.py +150 -60
- 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 +30 -0
- intentkit/skills/openai/__init__.py +17 -18
- intentkit/skills/openai/base.py +10 -14
- intentkit/skills/openai/dalle_image_generation.py +4 -9
- intentkit/skills/openai/gpt_avatar_generator.py +102 -0
- intentkit/skills/openai/gpt_image_generation.py +5 -9
- intentkit/skills/openai/gpt_image_mini_generator.py +92 -0
- intentkit/skills/openai/gpt_image_to_image.py +5 -9
- 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 +36 -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 +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/schema.json +2 -3
- intentkit/skills/supabase/update_data.py +6 -6
- intentkit/skills/supabase/upsert_data.py +4 -4
- 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 +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/schema.json +1 -0
- 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/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 +11 -10
- 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 +58 -0
- intentkit/skills/x402/base.py +99 -0
- intentkit/skills/x402/http_request.py +117 -0
- intentkit/skills/x402/schema.json +40 -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 +7 -6
- intentkit/skills/xmtp/schema.json +69 -71
- intentkit/skills/xmtp/swap.py +6 -8
- intentkit/skills/xmtp/transfer.py +4 -6
- intentkit/utils/__init__.py +4 -0
- intentkit/utils/chain.py +198 -96
- intentkit/utils/ens.py +135 -0
- intentkit/utils/error.py +5 -2
- intentkit/utils/logging.py +9 -11
- intentkit/utils/schema.py +100 -0
- intentkit/utils/slack_alert.py +8 -8
- intentkit/utils/tx.py +16 -8
- intentkit/uv.lock +3377 -0
- {intentkit-0.7.5.dev3.dist-info → intentkit-0.8.34.dev7.dist-info}/METADATA +13 -15
- intentkit-0.8.34.dev7.dist-info/RECORD +478 -0
- intentkit-0.8.34.dev7.dist-info/licenses/LICENSE +21 -0
- intentkit/core/node.py +0 -215
- intentkit/models/conversation.py +0 -286
- 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.7.5.dev3.dist-info/RECORD +0 -424
- {intentkit-0.7.5.dev3.dist-info/licenses → intentkit}/LICENSE +0 -0
- {intentkit-0.7.5.dev3.dist-info → intentkit-0.8.34.dev7.dist-info}/WHEEL +0 -0
|
@@ -1,121 +1,115 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from typing import
|
|
3
|
-
|
|
4
|
-
from intentkit.
|
|
5
|
-
from intentkit.skills.base import
|
|
6
|
-
from intentkit.skills.carv.
|
|
7
|
-
from intentkit.skills.carv.
|
|
8
|
-
from intentkit.skills.carv.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
state
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
117
|
-
return None # Failed to instantiate
|
|
118
|
-
else:
|
|
119
|
-
# This handles cases where a name might be in config but not in our map
|
|
120
|
-
logger.warning(f"Attempted to get unknown Carv skill: {name}")
|
|
121
|
-
return None
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Literal, TypedDict
|
|
3
|
+
|
|
4
|
+
from intentkit.skills.base import SkillConfig, SkillState
|
|
5
|
+
from intentkit.skills.carv.base import CarvBaseTool
|
|
6
|
+
from intentkit.skills.carv.fetch_news import FetchNewsTool
|
|
7
|
+
from intentkit.skills.carv.onchain_query import OnchainQueryTool
|
|
8
|
+
from intentkit.skills.carv.token_info_and_price import TokenInfoAndPriceTool
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
_cache: dict[str, CarvBaseTool] = {}
|
|
13
|
+
|
|
14
|
+
_SKILL_NAME_TO_CLASS_MAP: dict[str, type[CarvBaseTool]] = {
|
|
15
|
+
"onchain_query": OnchainQueryTool,
|
|
16
|
+
"token_info_and_price": TokenInfoAndPriceTool,
|
|
17
|
+
"fetch_news": FetchNewsTool,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SkillStates(TypedDict):
|
|
22
|
+
onchain_query: SkillState
|
|
23
|
+
token_info_and_price: SkillState
|
|
24
|
+
fetch_news: SkillState
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Config(SkillConfig):
|
|
28
|
+
enabled: bool
|
|
29
|
+
states: SkillStates # type: ignore
|
|
30
|
+
api_key_provider: Literal["agent_owner", "platform"] | None
|
|
31
|
+
|
|
32
|
+
# conditionally required
|
|
33
|
+
api_key: str | None
|
|
34
|
+
|
|
35
|
+
# optional
|
|
36
|
+
rate_limit_number: int | None
|
|
37
|
+
rate_limit_minutes: int | None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
async def get_skills(
|
|
41
|
+
config: "Config",
|
|
42
|
+
is_private: bool,
|
|
43
|
+
**_,
|
|
44
|
+
) -> list[CarvBaseTool]:
|
|
45
|
+
"""
|
|
46
|
+
Factory function to create and return CARV skill tools based on the provided configuration.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
config: The configuration object for the CARV skill.
|
|
50
|
+
is_private: A boolean indicating whether the request is from a private context.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
A list of `CarvBaseTool` instances.
|
|
54
|
+
"""
|
|
55
|
+
# Check if the entire category is disabled first
|
|
56
|
+
if not config.get("enabled", False):
|
|
57
|
+
return []
|
|
58
|
+
|
|
59
|
+
available_skills: list[CarvBaseTool] = []
|
|
60
|
+
skill_states = config.get("states", {})
|
|
61
|
+
|
|
62
|
+
# Iterate through all known skills defined in the map
|
|
63
|
+
for skill_name in _SKILL_NAME_TO_CLASS_MAP:
|
|
64
|
+
state = skill_states.get(
|
|
65
|
+
skill_name, "disabled"
|
|
66
|
+
) # Default to disabled if not in config
|
|
67
|
+
|
|
68
|
+
if state == "disabled":
|
|
69
|
+
continue
|
|
70
|
+
elif state == "public" or (state == "private" and is_private):
|
|
71
|
+
# If enabled, get the skill instance using the factory function
|
|
72
|
+
skill_instance = get_carv_skill(skill_name)
|
|
73
|
+
if skill_instance:
|
|
74
|
+
available_skills.append(skill_instance)
|
|
75
|
+
else:
|
|
76
|
+
logger.warning(f"Could not instantiate known skill: {skill_name}")
|
|
77
|
+
|
|
78
|
+
return available_skills
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def get_carv_skill(
|
|
82
|
+
name: str,
|
|
83
|
+
) -> CarvBaseTool | None:
|
|
84
|
+
"""
|
|
85
|
+
Factory function to retrieve a cached CARV skill instance by name.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
name: The name of the CARV skill to retrieve.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
The requested `CarvBaseTool` instance if found and enabled, otherwise None.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
# Return from cache immediately if already exists
|
|
95
|
+
if name in _cache:
|
|
96
|
+
return _cache[name]
|
|
97
|
+
|
|
98
|
+
# Get the class from the map
|
|
99
|
+
skill_class = _SKILL_NAME_TO_CLASS_MAP.get(name)
|
|
100
|
+
|
|
101
|
+
if skill_class:
|
|
102
|
+
try:
|
|
103
|
+
# Instantiate the skill and add to cache
|
|
104
|
+
instance = skill_class() # type: ignore
|
|
105
|
+
_cache[name] = instance
|
|
106
|
+
return instance
|
|
107
|
+
except Exception as e:
|
|
108
|
+
logger.error(
|
|
109
|
+
f"Failed to instantiate Carv skill '{name}': {e}", exc_info=True
|
|
110
|
+
)
|
|
111
|
+
return None # Failed to instantiate
|
|
112
|
+
else:
|
|
113
|
+
# This handles cases where a name might be in config but not in our map
|
|
114
|
+
logger.warning(f"Attempted to get unknown Carv skill: {name}")
|
|
115
|
+
return None
|
intentkit/skills/carv/base.py
CHANGED
|
@@ -1,185 +1,184 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from typing import Any
|
|
3
|
-
|
|
4
|
-
import httpx # Ensure httpx is installed: pip install httpx
|
|
5
|
-
from
|
|
6
|
-
from pydantic import BaseModel, Field
|
|
7
|
-
|
|
8
|
-
from intentkit.
|
|
9
|
-
from intentkit.skills.base import IntentKitSkill
|
|
10
|
-
|
|
11
|
-
logger = logging.getLogger(__name__)
|
|
12
|
-
|
|
13
|
-
CARV_API_BASE_URL = "https://interface.carv.io"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class CarvBaseTool(IntentKitSkill):
|
|
17
|
-
"""Base class for CARV API tools."""
|
|
18
|
-
|
|
19
|
-
name: str = Field(description="Tool name") # type: ignore
|
|
20
|
-
description: str = Field(description="Tool description")
|
|
21
|
-
args_schema:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
api_key_provider
|
|
42
|
-
|
|
43
|
-
agent_api_key:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
system_api_key
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
"
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
err_msg
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
"
|
|
165
|
-
"
|
|
166
|
-
"
|
|
167
|
-
"
|
|
168
|
-
"
|
|
169
|
-
"
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
"
|
|
182
|
-
"
|
|
183
|
-
"
|
|
184
|
-
|
|
185
|
-
}
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import httpx # Ensure httpx is installed: pip install httpx
|
|
5
|
+
from langchain_core.tools.base import ToolException
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from intentkit.config.config import config
|
|
9
|
+
from intentkit.skills.base import IntentKitSkill
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
CARV_API_BASE_URL = "https://interface.carv.io"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CarvBaseTool(IntentKitSkill):
|
|
17
|
+
"""Base class for CARV API tools."""
|
|
18
|
+
|
|
19
|
+
name: str = Field(description="Tool name") # type: ignore
|
|
20
|
+
description: str = Field(description="Tool description")
|
|
21
|
+
args_schema: type[BaseModel] # type: ignore
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def category(self) -> str:
|
|
25
|
+
return "carv"
|
|
26
|
+
|
|
27
|
+
def get_api_key(self) -> str:
|
|
28
|
+
"""
|
|
29
|
+
Retrieves the CARV API key based on the api_key_provider setting.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
The API key if found.
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
ToolException: If the API key is not found or provider is invalid.
|
|
36
|
+
"""
|
|
37
|
+
try:
|
|
38
|
+
context = self.get_context()
|
|
39
|
+
skill_config = context.agent.skill_config(self.category)
|
|
40
|
+
api_key_provider = skill_config.get("api_key_provider")
|
|
41
|
+
if api_key_provider == "agent_owner":
|
|
42
|
+
agent_api_key: str | None = skill_config.get("api_key")
|
|
43
|
+
if agent_api_key:
|
|
44
|
+
logger.debug(
|
|
45
|
+
f"Using agent-specific CARV API key for skill {self.name} in category {self.category}"
|
|
46
|
+
)
|
|
47
|
+
return agent_api_key
|
|
48
|
+
raise ToolException(
|
|
49
|
+
f"No agent-owned CARV API key found for skill '{self.name}' in category '{self.category}'."
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
elif api_key_provider == "platform":
|
|
53
|
+
system_api_key = config.carv_api_key
|
|
54
|
+
if system_api_key:
|
|
55
|
+
logger.debug(
|
|
56
|
+
f"Using system CARV API key for skill {self.name} in category {self.category}"
|
|
57
|
+
)
|
|
58
|
+
return system_api_key
|
|
59
|
+
raise ToolException(
|
|
60
|
+
f"No platform-hosted CARV API key found for skill '{self.name}' in category '{self.category}'."
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
else:
|
|
64
|
+
raise ToolException(
|
|
65
|
+
f"Invalid API key provider '{api_key_provider}' for skill '{self.name}'"
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
except Exception as e:
|
|
69
|
+
# Re-raise ToolException if it's already one, otherwise wrap
|
|
70
|
+
if isinstance(e, ToolException):
|
|
71
|
+
raise
|
|
72
|
+
raise ToolException(f"Failed to retrieve CARV API key: {str(e)}") from e
|
|
73
|
+
|
|
74
|
+
async def apply_rate_limit(self, context) -> None:
|
|
75
|
+
"""
|
|
76
|
+
Applies rate limiting ONLY if specified in the agent's config ('skill_config').
|
|
77
|
+
Checks for 'rate_limit_number' and 'rate_limit_minutes'.
|
|
78
|
+
If not configured, NO rate limiting is applied.
|
|
79
|
+
Raises ConnectionAbortedError if the configured limit is exceeded.
|
|
80
|
+
"""
|
|
81
|
+
skill_config = context.agent.skill_config(self.category)
|
|
82
|
+
user_id = context.agent.id
|
|
83
|
+
|
|
84
|
+
limit_num = skill_config.get("rate_limit_number")
|
|
85
|
+
limit_min = skill_config.get("rate_limit_minutes")
|
|
86
|
+
|
|
87
|
+
# Apply limit ONLY if both values are present and valid (truthy check handles None and 0)
|
|
88
|
+
if limit_num and limit_min:
|
|
89
|
+
logger.debug(
|
|
90
|
+
f"Applying rate limit ({limit_num}/{limit_min} min) for user {user_id} on {self.name}"
|
|
91
|
+
)
|
|
92
|
+
if user_id:
|
|
93
|
+
await self.user_rate_limit_by_category(limit_num, limit_min * 60)
|
|
94
|
+
else:
|
|
95
|
+
# No valid agent configuration found, so do nothing.
|
|
96
|
+
logger.debug(
|
|
97
|
+
f"No agent rate limits configured for category '{self.category}'. Skipping rate limit for user {user_id}."
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
async def _call_carv_api(
|
|
101
|
+
self,
|
|
102
|
+
context,
|
|
103
|
+
endpoint: str,
|
|
104
|
+
method: str = "GET",
|
|
105
|
+
params: dict[str, Any] | None = None,
|
|
106
|
+
payload: dict[str, Any] | None = None,
|
|
107
|
+
) -> tuple[dict[str, Any] | None, dict[str, Any] | None]:
|
|
108
|
+
"""
|
|
109
|
+
Makes a call to the CARV API and returns a tuple of (success, error).
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
context: The skill context.
|
|
113
|
+
endpoint: The API endpoint path (e.g., "/ai-agent-backend/token_info").
|
|
114
|
+
method: HTTP method ("GET", "POST", etc.).
|
|
115
|
+
params: Query parameters for the request.
|
|
116
|
+
payload: JSON payload for POST/PUT requests.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
Tuple where the first element is the response data if successful,
|
|
120
|
+
and the second element is an error dict if an error occurred.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
url = f"{CARV_API_BASE_URL}{endpoint}"
|
|
124
|
+
|
|
125
|
+
try:
|
|
126
|
+
api_key = self.get_api_key()
|
|
127
|
+
|
|
128
|
+
headers = {
|
|
129
|
+
"Authorization": api_key,
|
|
130
|
+
"Content-Type": "application/json",
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
logger.debug(
|
|
134
|
+
f"Calling CARV API: {method} {url} with params {params}, payload {payload}"
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
async with httpx.AsyncClient(timeout=30.0) as client:
|
|
138
|
+
if method == "GET":
|
|
139
|
+
response = await client.get(url, headers=headers, params=params)
|
|
140
|
+
elif method == "POST":
|
|
141
|
+
response = await client.post(
|
|
142
|
+
url, headers=headers, json=payload, params=params
|
|
143
|
+
)
|
|
144
|
+
else:
|
|
145
|
+
return None, {"error": f"Unsupported HTTP method: {method}"}
|
|
146
|
+
|
|
147
|
+
# Do NOT raise for status here; always parse JSON
|
|
148
|
+
try:
|
|
149
|
+
response_json: dict[str, Any] = response.json()
|
|
150
|
+
except Exception as json_err:
|
|
151
|
+
err_msg = f"Failed to parse JSON response: {json_err}"
|
|
152
|
+
logger.error(err_msg)
|
|
153
|
+
return None, {"error": err_msg}
|
|
154
|
+
|
|
155
|
+
logger.debug(
|
|
156
|
+
f"CARV API Response (status {response.status_code}): {response_json}"
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# Check if response_json signals an error explicitly (custom API error)
|
|
160
|
+
if response.status_code >= 400 or "error" in response_json:
|
|
161
|
+
# Return full error info (including status code, body, etc.)
|
|
162
|
+
return None, {
|
|
163
|
+
"error": response_json.get("error", "Unknown API error"),
|
|
164
|
+
"status_code": response.status_code,
|
|
165
|
+
"response": response_json,
|
|
166
|
+
"url": url,
|
|
167
|
+
"method": method,
|
|
168
|
+
"params": params,
|
|
169
|
+
"payload": payload,
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
# Otherwise return the 'data' field if present, else full response
|
|
173
|
+
return response_json.get("data", response_json), None
|
|
174
|
+
|
|
175
|
+
except Exception as e:
|
|
176
|
+
logger.error(
|
|
177
|
+
f"Error calling CARV API to {method} > {url}: {e}", exc_info=True
|
|
178
|
+
)
|
|
179
|
+
return None, {
|
|
180
|
+
"error": str(e),
|
|
181
|
+
"url": url,
|
|
182
|
+
"method": method,
|
|
183
|
+
"params": params,
|
|
184
|
+
}
|
|
@@ -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
|
|
5
5
|
|
|
@@ -29,12 +29,12 @@ class FetchNewsTool(CarvBaseTool):
|
|
|
29
29
|
"Fetches the latest news articles from the CARV API. "
|
|
30
30
|
"Returns a list of news items, each with a title, URL, and a short summary (card_text)."
|
|
31
31
|
)
|
|
32
|
-
args_schema:
|
|
32
|
+
args_schema: type[BaseModel] = CarvNewsInput
|
|
33
33
|
|
|
34
34
|
async def _arun(
|
|
35
35
|
self, # type: ignore
|
|
36
36
|
**kwargs: Any,
|
|
37
|
-
) ->
|
|
37
|
+
) -> dict[str, Any]:
|
|
38
38
|
"""
|
|
39
39
|
Fetches news from the CARV API and returns the response.
|
|
40
40
|
The expected successful response structure is a dictionary containing an "infos" key,
|