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
|
@@ -1,78 +1,77 @@
|
|
|
1
|
-
import base64
|
|
2
|
-
import io
|
|
3
|
-
import logging
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
from
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
response
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
msg
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
msg =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
msg
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
msg
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
msg =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return base64.b64encode(image_bytes).decode("utf-8")
|
|
1
|
+
import base64
|
|
2
|
+
import io
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
import filetype
|
|
6
|
+
import httpx
|
|
7
|
+
from PIL import Image
|
|
8
|
+
from pydantic import HttpUrl
|
|
9
|
+
|
|
10
|
+
from intentkit.skills.base import ToolException
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
async def fetch_image_as_bytes(image_url: HttpUrl) -> bytes:
|
|
16
|
+
"""Fetches image bytes from a given URL. Converts unsupported formats to PNG using Pillow.
|
|
17
|
+
|
|
18
|
+
Raises:
|
|
19
|
+
ToolException: If fetching or converting the image fails.
|
|
20
|
+
"""
|
|
21
|
+
try:
|
|
22
|
+
async with httpx.AsyncClient(timeout=90) as client:
|
|
23
|
+
response = await client.get(str(image_url), follow_redirects=True)
|
|
24
|
+
response.raise_for_status()
|
|
25
|
+
|
|
26
|
+
original_bytes = response.content
|
|
27
|
+
|
|
28
|
+
# Guess file type from content
|
|
29
|
+
kind = filetype.guess(original_bytes)
|
|
30
|
+
detected_ext = kind.extension if kind else None
|
|
31
|
+
detected_mime = kind.mime if kind else "unknown"
|
|
32
|
+
|
|
33
|
+
if not detected_ext or not detected_mime.startswith("image/"):
|
|
34
|
+
msg = f"URL {image_url} did not return a recognizable image format. Detected: {detected_mime}"
|
|
35
|
+
logger.error(msg)
|
|
36
|
+
raise ToolException(msg)
|
|
37
|
+
|
|
38
|
+
if detected_ext in ("jpg", "jpeg", "png"):
|
|
39
|
+
return original_bytes
|
|
40
|
+
|
|
41
|
+
# Convert unsupported image to PNG
|
|
42
|
+
try:
|
|
43
|
+
img = Image.open(io.BytesIO(original_bytes)).convert("RGBA")
|
|
44
|
+
with io.BytesIO() as output:
|
|
45
|
+
img.save(output, format="PNG")
|
|
46
|
+
logger.info(
|
|
47
|
+
f"Converted unsupported image type '{detected_ext}' to PNG."
|
|
48
|
+
)
|
|
49
|
+
return output.getvalue()
|
|
50
|
+
except Exception as e:
|
|
51
|
+
msg = f"Failed to convert image ({detected_ext}) to PNG: {e}"
|
|
52
|
+
logger.error(msg, exc_info=True)
|
|
53
|
+
raise ToolException(msg) from e
|
|
54
|
+
|
|
55
|
+
except httpx.HTTPStatusError as e:
|
|
56
|
+
msg = f"HTTP error fetching image {image_url}: Status {e.response.status_code}"
|
|
57
|
+
logger.error(msg)
|
|
58
|
+
raise ToolException(msg) from e
|
|
59
|
+
except httpx.RequestError as e:
|
|
60
|
+
msg = f"Network error fetching image {image_url}: {e}"
|
|
61
|
+
logger.error(msg)
|
|
62
|
+
raise ToolException(msg) from e
|
|
63
|
+
except Exception as e:
|
|
64
|
+
msg = f"Unexpected error fetching image {image_url}: {e}"
|
|
65
|
+
logger.error(msg, exc_info=True)
|
|
66
|
+
raise ToolException(msg) from e
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
async def fetch_image_as_base64(image_url: HttpUrl) -> str | None:
|
|
70
|
+
"""Fetches an image from the URL and returns the image as a Base64-encoded string."""
|
|
71
|
+
image_bytes = await fetch_image_as_bytes(image_url)
|
|
72
|
+
|
|
73
|
+
if image_bytes is None:
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
# Convert image bytes to a Base64-encoded string
|
|
77
|
+
return base64.b64encode(image_bytes).decode("utf-8")
|
|
@@ -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.skills.base import SkillConfig, SkillOwnerState, SkillState
|
|
8
7
|
from intentkit.skills.web_scraper.base import WebScraperBaseTool
|
|
9
8
|
from intentkit.skills.web_scraper.document_indexer import DocumentIndexer
|
|
@@ -35,7 +34,6 @@ class Config(SkillConfig):
|
|
|
35
34
|
async def get_skills(
|
|
36
35
|
config: "Config",
|
|
37
36
|
is_private: bool,
|
|
38
|
-
store: SkillStoreABC,
|
|
39
37
|
**_,
|
|
40
38
|
) -> list[WebScraperBaseTool]:
|
|
41
39
|
"""Get all web scraper skills.
|
|
@@ -43,7 +41,6 @@ async def get_skills(
|
|
|
43
41
|
Args:
|
|
44
42
|
config: The configuration for web scraper skills.
|
|
45
43
|
is_private: Whether to include private skills.
|
|
46
|
-
store: The skill store for persisting data.
|
|
47
44
|
|
|
48
45
|
Returns:
|
|
49
46
|
A list of web scraper skills.
|
|
@@ -60,7 +57,7 @@ async def get_skills(
|
|
|
60
57
|
# Get each skill using the cached getter
|
|
61
58
|
result = []
|
|
62
59
|
for name in available_skills:
|
|
63
|
-
skill = get_web_scraper_skill(name
|
|
60
|
+
skill = get_web_scraper_skill(name)
|
|
64
61
|
if skill:
|
|
65
62
|
result.append(skill)
|
|
66
63
|
return result
|
|
@@ -68,40 +65,30 @@ async def get_skills(
|
|
|
68
65
|
|
|
69
66
|
def get_web_scraper_skill(
|
|
70
67
|
name: str,
|
|
71
|
-
store: SkillStoreABC,
|
|
72
68
|
) -> WebScraperBaseTool:
|
|
73
69
|
"""Get a web scraper skill by name.
|
|
74
70
|
|
|
75
71
|
Args:
|
|
76
72
|
name: The name of the skill to get
|
|
77
|
-
store: The skill store for persisting data
|
|
78
73
|
|
|
79
74
|
Returns:
|
|
80
75
|
The requested web scraper skill
|
|
81
76
|
"""
|
|
82
77
|
if name == "scrape_and_index":
|
|
83
78
|
if name not in _cache:
|
|
84
|
-
_cache[name] = ScrapeAndIndex(
|
|
85
|
-
skill_store=store,
|
|
86
|
-
)
|
|
79
|
+
_cache[name] = ScrapeAndIndex()
|
|
87
80
|
return _cache[name]
|
|
88
81
|
elif name == "query_indexed_content":
|
|
89
82
|
if name not in _cache:
|
|
90
|
-
_cache[name] = QueryIndexedContent(
|
|
91
|
-
skill_store=store,
|
|
92
|
-
)
|
|
83
|
+
_cache[name] = QueryIndexedContent()
|
|
93
84
|
return _cache[name]
|
|
94
85
|
elif name == "website_indexer":
|
|
95
86
|
if name not in _cache:
|
|
96
|
-
_cache[name] = WebsiteIndexer(
|
|
97
|
-
skill_store=store,
|
|
98
|
-
)
|
|
87
|
+
_cache[name] = WebsiteIndexer()
|
|
99
88
|
return _cache[name]
|
|
100
89
|
elif name == "document_indexer":
|
|
101
90
|
if name not in _cache:
|
|
102
|
-
_cache[name] = DocumentIndexer(
|
|
103
|
-
skill_store=store,
|
|
104
|
-
)
|
|
91
|
+
_cache[name] = DocumentIndexer()
|
|
105
92
|
return _cache[name]
|
|
106
93
|
else:
|
|
107
94
|
logger.warning(f"Unknown web scraper skill: {name}")
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
1
|
+
from langchain_core.tools.base import ToolException
|
|
3
2
|
from pydantic import BaseModel, Field
|
|
4
3
|
|
|
5
|
-
from intentkit.
|
|
4
|
+
from intentkit.config.config import config
|
|
6
5
|
from intentkit.skills.base import IntentKitSkill
|
|
7
6
|
|
|
8
7
|
|
|
@@ -11,11 +10,26 @@ class WebScraperBaseTool(IntentKitSkill):
|
|
|
11
10
|
|
|
12
11
|
name: str = Field(description="The name of the tool")
|
|
13
12
|
description: str = Field(description="A description of what the tool does")
|
|
14
|
-
args_schema:
|
|
15
|
-
skill_store: SkillStoreABC = Field(
|
|
16
|
-
description="The skill store for persisting data"
|
|
17
|
-
)
|
|
13
|
+
args_schema: type[BaseModel]
|
|
18
14
|
|
|
19
15
|
@property
|
|
20
16
|
def category(self) -> str:
|
|
21
17
|
return "web_scraper"
|
|
18
|
+
|
|
19
|
+
def get_openai_api_key(self) -> str:
|
|
20
|
+
"""Retrieve the OpenAI API key for embedding operations."""
|
|
21
|
+
context = self.get_context()
|
|
22
|
+
skill_config = context.agent.skill_config(self.category)
|
|
23
|
+
api_key_provider = skill_config.get("api_key_provider")
|
|
24
|
+
|
|
25
|
+
if api_key_provider == "platform":
|
|
26
|
+
if not config.openai_api_key:
|
|
27
|
+
raise ToolException("OpenAI API key is not configured")
|
|
28
|
+
return config.openai_api_key
|
|
29
|
+
|
|
30
|
+
if skill_config.get("api_key"):
|
|
31
|
+
return skill_config["api_key"]
|
|
32
|
+
|
|
33
|
+
raise ToolException(
|
|
34
|
+
f"Invalid API key provider: {api_key_provider}, or no api_key in config"
|
|
35
|
+
)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Type
|
|
3
2
|
|
|
4
3
|
from pydantic import BaseModel, Field
|
|
5
4
|
|
|
@@ -65,7 +64,7 @@ class DocumentIndexer(WebScraperBaseTool):
|
|
|
65
64
|
"Perfect for adding content from Google Docs, Notion pages, PDFs, or any other document sources. "
|
|
66
65
|
"The indexed content can then be queried using the query_indexed_content tool."
|
|
67
66
|
)
|
|
68
|
-
args_schema:
|
|
67
|
+
args_schema: type[BaseModel] = DocumentIndexerInput
|
|
69
68
|
|
|
70
69
|
async def _arun(
|
|
71
70
|
self,
|
|
@@ -108,17 +107,19 @@ class DocumentIndexer(WebScraperBaseTool):
|
|
|
108
107
|
f"[{agent_id}] Document created, length: {len(document.page_content)} chars"
|
|
109
108
|
)
|
|
110
109
|
|
|
110
|
+
embedding_api_key = self.get_openai_api_key()
|
|
111
|
+
vector_manager = VectorStoreManager(embedding_api_key)
|
|
112
|
+
|
|
111
113
|
# Index the document
|
|
112
114
|
total_chunks, was_merged = await index_documents(
|
|
113
|
-
[document], agent_id,
|
|
115
|
+
[document], agent_id, vector_manager, chunk_size, chunk_overlap
|
|
114
116
|
)
|
|
115
117
|
|
|
116
118
|
# Get current storage size for response
|
|
117
|
-
|
|
118
|
-
current_size = await vs_manager.get_content_size(agent_id)
|
|
119
|
+
current_size = await vector_manager.get_content_size(agent_id)
|
|
119
120
|
|
|
120
121
|
# Update metadata
|
|
121
|
-
metadata_manager = MetadataManager(
|
|
122
|
+
metadata_manager = MetadataManager(vector_manager)
|
|
122
123
|
new_metadata = metadata_manager.create_document_metadata(
|
|
123
124
|
title, source, tags, [document], len(text_content)
|
|
124
125
|
)
|
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
"description": "Scrape web content and index it for intelligent querying and retrieval",
|
|
6
6
|
"x-icon": "https://ai.service.crestal.dev/skills/web_scraper/langchain.png",
|
|
7
7
|
"x-tags": [
|
|
8
|
-
"
|
|
9
|
-
"Content Indexing",
|
|
10
|
-
"Vector Search",
|
|
11
|
-
"LangChain",
|
|
12
|
-
"Document Retrieval"
|
|
8
|
+
"Knowledge Base"
|
|
13
9
|
],
|
|
14
10
|
"properties": {
|
|
15
11
|
"enabled": {
|
|
@@ -140,4 +136,4 @@
|
|
|
140
136
|
"enabled"
|
|
141
137
|
],
|
|
142
138
|
"additionalProperties": true
|
|
143
|
-
}
|
|
139
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import List, Type
|
|
3
2
|
|
|
4
3
|
from pydantic import BaseModel, Field
|
|
5
4
|
|
|
@@ -19,7 +18,7 @@ logger = logging.getLogger(__name__)
|
|
|
19
18
|
class ScrapeAndIndexInput(BaseModel):
|
|
20
19
|
"""Input for ScrapeAndIndex tool."""
|
|
21
20
|
|
|
22
|
-
urls:
|
|
21
|
+
urls: list[str] = Field(
|
|
23
22
|
description="List of URLs to scrape and index. Each URL should be a valid web address starting with http:// or https://",
|
|
24
23
|
min_items=1,
|
|
25
24
|
max_items=25,
|
|
@@ -67,11 +66,11 @@ class ScrapeAndIndex(WebScraperBaseTool):
|
|
|
67
66
|
"Use this tool to collect and index web content that you want to reference later.\n"
|
|
68
67
|
"The indexed content can then be queried using the query_indexed_content tool."
|
|
69
68
|
)
|
|
70
|
-
args_schema:
|
|
69
|
+
args_schema: type[BaseModel] = ScrapeAndIndexInput
|
|
71
70
|
|
|
72
71
|
async def _arun(
|
|
73
72
|
self,
|
|
74
|
-
urls:
|
|
73
|
+
urls: list[str],
|
|
75
74
|
chunk_size: int = DEFAULT_CHUNK_SIZE,
|
|
76
75
|
chunk_overlap: int = DEFAULT_CHUNK_OVERLAP,
|
|
77
76
|
**kwargs,
|
|
@@ -92,9 +91,12 @@ class ScrapeAndIndex(WebScraperBaseTool):
|
|
|
92
91
|
f"[{agent_id}] Starting scrape and index operation with {len(urls)} URLs"
|
|
93
92
|
)
|
|
94
93
|
|
|
94
|
+
embedding_api_key = self.get_openai_api_key()
|
|
95
|
+
vector_manager = VectorStoreManager(embedding_api_key)
|
|
96
|
+
|
|
95
97
|
# Use the utility function to scrape and index URLs
|
|
96
98
|
total_chunks, was_merged, valid_urls = await scrape_and_index_urls(
|
|
97
|
-
urls, agent_id,
|
|
99
|
+
urls, agent_id, vector_manager, chunk_size, chunk_overlap
|
|
98
100
|
)
|
|
99
101
|
|
|
100
102
|
logger.info(
|
|
@@ -110,12 +112,11 @@ class ScrapeAndIndex(WebScraperBaseTool):
|
|
|
110
112
|
return "Error: No content could be extracted from the provided URLs."
|
|
111
113
|
|
|
112
114
|
# Get current storage size for response
|
|
113
|
-
|
|
114
|
-
current_size = await vs_manager.get_content_size(agent_id)
|
|
115
|
+
current_size = await vector_manager.get_content_size(agent_id)
|
|
115
116
|
size_limit_reached = len(valid_urls) < len(urls)
|
|
116
117
|
|
|
117
118
|
# Update metadata
|
|
118
|
-
metadata_manager = MetadataManager(
|
|
119
|
+
metadata_manager = MetadataManager(vector_manager)
|
|
119
120
|
new_metadata = metadata_manager.create_url_metadata(
|
|
120
121
|
valid_urls, [], "scrape_and_index"
|
|
121
122
|
)
|
|
@@ -169,7 +170,7 @@ class QueryIndexedContent(WebScraperBaseTool):
|
|
|
169
170
|
"Use this tool to search through content that was previously scraped and indexed.\n"
|
|
170
171
|
"This tool can help answer questions based on the indexed web content."
|
|
171
172
|
)
|
|
172
|
-
args_schema:
|
|
173
|
+
args_schema: type[BaseModel] = QueryIndexInput
|
|
173
174
|
|
|
174
175
|
async def _arun(
|
|
175
176
|
self,
|
|
@@ -196,9 +197,9 @@ class QueryIndexedContent(WebScraperBaseTool):
|
|
|
196
197
|
|
|
197
198
|
logger.info(f"[{agent_id}] Looking for vector store: {vector_store_key}")
|
|
198
199
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
)
|
|
200
|
+
embedding_api_key = self.get_openai_api_key()
|
|
201
|
+
vector_manager = VectorStoreManager(embedding_api_key)
|
|
202
|
+
stored_data = await vector_manager.get_existing_vector_store(agent_id)
|
|
202
203
|
|
|
203
204
|
if not stored_data:
|
|
204
205
|
logger.warning(f"[{agent_id}] No vector store found")
|
|
@@ -210,9 +211,8 @@ class QueryIndexedContent(WebScraperBaseTool):
|
|
|
210
211
|
|
|
211
212
|
# Create embeddings and decode vector store
|
|
212
213
|
logger.info(f"[{agent_id}] Decoding vector store")
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
vector_store = vs_manager.decode_vector_store(
|
|
214
|
+
embeddings = vector_manager.create_embeddings()
|
|
215
|
+
vector_store = vector_manager.decode_vector_store(
|
|
216
216
|
stored_data["faiss_files"], embeddings
|
|
217
217
|
)
|
|
218
218
|
|