intentkit 0.5.0__py3-none-any.whl → 0.5.2__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 +17 -0
- intentkit/abstracts/__init__.py +0 -0
- intentkit/abstracts/agent.py +60 -0
- intentkit/abstracts/api.py +4 -0
- intentkit/abstracts/engine.py +38 -0
- intentkit/abstracts/exception.py +9 -0
- intentkit/abstracts/graph.py +25 -0
- intentkit/abstracts/skill.py +129 -0
- intentkit/abstracts/twitter.py +54 -0
- intentkit/clients/__init__.py +14 -0
- intentkit/clients/cdp.py +53 -0
- intentkit/clients/twitter.py +445 -0
- intentkit/config/__init__.py +0 -0
- intentkit/config/config.py +164 -0
- intentkit/core/__init__.py +0 -0
- intentkit/core/agent.py +191 -0
- intentkit/core/api.py +40 -0
- intentkit/core/client.py +45 -0
- intentkit/core/credit.py +1767 -0
- intentkit/core/engine.py +1018 -0
- intentkit/core/node.py +223 -0
- intentkit/core/prompt.py +58 -0
- intentkit/core/skill.py +124 -0
- intentkit/models/agent.py +1689 -0
- intentkit/models/agent_data.py +810 -0
- intentkit/models/agent_schema.json +733 -0
- intentkit/models/app_setting.py +156 -0
- intentkit/models/base.py +9 -0
- intentkit/models/chat.py +581 -0
- intentkit/models/conversation.py +286 -0
- intentkit/models/credit.py +1406 -0
- intentkit/models/db.py +120 -0
- intentkit/models/db_mig.py +102 -0
- intentkit/models/generator.py +347 -0
- intentkit/models/llm.py +746 -0
- intentkit/models/redis.py +132 -0
- intentkit/models/skill.py +466 -0
- intentkit/models/user.py +243 -0
- intentkit/skills/__init__.py +12 -0
- intentkit/skills/acolyt/__init__.py +83 -0
- intentkit/skills/acolyt/acolyt.jpg +0 -0
- intentkit/skills/acolyt/ask.py +128 -0
- intentkit/skills/acolyt/base.py +28 -0
- intentkit/skills/acolyt/schema.json +89 -0
- intentkit/skills/aixbt/README.md +71 -0
- intentkit/skills/aixbt/__init__.py +73 -0
- intentkit/skills/aixbt/aixbt.jpg +0 -0
- intentkit/skills/aixbt/base.py +21 -0
- intentkit/skills/aixbt/projects.py +153 -0
- intentkit/skills/aixbt/schema.json +99 -0
- intentkit/skills/allora/__init__.py +83 -0
- intentkit/skills/allora/allora.jpeg +0 -0
- intentkit/skills/allora/base.py +28 -0
- intentkit/skills/allora/price.py +130 -0
- intentkit/skills/allora/schema.json +89 -0
- intentkit/skills/base.py +174 -0
- intentkit/skills/carv/README.md +95 -0
- intentkit/skills/carv/__init__.py +121 -0
- intentkit/skills/carv/base.py +183 -0
- intentkit/skills/carv/carv.webp +0 -0
- intentkit/skills/carv/fetch_news.py +92 -0
- intentkit/skills/carv/onchain_query.py +164 -0
- intentkit/skills/carv/schema.json +137 -0
- intentkit/skills/carv/token_info_and_price.py +110 -0
- intentkit/skills/cdp/__init__.py +137 -0
- intentkit/skills/cdp/base.py +21 -0
- intentkit/skills/cdp/cdp.png +0 -0
- intentkit/skills/cdp/get_balance.py +81 -0
- intentkit/skills/cdp/schema.json +473 -0
- intentkit/skills/chainlist/README.md +38 -0
- intentkit/skills/chainlist/__init__.py +54 -0
- intentkit/skills/chainlist/base.py +21 -0
- intentkit/skills/chainlist/chain_lookup.py +208 -0
- intentkit/skills/chainlist/chainlist.png +0 -0
- intentkit/skills/chainlist/schema.json +47 -0
- intentkit/skills/common/__init__.py +82 -0
- intentkit/skills/common/base.py +21 -0
- intentkit/skills/common/common.jpg +0 -0
- intentkit/skills/common/current_time.py +84 -0
- intentkit/skills/common/schema.json +57 -0
- intentkit/skills/cookiefun/README.md +121 -0
- intentkit/skills/cookiefun/__init__.py +78 -0
- intentkit/skills/cookiefun/base.py +41 -0
- intentkit/skills/cookiefun/constants.py +18 -0
- intentkit/skills/cookiefun/cookiefun.png +0 -0
- intentkit/skills/cookiefun/get_account_details.py +171 -0
- intentkit/skills/cookiefun/get_account_feed.py +282 -0
- intentkit/skills/cookiefun/get_account_smart_followers.py +181 -0
- intentkit/skills/cookiefun/get_sectors.py +128 -0
- intentkit/skills/cookiefun/schema.json +155 -0
- intentkit/skills/cookiefun/search_accounts.py +225 -0
- intentkit/skills/cryptocompare/__init__.py +130 -0
- intentkit/skills/cryptocompare/api.py +159 -0
- intentkit/skills/cryptocompare/base.py +303 -0
- intentkit/skills/cryptocompare/cryptocompare.png +0 -0
- intentkit/skills/cryptocompare/fetch_news.py +96 -0
- intentkit/skills/cryptocompare/fetch_price.py +99 -0
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +113 -0
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +109 -0
- intentkit/skills/cryptocompare/fetch_top_volume.py +108 -0
- intentkit/skills/cryptocompare/fetch_trading_signals.py +107 -0
- intentkit/skills/cryptocompare/schema.json +168 -0
- intentkit/skills/cryptopanic/__init__.py +108 -0
- intentkit/skills/cryptopanic/base.py +51 -0
- intentkit/skills/cryptopanic/cryptopanic.png +0 -0
- intentkit/skills/cryptopanic/fetch_crypto_news.py +153 -0
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +136 -0
- intentkit/skills/cryptopanic/schema.json +103 -0
- intentkit/skills/dapplooker/README.md +92 -0
- intentkit/skills/dapplooker/__init__.py +83 -0
- intentkit/skills/dapplooker/base.py +26 -0
- intentkit/skills/dapplooker/dapplooker.jpg +0 -0
- intentkit/skills/dapplooker/dapplooker_token_data.py +476 -0
- intentkit/skills/dapplooker/schema.json +91 -0
- intentkit/skills/defillama/__init__.py +323 -0
- intentkit/skills/defillama/api.py +315 -0
- intentkit/skills/defillama/base.py +135 -0
- intentkit/skills/defillama/coins/__init__.py +0 -0
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +116 -0
- intentkit/skills/defillama/coins/fetch_block.py +98 -0
- intentkit/skills/defillama/coins/fetch_current_prices.py +105 -0
- intentkit/skills/defillama/coins/fetch_first_price.py +100 -0
- intentkit/skills/defillama/coins/fetch_historical_prices.py +110 -0
- intentkit/skills/defillama/coins/fetch_price_chart.py +109 -0
- intentkit/skills/defillama/coins/fetch_price_percentage.py +93 -0
- intentkit/skills/defillama/config/__init__.py +0 -0
- intentkit/skills/defillama/config/chains.py +433 -0
- intentkit/skills/defillama/defillama.jpeg +0 -0
- intentkit/skills/defillama/fees/__init__.py +0 -0
- intentkit/skills/defillama/fees/fetch_fees_overview.py +130 -0
- intentkit/skills/defillama/schema.json +383 -0
- intentkit/skills/defillama/stablecoins/__init__.py +0 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +100 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +129 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +83 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +126 -0
- intentkit/skills/defillama/tests/__init__.py +0 -0
- intentkit/skills/defillama/tests/api_integration.test.py +192 -0
- intentkit/skills/defillama/tests/api_unit.test.py +583 -0
- intentkit/skills/defillama/tvl/__init__.py +0 -0
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +106 -0
- intentkit/skills/defillama/tvl/fetch_chains.py +107 -0
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +91 -0
- intentkit/skills/defillama/tvl/fetch_protocol.py +207 -0
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +93 -0
- intentkit/skills/defillama/tvl/fetch_protocols.py +196 -0
- intentkit/skills/defillama/volumes/__init__.py +0 -0
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +157 -0
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +123 -0
- intentkit/skills/defillama/volumes/fetch_options_overview.py +131 -0
- intentkit/skills/defillama/yields/__init__.py +0 -0
- intentkit/skills/defillama/yields/fetch_pool_chart.py +100 -0
- intentkit/skills/defillama/yields/fetch_pools.py +126 -0
- intentkit/skills/dexscreener/__init__.py +93 -0
- intentkit/skills/dexscreener/base.py +133 -0
- intentkit/skills/dexscreener/dexscreener.png +0 -0
- intentkit/skills/dexscreener/model/__init__.py +0 -0
- intentkit/skills/dexscreener/model/search_token_response.py +82 -0
- intentkit/skills/dexscreener/schema.json +48 -0
- intentkit/skills/dexscreener/search_token.py +321 -0
- intentkit/skills/dune_analytics/__init__.py +103 -0
- intentkit/skills/dune_analytics/base.py +46 -0
- intentkit/skills/dune_analytics/dune.png +0 -0
- intentkit/skills/dune_analytics/fetch_kol_buys.py +128 -0
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +237 -0
- intentkit/skills/dune_analytics/schema.json +99 -0
- intentkit/skills/elfa/README.md +100 -0
- intentkit/skills/elfa/__init__.py +123 -0
- intentkit/skills/elfa/base.py +28 -0
- intentkit/skills/elfa/elfa.jpg +0 -0
- intentkit/skills/elfa/mention.py +504 -0
- intentkit/skills/elfa/schema.json +153 -0
- intentkit/skills/elfa/stats.py +118 -0
- intentkit/skills/elfa/tokens.py +126 -0
- intentkit/skills/enso/README.md +75 -0
- intentkit/skills/enso/__init__.py +114 -0
- intentkit/skills/enso/abi/__init__.py +0 -0
- intentkit/skills/enso/abi/approval.py +279 -0
- intentkit/skills/enso/abi/erc20.py +14 -0
- intentkit/skills/enso/abi/route.py +129 -0
- intentkit/skills/enso/base.py +44 -0
- intentkit/skills/enso/best_yield.py +286 -0
- intentkit/skills/enso/enso.jpg +0 -0
- intentkit/skills/enso/networks.py +105 -0
- intentkit/skills/enso/prices.py +93 -0
- intentkit/skills/enso/route.py +300 -0
- intentkit/skills/enso/schema.json +212 -0
- intentkit/skills/enso/tokens.py +223 -0
- intentkit/skills/enso/wallet.py +381 -0
- intentkit/skills/github/README.md +63 -0
- intentkit/skills/github/__init__.py +54 -0
- intentkit/skills/github/base.py +21 -0
- intentkit/skills/github/github.jpg +0 -0
- intentkit/skills/github/github_search.py +183 -0
- intentkit/skills/github/schema.json +59 -0
- intentkit/skills/heurist/__init__.py +143 -0
- intentkit/skills/heurist/base.py +26 -0
- intentkit/skills/heurist/heurist.png +0 -0
- intentkit/skills/heurist/image_generation_animagine_xl.py +162 -0
- intentkit/skills/heurist/image_generation_arthemy_comics.py +162 -0
- intentkit/skills/heurist/image_generation_arthemy_real.py +162 -0
- intentkit/skills/heurist/image_generation_braindance.py +162 -0
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +162 -0
- intentkit/skills/heurist/image_generation_flux_1_dev.py +162 -0
- intentkit/skills/heurist/image_generation_sdxl.py +161 -0
- intentkit/skills/heurist/schema.json +196 -0
- intentkit/skills/lifi/README.md +294 -0
- intentkit/skills/lifi/__init__.py +141 -0
- intentkit/skills/lifi/base.py +21 -0
- intentkit/skills/lifi/lifi.png +0 -0
- intentkit/skills/lifi/schema.json +89 -0
- intentkit/skills/lifi/token_execute.py +472 -0
- intentkit/skills/lifi/token_quote.py +190 -0
- intentkit/skills/lifi/utils.py +656 -0
- intentkit/skills/moralis/README.md +490 -0
- intentkit/skills/moralis/__init__.py +110 -0
- intentkit/skills/moralis/api.py +281 -0
- intentkit/skills/moralis/base.py +55 -0
- intentkit/skills/moralis/fetch_chain_portfolio.py +191 -0
- intentkit/skills/moralis/fetch_nft_portfolio.py +284 -0
- intentkit/skills/moralis/fetch_solana_portfolio.py +331 -0
- intentkit/skills/moralis/fetch_wallet_portfolio.py +301 -0
- intentkit/skills/moralis/moralis.png +0 -0
- intentkit/skills/moralis/schema.json +156 -0
- intentkit/skills/moralis/tests/__init__.py +0 -0
- intentkit/skills/moralis/tests/test_wallet.py +511 -0
- intentkit/skills/nation/__init__.py +62 -0
- intentkit/skills/nation/base.py +31 -0
- intentkit/skills/nation/nation.png +0 -0
- intentkit/skills/nation/nft_check.py +106 -0
- intentkit/skills/nation/schema.json +58 -0
- intentkit/skills/openai/__init__.py +107 -0
- intentkit/skills/openai/base.py +32 -0
- intentkit/skills/openai/dalle_image_generation.py +128 -0
- intentkit/skills/openai/gpt_image_generation.py +152 -0
- intentkit/skills/openai/gpt_image_to_image.py +186 -0
- intentkit/skills/openai/image_to_text.py +126 -0
- intentkit/skills/openai/openai.png +0 -0
- intentkit/skills/openai/schema.json +139 -0
- intentkit/skills/portfolio/README.md +55 -0
- intentkit/skills/portfolio/__init__.py +151 -0
- intentkit/skills/portfolio/base.py +107 -0
- intentkit/skills/portfolio/constants.py +9 -0
- intentkit/skills/portfolio/moralis.png +0 -0
- intentkit/skills/portfolio/schema.json +237 -0
- intentkit/skills/portfolio/token_balances.py +155 -0
- intentkit/skills/portfolio/wallet_approvals.py +102 -0
- intentkit/skills/portfolio/wallet_defi_positions.py +80 -0
- intentkit/skills/portfolio/wallet_history.py +155 -0
- intentkit/skills/portfolio/wallet_net_worth.py +112 -0
- intentkit/skills/portfolio/wallet_nfts.py +139 -0
- intentkit/skills/portfolio/wallet_profitability.py +101 -0
- intentkit/skills/portfolio/wallet_profitability_summary.py +91 -0
- intentkit/skills/portfolio/wallet_stats.py +79 -0
- intentkit/skills/portfolio/wallet_swaps.py +147 -0
- intentkit/skills/skills.toml +103 -0
- intentkit/skills/slack/__init__.py +98 -0
- intentkit/skills/slack/base.py +55 -0
- intentkit/skills/slack/get_channel.py +109 -0
- intentkit/skills/slack/get_message.py +136 -0
- intentkit/skills/slack/schedule_message.py +92 -0
- intentkit/skills/slack/schema.json +135 -0
- intentkit/skills/slack/send_message.py +81 -0
- intentkit/skills/slack/slack.jpg +0 -0
- intentkit/skills/system/__init__.py +90 -0
- intentkit/skills/system/base.py +22 -0
- intentkit/skills/system/read_agent_api_key.py +87 -0
- intentkit/skills/system/regenerate_agent_api_key.py +77 -0
- intentkit/skills/system/schema.json +53 -0
- intentkit/skills/system/system.svg +76 -0
- intentkit/skills/tavily/README.md +86 -0
- intentkit/skills/tavily/__init__.py +91 -0
- intentkit/skills/tavily/base.py +27 -0
- intentkit/skills/tavily/schema.json +119 -0
- intentkit/skills/tavily/tavily.jpg +0 -0
- intentkit/skills/tavily/tavily_extract.py +147 -0
- intentkit/skills/tavily/tavily_search.py +139 -0
- intentkit/skills/token/README.md +89 -0
- intentkit/skills/token/__init__.py +107 -0
- intentkit/skills/token/base.py +154 -0
- intentkit/skills/token/constants.py +9 -0
- intentkit/skills/token/erc20_transfers.py +145 -0
- intentkit/skills/token/moralis.png +0 -0
- intentkit/skills/token/schema.json +141 -0
- intentkit/skills/token/token_analytics.py +81 -0
- intentkit/skills/token/token_price.py +132 -0
- intentkit/skills/token/token_search.py +121 -0
- intentkit/skills/twitter/__init__.py +146 -0
- intentkit/skills/twitter/base.py +68 -0
- intentkit/skills/twitter/follow_user.py +69 -0
- intentkit/skills/twitter/get_mentions.py +124 -0
- intentkit/skills/twitter/get_timeline.py +111 -0
- intentkit/skills/twitter/get_user_by_username.py +84 -0
- intentkit/skills/twitter/get_user_tweets.py +123 -0
- intentkit/skills/twitter/like_tweet.py +65 -0
- intentkit/skills/twitter/post_tweet.py +90 -0
- intentkit/skills/twitter/reply_tweet.py +98 -0
- intentkit/skills/twitter/retweet.py +76 -0
- intentkit/skills/twitter/schema.json +258 -0
- intentkit/skills/twitter/search_tweets.py +115 -0
- intentkit/skills/twitter/twitter.png +0 -0
- intentkit/skills/unrealspeech/__init__.py +55 -0
- intentkit/skills/unrealspeech/base.py +21 -0
- intentkit/skills/unrealspeech/schema.json +100 -0
- intentkit/skills/unrealspeech/text_to_speech.py +177 -0
- intentkit/skills/unrealspeech/unrealspeech.jpg +0 -0
- intentkit/skills/venice_audio/__init__.py +106 -0
- intentkit/skills/venice_audio/base.py +119 -0
- intentkit/skills/venice_audio/input.py +41 -0
- intentkit/skills/venice_audio/schema.json +152 -0
- intentkit/skills/venice_audio/venice_audio.py +240 -0
- intentkit/skills/venice_audio/venice_logo.jpg +0 -0
- intentkit/skills/venice_image/README.md +119 -0
- intentkit/skills/venice_image/__init__.py +154 -0
- intentkit/skills/venice_image/api.py +138 -0
- intentkit/skills/venice_image/base.py +188 -0
- intentkit/skills/venice_image/config.py +35 -0
- intentkit/skills/venice_image/image_enhance/README.md +119 -0
- intentkit/skills/venice_image/image_enhance/__init__.py +0 -0
- intentkit/skills/venice_image/image_enhance/image_enhance.py +80 -0
- intentkit/skills/venice_image/image_enhance/image_enhance_base.py +23 -0
- intentkit/skills/venice_image/image_enhance/image_enhance_input.py +40 -0
- intentkit/skills/venice_image/image_generation/README.md +144 -0
- intentkit/skills/venice_image/image_generation/__init__.py +0 -0
- intentkit/skills/venice_image/image_generation/image_generation_base.py +117 -0
- intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -0
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -0
- intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -0
- intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -0
- intentkit/skills/venice_image/image_upscale/README.md +111 -0
- intentkit/skills/venice_image/image_upscale/__init__.py +0 -0
- intentkit/skills/venice_image/image_upscale/image_upscale.py +90 -0
- intentkit/skills/venice_image/image_upscale/image_upscale_base.py +23 -0
- intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -0
- intentkit/skills/venice_image/image_vision/README.md +112 -0
- intentkit/skills/venice_image/image_vision/__init__.py +0 -0
- intentkit/skills/venice_image/image_vision/image_vision.py +100 -0
- intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -0
- intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -0
- intentkit/skills/venice_image/schema.json +267 -0
- intentkit/skills/venice_image/utils.py +78 -0
- intentkit/skills/venice_image/venice_image.jpg +0 -0
- intentkit/skills/web_scraper/README.md +82 -0
- intentkit/skills/web_scraper/__init__.py +92 -0
- intentkit/skills/web_scraper/base.py +21 -0
- intentkit/skills/web_scraper/langchain.png +0 -0
- intentkit/skills/web_scraper/schema.json +115 -0
- intentkit/skills/web_scraper/scrape_and_index.py +327 -0
- intentkit/utils/__init__.py +1 -0
- intentkit/utils/chain.py +436 -0
- intentkit/utils/error.py +134 -0
- intentkit/utils/logging.py +70 -0
- intentkit/utils/middleware.py +61 -0
- intentkit/utils/random.py +16 -0
- intentkit/utils/s3.py +267 -0
- intentkit/utils/slack_alert.py +79 -0
- intentkit/utils/tx.py +37 -0
- {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/METADATA +1 -1
- intentkit-0.5.2.dist-info/RECORD +365 -0
- intentkit-0.5.0.dist-info/RECORD +0 -4
- {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/WHEEL +0 -0
- {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any, Dict, List, Optional, Type
|
|
3
|
+
|
|
4
|
+
from langchain_core.runnables import RunnableConfig
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
from intentkit.skills.portfolio.base import PortfolioBaseTool
|
|
8
|
+
from intentkit.skills.portfolio.constants import (
|
|
9
|
+
DEFAULT_CHAIN,
|
|
10
|
+
DEFAULT_LIMIT,
|
|
11
|
+
DEFAULT_ORDER,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class WalletSwapsInput(BaseModel):
|
|
18
|
+
"""Input for wallet swaps tool."""
|
|
19
|
+
|
|
20
|
+
address: str = Field(description="The wallet address to get swap transactions for.")
|
|
21
|
+
chain: str = Field(
|
|
22
|
+
description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
|
|
23
|
+
default=DEFAULT_CHAIN,
|
|
24
|
+
)
|
|
25
|
+
cursor: Optional[str] = Field(
|
|
26
|
+
description="The cursor for pagination.",
|
|
27
|
+
default=None,
|
|
28
|
+
)
|
|
29
|
+
limit: Optional[int] = Field(
|
|
30
|
+
description="The number of results per page.",
|
|
31
|
+
default=DEFAULT_LIMIT,
|
|
32
|
+
)
|
|
33
|
+
from_block: Optional[str] = Field(
|
|
34
|
+
description="The minimum block number to get transactions from.",
|
|
35
|
+
default=None,
|
|
36
|
+
)
|
|
37
|
+
to_block: Optional[str] = Field(
|
|
38
|
+
description="The maximum block number to get transactions from.",
|
|
39
|
+
default=None,
|
|
40
|
+
)
|
|
41
|
+
from_date: Optional[str] = Field(
|
|
42
|
+
description="The start date to get transactions from (format in seconds or datestring).",
|
|
43
|
+
default=None,
|
|
44
|
+
)
|
|
45
|
+
to_date: Optional[str] = Field(
|
|
46
|
+
description="The end date to get transactions from (format in seconds or datestring).",
|
|
47
|
+
default=None,
|
|
48
|
+
)
|
|
49
|
+
order: Optional[str] = Field(
|
|
50
|
+
description="The order of the result (ASC or DESC).",
|
|
51
|
+
default=DEFAULT_ORDER,
|
|
52
|
+
)
|
|
53
|
+
transaction_types: Optional[List[str]] = Field(
|
|
54
|
+
description="Array of transaction types. Allowed values are 'buy', 'sell'.",
|
|
55
|
+
default=None,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class WalletSwaps(PortfolioBaseTool):
|
|
60
|
+
"""Tool for retrieving swap-related transactions for a wallet using Moralis.
|
|
61
|
+
|
|
62
|
+
This tool uses Moralis' API to fetch all swap-related (buy, sell) transactions
|
|
63
|
+
for a specific wallet address.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
name: str = "portfolio_wallet_swaps"
|
|
67
|
+
description: str = (
|
|
68
|
+
"Get all swap-related transactions (buy, sell) for a wallet address. "
|
|
69
|
+
"Note that swaps data is only available from September 2024 onwards."
|
|
70
|
+
)
|
|
71
|
+
args_schema: Type[BaseModel] = WalletSwapsInput
|
|
72
|
+
|
|
73
|
+
async def _arun(
|
|
74
|
+
self,
|
|
75
|
+
address: str,
|
|
76
|
+
chain: str = DEFAULT_CHAIN,
|
|
77
|
+
cursor: Optional[str] = None,
|
|
78
|
+
limit: Optional[int] = DEFAULT_LIMIT,
|
|
79
|
+
from_block: Optional[str] = None,
|
|
80
|
+
to_block: Optional[str] = None,
|
|
81
|
+
from_date: Optional[str] = None,
|
|
82
|
+
to_date: Optional[str] = None,
|
|
83
|
+
order: Optional[str] = DEFAULT_ORDER,
|
|
84
|
+
transaction_types: Optional[List[str]] = None,
|
|
85
|
+
config: RunnableConfig = None,
|
|
86
|
+
**kwargs,
|
|
87
|
+
) -> Dict[str, Any]:
|
|
88
|
+
"""Fetch wallet swap transactions from Moralis.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
address: The wallet address to get swaps for
|
|
92
|
+
chain: The blockchain to query
|
|
93
|
+
cursor: Pagination cursor
|
|
94
|
+
limit: Number of results per page
|
|
95
|
+
from_block: Minimum block number for transactions
|
|
96
|
+
to_block: Maximum block number for transactions
|
|
97
|
+
from_date: Start date for transactions
|
|
98
|
+
to_date: End date for transactions
|
|
99
|
+
order: Order of results (ASC/DESC)
|
|
100
|
+
transaction_types: Types of transactions to include ('buy', 'sell')
|
|
101
|
+
config: The configuration for the tool call
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Dict containing wallet swaps data
|
|
105
|
+
"""
|
|
106
|
+
context = self.context_from_config(config)
|
|
107
|
+
logger.debug(f"wallet_swaps.py: Fetching wallet swaps with context {context}")
|
|
108
|
+
|
|
109
|
+
# Get the API key from the agent's configuration
|
|
110
|
+
api_key = self.get_api_key(context)
|
|
111
|
+
if not api_key:
|
|
112
|
+
return {"error": "No Moralis API key provided in the configuration."}
|
|
113
|
+
|
|
114
|
+
# Build query parameters
|
|
115
|
+
params = {
|
|
116
|
+
"chain": chain,
|
|
117
|
+
"limit": limit,
|
|
118
|
+
"order": order,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# Add optional parameters if they exist
|
|
122
|
+
if cursor:
|
|
123
|
+
params["cursor"] = cursor
|
|
124
|
+
if from_block:
|
|
125
|
+
params["fromBlock"] = from_block
|
|
126
|
+
if to_block:
|
|
127
|
+
params["toBlock"] = to_block
|
|
128
|
+
if from_date:
|
|
129
|
+
params["fromDate"] = from_date
|
|
130
|
+
if to_date:
|
|
131
|
+
params["toDate"] = to_date
|
|
132
|
+
if transaction_types:
|
|
133
|
+
params["transactionTypes"] = transaction_types
|
|
134
|
+
|
|
135
|
+
# Call Moralis API
|
|
136
|
+
try:
|
|
137
|
+
endpoint = f"/wallets/{address}/swaps"
|
|
138
|
+
return await self._make_request(
|
|
139
|
+
method="GET", endpoint=endpoint, api_key=api_key, params=params
|
|
140
|
+
)
|
|
141
|
+
except Exception as e:
|
|
142
|
+
logger.error(
|
|
143
|
+
f"wallet_swaps.py: Error fetching wallet swaps: {e}", exc_info=True
|
|
144
|
+
)
|
|
145
|
+
return {
|
|
146
|
+
"error": "An error occurred while fetching wallet swaps. Please try again later."
|
|
147
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
[acolyt]
|
|
2
|
+
author_github = "TxCorpi0x"
|
|
3
|
+
author_wallet = "0x2Bd32A312280bF5A01140e68ca630fB76cE8A3De"
|
|
4
|
+
|
|
5
|
+
[aixbt]
|
|
6
|
+
author_github = "bluntbrain"
|
|
7
|
+
author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
|
|
8
|
+
|
|
9
|
+
[allora]
|
|
10
|
+
author_github = "TxCorpi0x"
|
|
11
|
+
author_wallet = "0x2Bd32A312280bF5A01140e68ca630fB76cE8A3De"
|
|
12
|
+
|
|
13
|
+
[cdp]
|
|
14
|
+
author_github = "hyacinthus"
|
|
15
|
+
author_wallet = "0x445750026A4a1906b61302442E085f9cbAfe206a"
|
|
16
|
+
|
|
17
|
+
[chainlist]
|
|
18
|
+
author_github = "bluntbrain"
|
|
19
|
+
author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
|
|
20
|
+
|
|
21
|
+
[common]
|
|
22
|
+
author_github = "hyacinthus"
|
|
23
|
+
author_wallet = "0x445750026A4a1906b61302442E085f9cbAfe206a"
|
|
24
|
+
|
|
25
|
+
[cryptocompare]
|
|
26
|
+
author_github = "0xkieranwilliams"
|
|
27
|
+
author_wallet = "0x91D43BfDc698b1e510efa0811e2e07F628D02e6b"
|
|
28
|
+
|
|
29
|
+
[cryptopanic]
|
|
30
|
+
author_github = "v1ktorrr0x"
|
|
31
|
+
author_wallet = "0x178741Fc5BA9B77147398853c28736eEFe5fCff1"
|
|
32
|
+
|
|
33
|
+
[dapplooker]
|
|
34
|
+
author_github = "bluntbrain"
|
|
35
|
+
author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
|
|
36
|
+
|
|
37
|
+
[defillama]
|
|
38
|
+
author_github = "0xkieranwilliams"
|
|
39
|
+
author_wallet = "0x91D43BfDc698b1e510efa0811e2e07F628D02e6b"
|
|
40
|
+
|
|
41
|
+
[elfa]
|
|
42
|
+
author_github = "TxCorpi0x"
|
|
43
|
+
author_wallet = "0x2Bd32A312280bF5A01140e68ca630fB76cE8A3De"
|
|
44
|
+
|
|
45
|
+
[enso]
|
|
46
|
+
author_github = "TxCorpi0x"
|
|
47
|
+
author_wallet = "0x2Bd32A312280bF5A01140e68ca630fB76cE8A3De"
|
|
48
|
+
|
|
49
|
+
[github]
|
|
50
|
+
author_github = "bluntbrain"
|
|
51
|
+
author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
|
|
52
|
+
|
|
53
|
+
[goat]
|
|
54
|
+
author_github = "TxCorpi0x"
|
|
55
|
+
author_wallet = "0x2Bd32A312280bF5A01140e68ca630fB76cE8A3De"
|
|
56
|
+
|
|
57
|
+
[heurist]
|
|
58
|
+
author_github = "hyacinthus"
|
|
59
|
+
author_wallet = "0x445750026A4a1906b61302442E085f9cbAfe206a"
|
|
60
|
+
|
|
61
|
+
[moralis]
|
|
62
|
+
author_github = "developerfred"
|
|
63
|
+
author_wallet = "0xd1a8Dd23e356B9fAE27dF5DeF9ea025A602EC81e"
|
|
64
|
+
|
|
65
|
+
[nation]
|
|
66
|
+
author_github = "spidemen"
|
|
67
|
+
author_wallet = "0x275960ad41DbE218bBf72cDF612F88b5C6f40648"
|
|
68
|
+
|
|
69
|
+
[openai]
|
|
70
|
+
author_github = "hyacinthus"
|
|
71
|
+
author_wallet = "0x445750026A4a1906b61302442E085f9cbAfe206a"
|
|
72
|
+
|
|
73
|
+
[slack]
|
|
74
|
+
author_github = "hyacinthus"
|
|
75
|
+
author_wallet = "0x445750026A4a1906b61302442E085f9cbAfe206a"
|
|
76
|
+
|
|
77
|
+
[system]
|
|
78
|
+
author_github = "hyacinthus"
|
|
79
|
+
author_wallet = "0x445750026A4a1906b61302442E085f9cbAfe206a"
|
|
80
|
+
|
|
81
|
+
[tavily]
|
|
82
|
+
author_github = "bluntbrain"
|
|
83
|
+
author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
|
|
84
|
+
|
|
85
|
+
[twitter]
|
|
86
|
+
author_github = "hyacinthus"
|
|
87
|
+
author_wallet = "0x445750026A4a1906b61302442E085f9cbAfe206a"
|
|
88
|
+
|
|
89
|
+
[unrealspeech]
|
|
90
|
+
author_github = "bluntbrain"
|
|
91
|
+
author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
|
|
92
|
+
|
|
93
|
+
[venice_image]
|
|
94
|
+
author_github = "yornfifty"
|
|
95
|
+
author_wallet = "0xF60D4B6780D5D51827602D7aC319458bc9e921F4"
|
|
96
|
+
|
|
97
|
+
[portfolio]
|
|
98
|
+
author_github = "bluntbrain"
|
|
99
|
+
author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
|
|
100
|
+
|
|
101
|
+
[token]
|
|
102
|
+
author_github = "bluntbrain"
|
|
103
|
+
author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""Slack skills."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from typing import TypedDict
|
|
5
|
+
|
|
6
|
+
from intentkit.abstracts.skill import SkillStoreABC
|
|
7
|
+
from intentkit.skills.base import SkillConfig, SkillState
|
|
8
|
+
from intentkit.skills.slack.base import SlackBaseTool
|
|
9
|
+
from intentkit.skills.slack.get_channel import SlackGetChannel
|
|
10
|
+
from intentkit.skills.slack.get_message import SlackGetMessage
|
|
11
|
+
from intentkit.skills.slack.schedule_message import SlackScheduleMessage
|
|
12
|
+
from intentkit.skills.slack.send_message import SlackSendMessage
|
|
13
|
+
|
|
14
|
+
# we cache skills in system level, because they are stateless
|
|
15
|
+
_cache: dict[str, SlackBaseTool] = {}
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SkillStates(TypedDict):
|
|
21
|
+
get_channel: SkillState
|
|
22
|
+
get_message: SkillState
|
|
23
|
+
schedule_message: SkillState
|
|
24
|
+
send_message: SkillState
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Config(SkillConfig):
|
|
28
|
+
"""Configuration for Slack skills."""
|
|
29
|
+
|
|
30
|
+
states: SkillStates
|
|
31
|
+
slack_bot_token: str
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
async def get_skills(
|
|
35
|
+
config: "Config",
|
|
36
|
+
is_private: bool,
|
|
37
|
+
store: SkillStoreABC,
|
|
38
|
+
**_,
|
|
39
|
+
) -> list[SlackBaseTool]:
|
|
40
|
+
"""Get all Slack skills."""
|
|
41
|
+
available_skills = []
|
|
42
|
+
|
|
43
|
+
# Include skills based on their state
|
|
44
|
+
for skill_name, state in config["states"].items():
|
|
45
|
+
if state == "disabled":
|
|
46
|
+
continue
|
|
47
|
+
elif state == "public" or (state == "private" and is_private):
|
|
48
|
+
available_skills.append(skill_name)
|
|
49
|
+
|
|
50
|
+
# Get each skill using the cached getter
|
|
51
|
+
result = []
|
|
52
|
+
for name in available_skills:
|
|
53
|
+
skill = get_slack_skill(name, store)
|
|
54
|
+
if skill:
|
|
55
|
+
result.append(skill)
|
|
56
|
+
return result
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_slack_skill(
|
|
60
|
+
name: str,
|
|
61
|
+
store: SkillStoreABC,
|
|
62
|
+
) -> SlackBaseTool:
|
|
63
|
+
"""Get a Slack skill by name.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
name: The name of the skill to get
|
|
67
|
+
store: The skill store for persisting data
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
The requested Slack skill
|
|
71
|
+
"""
|
|
72
|
+
if name == "get_channel":
|
|
73
|
+
if name not in _cache:
|
|
74
|
+
_cache[name] = SlackGetChannel(
|
|
75
|
+
skill_store=store,
|
|
76
|
+
)
|
|
77
|
+
return _cache[name]
|
|
78
|
+
elif name == "get_message":
|
|
79
|
+
if name not in _cache:
|
|
80
|
+
_cache[name] = SlackGetMessage(
|
|
81
|
+
skill_store=store,
|
|
82
|
+
)
|
|
83
|
+
return _cache[name]
|
|
84
|
+
elif name == "schedule_message":
|
|
85
|
+
if name not in _cache:
|
|
86
|
+
_cache[name] = SlackScheduleMessage(
|
|
87
|
+
skill_store=store,
|
|
88
|
+
)
|
|
89
|
+
return _cache[name]
|
|
90
|
+
elif name == "send_message":
|
|
91
|
+
if name not in _cache:
|
|
92
|
+
_cache[name] = SlackSendMessage(
|
|
93
|
+
skill_store=store,
|
|
94
|
+
)
|
|
95
|
+
return _cache[name]
|
|
96
|
+
else:
|
|
97
|
+
logger.warning(f"Unknown Slack skill: {name}")
|
|
98
|
+
return None
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from typing import Optional, Type
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
from slack_sdk import WebClient
|
|
5
|
+
|
|
6
|
+
from intentkit.abstracts.skill import SkillStoreABC
|
|
7
|
+
from intentkit.skills.base import IntentKitSkill
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SlackBaseTool(IntentKitSkill):
|
|
11
|
+
"""Base class for Slack tools."""
|
|
12
|
+
|
|
13
|
+
name: str = Field(description="The name of the tool")
|
|
14
|
+
description: str = Field(description="A description of what the tool does")
|
|
15
|
+
args_schema: Type[BaseModel]
|
|
16
|
+
skill_store: SkillStoreABC = Field(
|
|
17
|
+
description="The skill store for persisting data"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def category(self) -> str:
|
|
22
|
+
return "slack"
|
|
23
|
+
|
|
24
|
+
def get_client(self, token: str) -> WebClient:
|
|
25
|
+
"""Get a Slack WebClient instance.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
token: The Slack bot token to use
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
WebClient: A configured Slack client
|
|
32
|
+
"""
|
|
33
|
+
return WebClient(token=token)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SlackChannel(BaseModel):
|
|
37
|
+
"""Model representing a Slack channel."""
|
|
38
|
+
|
|
39
|
+
id: str
|
|
40
|
+
name: str
|
|
41
|
+
is_private: bool
|
|
42
|
+
created: int
|
|
43
|
+
creator: str
|
|
44
|
+
is_archived: bool
|
|
45
|
+
members: list[str] = []
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class SlackMessage(BaseModel):
|
|
49
|
+
"""Model representing a Slack message."""
|
|
50
|
+
|
|
51
|
+
ts: str
|
|
52
|
+
text: str
|
|
53
|
+
user: str
|
|
54
|
+
channel: str
|
|
55
|
+
thread_ts: Optional[str] = None
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional, Type, Union
|
|
2
|
+
|
|
3
|
+
from langchain_core.runnables import RunnableConfig
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
from intentkit.skills.slack.base import SlackBaseTool, SlackChannel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SlackGetChannelSchema(BaseModel):
|
|
10
|
+
"""Input schema for SlackGetChannel."""
|
|
11
|
+
|
|
12
|
+
channel_id: Optional[str] = Field(
|
|
13
|
+
None,
|
|
14
|
+
description="The ID of the channel to get information about. Provide either channel_id or channel_name.",
|
|
15
|
+
)
|
|
16
|
+
channel_name: Optional[str] = Field(
|
|
17
|
+
None,
|
|
18
|
+
description="The name of the channel to get information about. Provide either channel_id or channel_name.",
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class SlackGetChannel(SlackBaseTool):
|
|
23
|
+
"""Tool for getting information about a Slack channel."""
|
|
24
|
+
|
|
25
|
+
name: str = "slack_get_channel"
|
|
26
|
+
description: str = "Get information about a Slack channel by ID or name"
|
|
27
|
+
args_schema: Type[BaseModel] = SlackGetChannelSchema
|
|
28
|
+
|
|
29
|
+
async def _arun(
|
|
30
|
+
self,
|
|
31
|
+
config: RunnableConfig,
|
|
32
|
+
channel_id: Optional[str] = None,
|
|
33
|
+
channel_name: Optional[str] = None,
|
|
34
|
+
**kwargs,
|
|
35
|
+
) -> Union[SlackChannel, Dict[str, SlackChannel]]:
|
|
36
|
+
"""Run the tool to get information about a Slack channel.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
channel_id: The ID of the channel to get information about
|
|
40
|
+
channel_name: The name of the channel to get information about
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Information about the requested channel or all channels if no ID/name provided
|
|
44
|
+
|
|
45
|
+
Raises:
|
|
46
|
+
ValueError: If neither channel_id nor channel_name is provided
|
|
47
|
+
Exception: If an error occurs getting the channel information
|
|
48
|
+
"""
|
|
49
|
+
context = self.context_from_config(config)
|
|
50
|
+
client = self.get_client(context.config.get("slack_bot_token"))
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
# If no channel specified, return a dict of all channels
|
|
54
|
+
if not channel_id and not channel_name:
|
|
55
|
+
# Get all channels
|
|
56
|
+
response = client.conversations_list()
|
|
57
|
+
if response["ok"]:
|
|
58
|
+
channels = {}
|
|
59
|
+
for channel in response["channels"]:
|
|
60
|
+
channels[channel["id"]] = self._format_channel(channel)
|
|
61
|
+
return channels
|
|
62
|
+
else:
|
|
63
|
+
raise Exception(f"Error getting channels: {response['error']}")
|
|
64
|
+
|
|
65
|
+
# First try to find by channel_id if provided
|
|
66
|
+
if channel_id:
|
|
67
|
+
response = client.conversations_info(channel=channel_id)
|
|
68
|
+
if response["ok"]:
|
|
69
|
+
return self._format_channel(response["channel"])
|
|
70
|
+
else:
|
|
71
|
+
raise Exception(f"Error getting channel: {response['error']}")
|
|
72
|
+
|
|
73
|
+
# Otherwise try to find by channel_name
|
|
74
|
+
if channel_name:
|
|
75
|
+
# If channel name doesn't start with #, add it
|
|
76
|
+
if not channel_name.startswith("#"):
|
|
77
|
+
channel_name = f"#{channel_name}"
|
|
78
|
+
|
|
79
|
+
# Get all channels and filter by name
|
|
80
|
+
response = client.conversations_list()
|
|
81
|
+
if response["ok"]:
|
|
82
|
+
for channel in response["channels"]:
|
|
83
|
+
if channel["name"] == channel_name.lstrip("#"):
|
|
84
|
+
return self._format_channel(channel)
|
|
85
|
+
raise ValueError(f"Channel {channel_name} not found")
|
|
86
|
+
else:
|
|
87
|
+
raise Exception(f"Error getting channels: {response['error']}")
|
|
88
|
+
|
|
89
|
+
except Exception as e:
|
|
90
|
+
raise Exception(f"Error getting channel information: {str(e)}")
|
|
91
|
+
|
|
92
|
+
def _format_channel(self, channel: Dict[str, Any]) -> SlackChannel:
|
|
93
|
+
"""Format the channel data into a SlackChannel model.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
channel: The raw channel data from the Slack API
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
A formatted SlackChannel object
|
|
100
|
+
"""
|
|
101
|
+
return SlackChannel(
|
|
102
|
+
id=channel["id"],
|
|
103
|
+
name=channel["name"],
|
|
104
|
+
is_private=channel.get("is_private", False),
|
|
105
|
+
created=channel.get("created", 0),
|
|
106
|
+
creator=channel.get("creator", ""),
|
|
107
|
+
is_archived=channel.get("is_archived", False),
|
|
108
|
+
members=channel.get("members", []),
|
|
109
|
+
)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional, Type
|
|
2
|
+
|
|
3
|
+
from langchain_core.runnables import RunnableConfig
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
from intentkit.skills.slack.base import SlackBaseTool, SlackMessage
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SlackGetMessageSchema(BaseModel):
|
|
10
|
+
"""Input schema for SlackGetMessage."""
|
|
11
|
+
|
|
12
|
+
channel_id: str = Field(
|
|
13
|
+
description="The ID of the channel containing the message",
|
|
14
|
+
)
|
|
15
|
+
ts: Optional[str] = Field(
|
|
16
|
+
None,
|
|
17
|
+
description="The timestamp of a specific message to retrieve. If not provided, returns recent messages.",
|
|
18
|
+
)
|
|
19
|
+
thread_ts: Optional[str] = Field(
|
|
20
|
+
None,
|
|
21
|
+
description="If provided, retrieve messages from this thread instead of the channel.",
|
|
22
|
+
)
|
|
23
|
+
limit: Optional[int] = Field(
|
|
24
|
+
10,
|
|
25
|
+
description="The maximum number of messages to return (1-100, default 10).",
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class SlackGetMessage(SlackBaseTool):
|
|
30
|
+
"""Tool for getting messages from a Slack channel or thread."""
|
|
31
|
+
|
|
32
|
+
name: str = "slack_get_message"
|
|
33
|
+
description: str = "Get messages from a Slack channel or thread"
|
|
34
|
+
args_schema: Type[BaseModel] = SlackGetMessageSchema
|
|
35
|
+
|
|
36
|
+
async def _arun(
|
|
37
|
+
self,
|
|
38
|
+
config: RunnableConfig,
|
|
39
|
+
channel_id: str,
|
|
40
|
+
ts: Optional[str] = None,
|
|
41
|
+
thread_ts: Optional[str] = None,
|
|
42
|
+
limit: int = 10,
|
|
43
|
+
**kwargs,
|
|
44
|
+
) -> Dict[str, Any]:
|
|
45
|
+
"""Run the tool to get Slack messages.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
channel_id: The ID of the channel to get messages from
|
|
49
|
+
ts: The timestamp of a specific message to retrieve
|
|
50
|
+
thread_ts: If provided, retrieve messages from this thread
|
|
51
|
+
limit: Maximum number of messages to return (1-100)
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
A dictionary containing the requested messages
|
|
55
|
+
|
|
56
|
+
Raises:
|
|
57
|
+
Exception: If an error occurs getting the messages
|
|
58
|
+
"""
|
|
59
|
+
context = self.context_from_config(config)
|
|
60
|
+
client = self.get_client(context.config.get("slack_bot_token"))
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
# Ensure limit is within bounds
|
|
64
|
+
if limit < 1:
|
|
65
|
+
limit = 1
|
|
66
|
+
elif limit > 100:
|
|
67
|
+
limit = 100
|
|
68
|
+
|
|
69
|
+
# Get a specific message by timestamp
|
|
70
|
+
if ts and not thread_ts:
|
|
71
|
+
response = client.conversations_history(
|
|
72
|
+
channel=channel_id, latest=ts, limit=1, inclusive=True
|
|
73
|
+
)
|
|
74
|
+
if response["ok"] and response["messages"]:
|
|
75
|
+
return {
|
|
76
|
+
"messages": [
|
|
77
|
+
self._format_message(response["messages"][0], channel_id)
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
else:
|
|
81
|
+
raise Exception(f"Message with timestamp {ts} not found")
|
|
82
|
+
|
|
83
|
+
# Get messages from a thread
|
|
84
|
+
elif thread_ts:
|
|
85
|
+
response = client.conversations_replies(
|
|
86
|
+
channel=channel_id, ts=thread_ts, limit=limit
|
|
87
|
+
)
|
|
88
|
+
if response["ok"]:
|
|
89
|
+
return {
|
|
90
|
+
"messages": [
|
|
91
|
+
self._format_message(msg, channel_id)
|
|
92
|
+
for msg in response["messages"]
|
|
93
|
+
],
|
|
94
|
+
"has_more": response.get("has_more", False),
|
|
95
|
+
}
|
|
96
|
+
else:
|
|
97
|
+
raise Exception(
|
|
98
|
+
f"Error getting thread messages: {response.get('error')}"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Get channel history
|
|
102
|
+
else:
|
|
103
|
+
response = client.conversations_history(channel=channel_id, limit=limit)
|
|
104
|
+
if response["ok"]:
|
|
105
|
+
return {
|
|
106
|
+
"messages": [
|
|
107
|
+
self._format_message(msg, channel_id)
|
|
108
|
+
for msg in response["messages"]
|
|
109
|
+
],
|
|
110
|
+
"has_more": response.get("has_more", False),
|
|
111
|
+
}
|
|
112
|
+
else:
|
|
113
|
+
raise Exception(
|
|
114
|
+
f"Error getting channel messages: {response.get('error')}"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
except Exception as e:
|
|
118
|
+
raise Exception(f"Error getting messages: {str(e)}")
|
|
119
|
+
|
|
120
|
+
def _format_message(self, message: Dict[str, Any], channel_id: str) -> SlackMessage:
|
|
121
|
+
"""Format the message data into a SlackMessage model.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
message: The raw message data from the Slack API
|
|
125
|
+
channel_id: The channel ID the message belongs to
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
A formatted SlackMessage object
|
|
129
|
+
"""
|
|
130
|
+
return SlackMessage(
|
|
131
|
+
ts=message["ts"],
|
|
132
|
+
text=message["text"],
|
|
133
|
+
user=message.get("user", ""),
|
|
134
|
+
channel=channel_id,
|
|
135
|
+
thread_ts=message.get("thread_ts"),
|
|
136
|
+
)
|