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,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import List, Optional, Type
|
|
3
2
|
|
|
4
3
|
import httpx
|
|
5
4
|
from langchain_core.documents import Document
|
|
@@ -16,7 +15,7 @@ class FirecrawlScrapeInput(BaseModel):
|
|
|
16
15
|
url: str = Field(
|
|
17
16
|
description="The URL to scrape. Must be a valid HTTP or HTTPS URL."
|
|
18
17
|
)
|
|
19
|
-
formats:
|
|
18
|
+
formats: list[str] = Field(
|
|
20
19
|
description="Output formats to include in the response. Options: 'markdown', 'html', 'rawHtml', 'screenshot', 'links', 'json'",
|
|
21
20
|
default=["markdown"],
|
|
22
21
|
)
|
|
@@ -24,11 +23,11 @@ class FirecrawlScrapeInput(BaseModel):
|
|
|
24
23
|
description="Whether to extract only the main content (excluding headers, footers, navigation, etc.)",
|
|
25
24
|
default=True,
|
|
26
25
|
)
|
|
27
|
-
include_tags:
|
|
26
|
+
include_tags: list[str] | None = Field(
|
|
28
27
|
description="HTML tags, classes, or IDs to include in the response (e.g., ['h1', 'p', '.main-content'])",
|
|
29
28
|
default=None,
|
|
30
29
|
)
|
|
31
|
-
exclude_tags:
|
|
30
|
+
exclude_tags: list[str] | None = Field(
|
|
32
31
|
description="HTML tags, classes, or IDs to exclude from the response (e.g., ['#ad', '#footer'])",
|
|
33
32
|
default=None,
|
|
34
33
|
)
|
|
@@ -62,10 +61,11 @@ class FirecrawlScrapeInput(BaseModel):
|
|
|
62
61
|
|
|
63
62
|
|
|
64
63
|
class FirecrawlScrape(FirecrawlBaseTool):
|
|
65
|
-
"""Tool for scraping web pages using Firecrawl.
|
|
64
|
+
"""Tool for scraping web pages using Firecrawl with REPLACE behavior.
|
|
66
65
|
|
|
67
|
-
This tool uses Firecrawl's API to scrape web pages and
|
|
68
|
-
|
|
66
|
+
This tool uses Firecrawl's API to scrape web pages and REPLACES any existing
|
|
67
|
+
indexed content for the same URL instead of appending to it. This prevents
|
|
68
|
+
duplicate content when re-scraping the same page.
|
|
69
69
|
|
|
70
70
|
Attributes:
|
|
71
71
|
name: The name of the tool.
|
|
@@ -75,20 +75,20 @@ class FirecrawlScrape(FirecrawlBaseTool):
|
|
|
75
75
|
|
|
76
76
|
name: str = "firecrawl_scrape"
|
|
77
77
|
description: str = (
|
|
78
|
-
"Scrape a single web page and
|
|
78
|
+
"Scrape a single web page and REPLACE any existing indexed content for that URL. "
|
|
79
|
+
"Unlike regular scrape, this tool removes old content before adding new content, preventing duplicates. "
|
|
79
80
|
"This tool can handle JavaScript-rendered content, PDFs, and dynamic websites. "
|
|
80
|
-
"
|
|
81
|
-
"Use this when you need to extract clean, structured content from a specific URL."
|
|
81
|
+
"Use this when you want to refresh/update content from a URL that was previously scraped."
|
|
82
82
|
)
|
|
83
|
-
args_schema:
|
|
83
|
+
args_schema: type[BaseModel] = FirecrawlScrapeInput
|
|
84
84
|
|
|
85
85
|
async def _arun(
|
|
86
86
|
self,
|
|
87
87
|
url: str,
|
|
88
|
-
formats:
|
|
88
|
+
formats: list[str] = None,
|
|
89
89
|
only_main_content: bool = True,
|
|
90
|
-
include_tags:
|
|
91
|
-
exclude_tags:
|
|
90
|
+
include_tags: list[str] | None = None,
|
|
91
|
+
exclude_tags: list[str] | None = None,
|
|
92
92
|
wait_for: int = 0,
|
|
93
93
|
timeout: int = 30000,
|
|
94
94
|
index_content: bool = True,
|
|
@@ -123,9 +123,8 @@ class FirecrawlScrape(FirecrawlBaseTool):
|
|
|
123
123
|
"rate_limit_minutes"
|
|
124
124
|
):
|
|
125
125
|
await self.user_rate_limit_by_category(
|
|
126
|
-
context.user_id,
|
|
127
126
|
skill_config["rate_limit_number"],
|
|
128
|
-
skill_config["rate_limit_minutes"],
|
|
127
|
+
skill_config["rate_limit_minutes"] * 60,
|
|
129
128
|
)
|
|
130
129
|
|
|
131
130
|
# Get the API key from the agent's configuration
|
|
@@ -187,7 +186,7 @@ class FirecrawlScrape(FirecrawlBaseTool):
|
|
|
187
186
|
result_data = data.get("data", {})
|
|
188
187
|
|
|
189
188
|
# Format the results based on requested formats
|
|
190
|
-
formatted_result = f"Successfully scraped: {url}\n\n"
|
|
189
|
+
formatted_result = f"Successfully scraped (REPLACE mode): {url}\n\n"
|
|
191
190
|
|
|
192
191
|
if "markdown" in formats and result_data.get("markdown"):
|
|
193
192
|
formatted_result += "## Markdown Content\n"
|
|
@@ -236,13 +235,16 @@ class FirecrawlScrape(FirecrawlBaseTool):
|
|
|
236
235
|
formatted_result += f"Language: {metadata['language']}\n"
|
|
237
236
|
formatted_result += "\n"
|
|
238
237
|
|
|
239
|
-
# Index content if requested
|
|
238
|
+
# Index content if requested - REPLACE MODE
|
|
240
239
|
if index_content and result_data.get("markdown"):
|
|
241
240
|
try:
|
|
242
|
-
# Import indexing utilities
|
|
241
|
+
# Import indexing utilities
|
|
242
|
+
from langchain_community.vectorstores import FAISS
|
|
243
|
+
|
|
243
244
|
from intentkit.skills.firecrawl.utils import (
|
|
245
|
+
FirecrawlDocumentProcessor,
|
|
244
246
|
FirecrawlMetadataManager,
|
|
245
|
-
|
|
247
|
+
FirecrawlVectorStoreManager,
|
|
246
248
|
)
|
|
247
249
|
|
|
248
250
|
# Create document from scraped content
|
|
@@ -261,38 +263,146 @@ class FirecrawlScrape(FirecrawlBaseTool):
|
|
|
261
263
|
# Get agent ID for indexing
|
|
262
264
|
agent_id = context.agent_id
|
|
263
265
|
if agent_id:
|
|
264
|
-
#
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
chunk_overlap,
|
|
266
|
+
# Initialize vector store manager
|
|
267
|
+
vs_manager = FirecrawlVectorStoreManager()
|
|
268
|
+
|
|
269
|
+
# Load existing vector store
|
|
270
|
+
existing_vector_store = await vs_manager.load_vector_store(
|
|
271
|
+
agent_id
|
|
271
272
|
)
|
|
272
273
|
|
|
273
|
-
#
|
|
274
|
-
|
|
275
|
-
|
|
274
|
+
# Split the new document into chunks
|
|
275
|
+
split_docs = FirecrawlDocumentProcessor.split_documents(
|
|
276
|
+
[document], chunk_size, chunk_overlap
|
|
276
277
|
)
|
|
277
|
-
|
|
278
|
-
|
|
278
|
+
|
|
279
|
+
# Create embeddings
|
|
280
|
+
embeddings = vs_manager.create_embeddings()
|
|
281
|
+
|
|
282
|
+
if existing_vector_store:
|
|
283
|
+
# Get all existing documents and filter out those from the same URL
|
|
284
|
+
try:
|
|
285
|
+
# Try to access documents directly if available
|
|
286
|
+
if hasattr(
|
|
287
|
+
existing_vector_store, "docstore"
|
|
288
|
+
) and hasattr(
|
|
289
|
+
existing_vector_store.docstore, "_dict"
|
|
290
|
+
):
|
|
291
|
+
# Access FAISS documents directly
|
|
292
|
+
all_docs = list(
|
|
293
|
+
existing_vector_store.docstore._dict.values()
|
|
294
|
+
)
|
|
295
|
+
else:
|
|
296
|
+
# Fallback: use a reasonable k value for similarity search
|
|
297
|
+
# Use a dummy query to retrieve documents
|
|
298
|
+
all_docs = existing_vector_store.similarity_search(
|
|
299
|
+
"dummy", # Use a dummy query instead of empty string
|
|
300
|
+
k=1000, # Use reasonable upper bound
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
# Filter out documents from the same URL
|
|
304
|
+
preserved_docs = [
|
|
305
|
+
doc
|
|
306
|
+
for doc in all_docs
|
|
307
|
+
if doc.metadata.get("source") != url
|
|
308
|
+
]
|
|
309
|
+
|
|
310
|
+
logger.info(
|
|
311
|
+
f"firecrawl_scrape: Preserving {len(preserved_docs)} docs from other URLs, "
|
|
312
|
+
f"replacing content from {url}"
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
# Create new vector store with preserved docs + new docs
|
|
316
|
+
if preserved_docs:
|
|
317
|
+
# Combine preserved and new documents
|
|
318
|
+
all_documents = preserved_docs + split_docs
|
|
319
|
+
new_vector_store = FAISS.from_documents(
|
|
320
|
+
all_documents, embeddings
|
|
321
|
+
)
|
|
322
|
+
formatted_result += "\n## Content Replacement\n"
|
|
323
|
+
formatted_result += f"Replaced existing content for URL: {url}\n"
|
|
324
|
+
num_preserved_urls = len(
|
|
325
|
+
set(
|
|
326
|
+
doc.metadata.get("source", "")
|
|
327
|
+
for doc in preserved_docs
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
formatted_result += f"Preserved content from {num_preserved_urls} other URLs\n"
|
|
331
|
+
else:
|
|
332
|
+
# No other documents to preserve, just create from new docs
|
|
333
|
+
new_vector_store = FAISS.from_documents(
|
|
334
|
+
split_docs, embeddings
|
|
335
|
+
)
|
|
336
|
+
formatted_result += "\n## Content Replacement\n"
|
|
337
|
+
formatted_result += f"Created new index with content from: {url}\n"
|
|
338
|
+
except Exception as e:
|
|
339
|
+
logger.warning(
|
|
340
|
+
f"Could not preserve other URLs, creating fresh index: {e}"
|
|
341
|
+
)
|
|
342
|
+
# Fallback: create new store with just the new documents
|
|
343
|
+
new_vector_store = FAISS.from_documents(
|
|
344
|
+
split_docs, embeddings
|
|
345
|
+
)
|
|
346
|
+
formatted_result += "\n## Content Replacement\n"
|
|
347
|
+
formatted_result += f"Created fresh index with content from: {url}\n"
|
|
348
|
+
else:
|
|
349
|
+
# No existing store, create new one
|
|
350
|
+
new_vector_store = FAISS.from_documents(
|
|
351
|
+
split_docs, embeddings
|
|
352
|
+
)
|
|
353
|
+
formatted_result += "\n## Content Indexing\n"
|
|
354
|
+
formatted_result += (
|
|
355
|
+
f"Created new index with content from: {url}\n"
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
# Save the new vector store
|
|
359
|
+
await vs_manager.save_vector_store(
|
|
360
|
+
agent_id, new_vector_store, chunk_size, chunk_overlap
|
|
279
361
|
)
|
|
280
|
-
|
|
281
|
-
|
|
362
|
+
|
|
363
|
+
# Update metadata to track all URLs
|
|
364
|
+
# Get existing metadata to preserve other URLs
|
|
365
|
+
metadata_key = f"indexed_urls_{agent_id}"
|
|
366
|
+
existing_metadata = await self.get_agent_skill_data_raw(
|
|
367
|
+
"firecrawl", metadata_key
|
|
282
368
|
)
|
|
283
369
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
370
|
+
if existing_metadata and existing_metadata.get("urls"):
|
|
371
|
+
# Remove the current URL and add it back (to update timestamp)
|
|
372
|
+
existing_urls = [
|
|
373
|
+
u for u in existing_metadata["urls"] if u != url
|
|
374
|
+
]
|
|
375
|
+
existing_urls.append(url)
|
|
376
|
+
updated_metadata = {
|
|
377
|
+
"urls": existing_urls,
|
|
378
|
+
"document_count": len(existing_urls),
|
|
379
|
+
"source_type": "firecrawl_mixed",
|
|
380
|
+
"indexed_at": str(len(existing_urls)),
|
|
381
|
+
}
|
|
382
|
+
else:
|
|
383
|
+
# Create new metadata
|
|
384
|
+
updated_metadata = (
|
|
385
|
+
FirecrawlMetadataManager.create_url_metadata(
|
|
386
|
+
[url], [document], "firecrawl_scrape"
|
|
387
|
+
)
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
await FirecrawlMetadataManager.update_metadata(
|
|
391
|
+
agent_id, updated_metadata
|
|
287
392
|
)
|
|
288
|
-
|
|
393
|
+
|
|
394
|
+
formatted_result += "\n## Content Indexing (REPLACE MODE)\n"
|
|
395
|
+
formatted_result += "Successfully REPLACED indexed content in vector store:\n"
|
|
396
|
+
formatted_result += f"- Chunks created: {len(split_docs)}\n"
|
|
289
397
|
formatted_result += f"- Chunk size: {chunk_size}\n"
|
|
290
398
|
formatted_result += f"- Chunk overlap: {chunk_overlap}\n"
|
|
291
|
-
formatted_result +=
|
|
399
|
+
formatted_result += (
|
|
400
|
+
"- Previous content for this URL: REPLACED\n"
|
|
401
|
+
)
|
|
292
402
|
formatted_result += "Use the 'firecrawl_query_indexed_content' skill to search this content.\n"
|
|
293
403
|
|
|
294
404
|
logger.info(
|
|
295
|
-
f"firecrawl_scrape: Successfully
|
|
405
|
+
f"firecrawl_scrape: Successfully replaced content for {url} with {len(split_docs)} chunks"
|
|
296
406
|
)
|
|
297
407
|
else:
|
|
298
408
|
formatted_result += "\n## Content Indexing\n"
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
import re
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
6
6
|
|
|
7
|
-
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
|
8
7
|
from langchain_community.vectorstores import FAISS
|
|
9
8
|
from langchain_core.documents import Document
|
|
10
9
|
from langchain_openai import OpenAIEmbeddings
|
|
10
|
+
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
|
11
11
|
|
|
12
|
-
from intentkit.
|
|
12
|
+
from intentkit.config.config import config
|
|
13
|
+
from intentkit.models.skill import AgentSkillData, AgentSkillDataCreate
|
|
13
14
|
|
|
14
15
|
logger = logging.getLogger(__name__)
|
|
15
16
|
|
|
@@ -35,8 +36,8 @@ class FirecrawlDocumentProcessor:
|
|
|
35
36
|
|
|
36
37
|
@staticmethod
|
|
37
38
|
def split_documents(
|
|
38
|
-
documents:
|
|
39
|
-
) ->
|
|
39
|
+
documents: list[Document], chunk_size: int = 1000, chunk_overlap: int = 200
|
|
40
|
+
) -> list[Document]:
|
|
40
41
|
"""Split documents into smaller chunks for better indexing."""
|
|
41
42
|
text_splitter = RecursiveCharacterTextSplitter(
|
|
42
43
|
chunk_size=chunk_size,
|
|
@@ -62,20 +63,25 @@ class FirecrawlDocumentProcessor:
|
|
|
62
63
|
class FirecrawlVectorStoreManager:
|
|
63
64
|
"""Manages vector store operations for Firecrawl content."""
|
|
64
65
|
|
|
65
|
-
def __init__(self,
|
|
66
|
-
self.
|
|
66
|
+
def __init__(self, embedding_api_key: str | None = None):
|
|
67
|
+
self._embedding_api_key = embedding_api_key
|
|
68
|
+
|
|
69
|
+
def _resolve_api_key(self) -> str:
|
|
70
|
+
"""Resolve the API key to use for embeddings."""
|
|
71
|
+
if self._embedding_api_key:
|
|
72
|
+
return self._embedding_api_key
|
|
73
|
+
if config.openai_api_key:
|
|
74
|
+
return config.openai_api_key
|
|
75
|
+
raise ValueError("OpenAI API key not found in system configuration")
|
|
67
76
|
|
|
68
77
|
def create_embeddings(self) -> OpenAIEmbeddings:
|
|
69
78
|
"""Create OpenAI embeddings instance."""
|
|
70
|
-
openai_api_key = self.
|
|
71
|
-
if not openai_api_key:
|
|
72
|
-
raise ValueError("OpenAI API key not found in system configuration")
|
|
73
|
-
|
|
79
|
+
openai_api_key = self._resolve_api_key()
|
|
74
80
|
return OpenAIEmbeddings(
|
|
75
81
|
openai_api_key=openai_api_key, model="text-embedding-3-small"
|
|
76
82
|
)
|
|
77
83
|
|
|
78
|
-
def encode_vector_store(self, vector_store: FAISS) ->
|
|
84
|
+
def encode_vector_store(self, vector_store: FAISS) -> dict[str, str]:
|
|
79
85
|
"""Encode FAISS vector store to base64 for storage (compatible with web_scraper)."""
|
|
80
86
|
import base64
|
|
81
87
|
import os
|
|
@@ -100,7 +106,7 @@ class FirecrawlVectorStoreManager:
|
|
|
100
106
|
raise
|
|
101
107
|
|
|
102
108
|
def decode_vector_store(
|
|
103
|
-
self, encoded_files:
|
|
109
|
+
self, encoded_files: dict[str, str], embeddings: OpenAIEmbeddings
|
|
104
110
|
) -> FAISS:
|
|
105
111
|
"""Decode base64 files back to FAISS vector store (compatible with web_scraper)."""
|
|
106
112
|
import base64
|
|
@@ -125,11 +131,11 @@ class FirecrawlVectorStoreManager:
|
|
|
125
131
|
logger.error(f"Error decoding vector store: {e}")
|
|
126
132
|
raise
|
|
127
133
|
|
|
128
|
-
async def load_vector_store(self, agent_id: str) ->
|
|
134
|
+
async def load_vector_store(self, agent_id: str) -> FAISS | None:
|
|
129
135
|
"""Load existing vector store for an agent."""
|
|
130
136
|
try:
|
|
131
137
|
vector_store_key = f"vector_store_{agent_id}"
|
|
132
|
-
stored_data = await
|
|
138
|
+
stored_data = await AgentSkillData.get(
|
|
133
139
|
agent_id, "web_scraper", vector_store_key
|
|
134
140
|
)
|
|
135
141
|
|
|
@@ -162,9 +168,13 @@ class FirecrawlVectorStoreManager:
|
|
|
162
168
|
"chunk_overlap": chunk_overlap,
|
|
163
169
|
}
|
|
164
170
|
|
|
165
|
-
|
|
166
|
-
agent_id,
|
|
171
|
+
skill_data = AgentSkillDataCreate(
|
|
172
|
+
agent_id=agent_id,
|
|
173
|
+
skill="web_scraper",
|
|
174
|
+
key=vector_store_key,
|
|
175
|
+
data=storage_data,
|
|
167
176
|
)
|
|
177
|
+
await skill_data.save()
|
|
168
178
|
|
|
169
179
|
except Exception as e:
|
|
170
180
|
logger.error(f"Error saving vector store for agent {agent_id}: {e}")
|
|
@@ -174,12 +184,10 @@ class FirecrawlVectorStoreManager:
|
|
|
174
184
|
class FirecrawlMetadataManager:
|
|
175
185
|
"""Manages metadata for Firecrawl indexed content."""
|
|
176
186
|
|
|
177
|
-
|
|
178
|
-
self.skill_store = skill_store
|
|
179
|
-
|
|
187
|
+
@staticmethod
|
|
180
188
|
def create_url_metadata(
|
|
181
|
-
|
|
182
|
-
) ->
|
|
189
|
+
urls: list[str], documents: list[Document], source_type: str
|
|
190
|
+
) -> dict[str, Any]:
|
|
183
191
|
"""Create metadata for indexed URLs."""
|
|
184
192
|
return {
|
|
185
193
|
"urls": urls,
|
|
@@ -188,34 +196,38 @@ class FirecrawlMetadataManager:
|
|
|
188
196
|
"indexed_at": str(len(urls)), # Simple counter
|
|
189
197
|
}
|
|
190
198
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
) -> None:
|
|
199
|
+
@staticmethod
|
|
200
|
+
@staticmethod
|
|
201
|
+
async def update_metadata(agent_id: str, new_metadata: dict[str, Any]) -> None:
|
|
194
202
|
"""Update metadata for an agent."""
|
|
195
203
|
try:
|
|
196
204
|
metadata_key = f"indexed_urls_{agent_id}"
|
|
197
|
-
|
|
198
|
-
agent_id,
|
|
205
|
+
skill_data = AgentSkillDataCreate(
|
|
206
|
+
agent_id=agent_id,
|
|
207
|
+
skill="web_scraper",
|
|
208
|
+
key=metadata_key,
|
|
209
|
+
data=new_metadata,
|
|
199
210
|
)
|
|
211
|
+
await skill_data.save()
|
|
200
212
|
except Exception as e:
|
|
201
213
|
logger.error(f"Error updating metadata for agent {agent_id}: {e}")
|
|
202
214
|
raise
|
|
203
215
|
|
|
204
216
|
|
|
205
217
|
async def index_documents(
|
|
206
|
-
documents:
|
|
218
|
+
documents: list[Document],
|
|
207
219
|
agent_id: str,
|
|
208
|
-
|
|
220
|
+
vector_manager: FirecrawlVectorStoreManager,
|
|
209
221
|
chunk_size: int = 1000,
|
|
210
222
|
chunk_overlap: int = 200,
|
|
211
|
-
) ->
|
|
223
|
+
) -> tuple[int, bool]:
|
|
212
224
|
"""
|
|
213
225
|
Index documents into the Firecrawl vector store.
|
|
214
226
|
|
|
215
227
|
Args:
|
|
216
228
|
documents: List of documents to index
|
|
217
229
|
agent_id: Agent ID for storage
|
|
218
|
-
|
|
230
|
+
vector_manager: Vector store manager
|
|
219
231
|
chunk_size: Size of text chunks
|
|
220
232
|
chunk_overlap: Overlap between chunks
|
|
221
233
|
|
|
@@ -224,8 +236,6 @@ async def index_documents(
|
|
|
224
236
|
"""
|
|
225
237
|
try:
|
|
226
238
|
# Initialize managers
|
|
227
|
-
vs_manager = FirecrawlVectorStoreManager(skill_store)
|
|
228
|
-
|
|
229
239
|
# Split documents into chunks
|
|
230
240
|
split_docs = FirecrawlDocumentProcessor.split_documents(
|
|
231
241
|
documents, chunk_size, chunk_overlap
|
|
@@ -236,10 +246,10 @@ async def index_documents(
|
|
|
236
246
|
return 0, False
|
|
237
247
|
|
|
238
248
|
# Create embeddings
|
|
239
|
-
embeddings =
|
|
249
|
+
embeddings = vector_manager.create_embeddings()
|
|
240
250
|
|
|
241
251
|
# Try to load existing vector store
|
|
242
|
-
existing_vector_store = await
|
|
252
|
+
existing_vector_store = await vector_manager.load_vector_store(agent_id)
|
|
243
253
|
|
|
244
254
|
if existing_vector_store:
|
|
245
255
|
# Add to existing vector store
|
|
@@ -252,7 +262,7 @@ async def index_documents(
|
|
|
252
262
|
was_merged = False
|
|
253
263
|
|
|
254
264
|
# Save the vector store
|
|
255
|
-
await
|
|
265
|
+
await vector_manager.save_vector_store(
|
|
256
266
|
agent_id, vector_store, chunk_size, chunk_overlap
|
|
257
267
|
)
|
|
258
268
|
|
|
@@ -269,16 +279,16 @@ async def index_documents(
|
|
|
269
279
|
async def query_indexed_content(
|
|
270
280
|
query: str,
|
|
271
281
|
agent_id: str,
|
|
272
|
-
|
|
282
|
+
vector_manager: FirecrawlVectorStoreManager,
|
|
273
283
|
max_results: int = 4,
|
|
274
|
-
) ->
|
|
284
|
+
) -> list[Document]:
|
|
275
285
|
"""
|
|
276
286
|
Query the Firecrawl indexed content.
|
|
277
287
|
|
|
278
288
|
Args:
|
|
279
289
|
query: Search query
|
|
280
290
|
agent_id: Agent ID
|
|
281
|
-
|
|
291
|
+
vector_manager: Manager for vector store persistence
|
|
282
292
|
max_results: Maximum number of results to return
|
|
283
293
|
|
|
284
294
|
Returns:
|
|
@@ -286,10 +296,8 @@ async def query_indexed_content(
|
|
|
286
296
|
"""
|
|
287
297
|
try:
|
|
288
298
|
# Initialize vector store manager
|
|
289
|
-
vs_manager = FirecrawlVectorStoreManager(skill_store)
|
|
290
|
-
|
|
291
299
|
# Load vector store
|
|
292
|
-
vector_store = await
|
|
300
|
+
vector_store = await vector_manager.load_vector_store(agent_id)
|
|
293
301
|
|
|
294
302
|
if not vector_store:
|
|
295
303
|
logger.warning(f"No vector store found for agent {agent_id}")
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from typing import TypedDict
|
|
2
2
|
|
|
3
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
4
3
|
from intentkit.skills.base import SkillConfig, SkillState
|
|
5
4
|
from intentkit.skills.github.base import GitHubBaseTool
|
|
6
5
|
from intentkit.skills.github.github_search import GitHubSearch
|
|
@@ -22,7 +21,6 @@ class Config(SkillConfig):
|
|
|
22
21
|
async def get_skills(
|
|
23
22
|
config: "Config",
|
|
24
23
|
is_private: bool,
|
|
25
|
-
store: SkillStoreABC,
|
|
26
24
|
**_,
|
|
27
25
|
) -> list[GitHubBaseTool]:
|
|
28
26
|
"""Get all GitHub skills."""
|
|
@@ -36,19 +34,16 @@ async def get_skills(
|
|
|
36
34
|
available_skills.append(skill_name)
|
|
37
35
|
|
|
38
36
|
# Get each skill using the cached getter
|
|
39
|
-
return [get_github_skill(name
|
|
37
|
+
return [get_github_skill(name) for name in available_skills]
|
|
40
38
|
|
|
41
39
|
|
|
42
40
|
def get_github_skill(
|
|
43
41
|
name: str,
|
|
44
|
-
store: SkillStoreABC,
|
|
45
42
|
) -> GitHubBaseTool:
|
|
46
43
|
"""Get a GitHub skill by name."""
|
|
47
44
|
if name == "github_search":
|
|
48
45
|
if name not in _cache:
|
|
49
|
-
_cache[name] = GitHubSearch(
|
|
50
|
-
skill_store=store,
|
|
51
|
-
)
|
|
46
|
+
_cache[name] = GitHubSearch()
|
|
52
47
|
return _cache[name]
|
|
53
48
|
else:
|
|
54
49
|
raise ValueError(f"Unknown GitHub skill: {name}")
|
intentkit/skills/github/base.py
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
from typing import Type
|
|
2
|
-
|
|
3
1
|
from pydantic import BaseModel, Field
|
|
4
2
|
|
|
5
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
6
3
|
from intentkit.skills.base import IntentKitSkill
|
|
7
4
|
|
|
8
5
|
|
|
@@ -11,10 +8,7 @@ class GitHubBaseTool(IntentKitSkill):
|
|
|
11
8
|
|
|
12
9
|
name: str = Field(description="The name of the tool")
|
|
13
10
|
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
|
-
)
|
|
11
|
+
args_schema: type[BaseModel]
|
|
18
12
|
|
|
19
13
|
@property
|
|
20
14
|
def category(self) -> str:
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from enum import Enum
|
|
3
|
-
from typing import Type
|
|
4
3
|
|
|
5
4
|
import httpx
|
|
6
5
|
from pydantic import BaseModel, Field
|
|
@@ -54,7 +53,7 @@ class GitHubSearch(GitHubBaseTool):
|
|
|
54
53
|
"- Code snippets across GitHub repositories\n"
|
|
55
54
|
"You must call this tool whenever the user asks about finding something on GitHub."
|
|
56
55
|
)
|
|
57
|
-
args_schema:
|
|
56
|
+
args_schema: type[BaseModel] = GitHubSearchInput
|
|
58
57
|
|
|
59
58
|
async def _arun(
|
|
60
59
|
self,
|
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
"description": "Search capabilities for GitHub repositories, users, and code",
|
|
6
6
|
"x-icon": "https://ai.service.crestal.dev/skills/github/github.jpg",
|
|
7
7
|
"x-tags": [
|
|
8
|
-
"
|
|
9
|
-
"Search"
|
|
10
|
-
"Code"
|
|
8
|
+
"Developer Tools",
|
|
9
|
+
"Search"
|
|
11
10
|
],
|
|
12
11
|
"properties": {
|
|
13
12
|
"enabled": {
|
|
@@ -56,4 +55,4 @@
|
|
|
56
55
|
"enabled"
|
|
57
56
|
],
|
|
58
57
|
"additionalProperties": true
|
|
59
|
-
}
|
|
58
|
+
}
|