intentkit 0.8.6.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 +10 -5
- intentkit/abstracts/skill.py +6 -144
- intentkit/abstracts/twitter.py +4 -5
- intentkit/clients/__init__.py +3 -2
- intentkit/clients/cdp.py +53 -92
- intentkit/clients/twitter.py +56 -57
- intentkit/clients/web3.py +1 -3
- intentkit/config/config.py +5 -0
- intentkit/core/agent.py +16 -388
- intentkit/core/asset.py +64 -18
- intentkit/core/client.py +1 -1
- intentkit/core/credit.py +19 -20
- intentkit/core/engine.py +26 -11
- intentkit/core/node.py +2 -1
- intentkit/core/prompt.py +53 -15
- intentkit/core/scheduler.py +9 -9
- intentkit/core/statistics.py +6 -7
- intentkit/models/agent.py +256 -176
- intentkit/models/agent_data.py +62 -36
- intentkit/models/agent_schema.json +6 -9
- intentkit/models/app_setting.py +6 -6
- intentkit/models/chat.py +28 -24
- intentkit/models/conversation.py +8 -8
- intentkit/models/credit.py +62 -64
- intentkit/models/db.py +8 -7
- intentkit/models/db_mig.py +2 -2
- intentkit/models/llm.csv +15 -12
- intentkit/models/llm.py +18 -16
- intentkit/models/redis.py +2 -3
- intentkit/models/skill.py +62 -66
- intentkit/models/skills.csv +30 -26
- intentkit/models/user.py +46 -21
- intentkit/skills/acolyt/__init__.py +2 -9
- intentkit/skills/acolyt/ask.py +3 -4
- intentkit/skills/acolyt/base.py +4 -9
- intentkit/skills/aixbt/__init__.py +2 -13
- intentkit/skills/aixbt/base.py +1 -7
- intentkit/skills/aixbt/projects.py +14 -15
- intentkit/skills/allora/__init__.py +2 -9
- intentkit/skills/allora/base.py +4 -9
- intentkit/skills/allora/price.py +3 -4
- intentkit/skills/base.py +175 -52
- intentkit/skills/basename/__init__.py +4 -8
- 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/token_info_and_price.py +5 -5
- intentkit/skills/casino/__init__.py +4 -15
- intentkit/skills/casino/base.py +1 -7
- intentkit/skills/casino/deck_draw.py +5 -8
- intentkit/skills/casino/deck_shuffle.py +6 -6
- intentkit/skills/casino/dice_roll.py +2 -4
- intentkit/skills/cdp/__init__.py +3 -10
- intentkit/skills/cdp/base.py +1 -7
- intentkit/skills/cdp/schema.json +1 -17
- intentkit/skills/chainlist/__init__.py +2 -7
- intentkit/skills/chainlist/base.py +1 -7
- intentkit/skills/chainlist/chain_lookup.py +18 -18
- intentkit/skills/common/__init__.py +2 -9
- intentkit/skills/common/base.py +1 -7
- intentkit/skills/common/current_time.py +1 -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/search_accounts.py +9 -9
- intentkit/skills/cryptocompare/__init__.py +7 -24
- intentkit/skills/cryptocompare/api.py +2 -3
- intentkit/skills/cryptocompare/base.py +10 -24
- intentkit/skills/cryptocompare/fetch_news.py +4 -5
- intentkit/skills/cryptocompare/fetch_price.py +6 -7
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
- intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
- intentkit/skills/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/dapplooker/__init__.py +2 -9
- intentkit/skills/dapplooker/base.py +4 -9
- intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
- intentkit/skills/defillama/__init__.py +24 -74
- intentkit/skills/defillama/api.py +6 -9
- intentkit/skills/defillama/base.py +8 -19
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_block.py +6 -8
- intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
- intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
- intentkit/skills/defillama/config/chains.py +1 -3
- intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
- intentkit/skills/defillama/tests/api_integration.test.py +1 -1
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
- intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
- intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
- intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
- intentkit/skills/defillama/yields/fetch_pools.py +26 -30
- intentkit/skills/dexscreener/__init__.py +97 -102
- intentkit/skills/dexscreener/base.py +125 -130
- intentkit/skills/dexscreener/get_pair_info.py +4 -5
- intentkit/skills/dexscreener/get_token_pairs.py +4 -5
- intentkit/skills/dexscreener/get_tokens_info.py +7 -8
- intentkit/skills/dexscreener/model/search_token_response.py +80 -82
- intentkit/skills/dexscreener/search_token.py +182 -184
- intentkit/skills/dexscreener/utils.py +15 -14
- intentkit/skills/dune_analytics/__init__.py +7 -9
- intentkit/skills/dune_analytics/base.py +48 -52
- intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
- intentkit/skills/elfa/__init__.py +5 -18
- intentkit/skills/elfa/base.py +10 -14
- intentkit/skills/elfa/mention.py +19 -21
- 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 +9 -15
- intentkit/skills/enso/best_yield.py +5 -7
- intentkit/skills/enso/networks.py +3 -9
- intentkit/skills/enso/prices.py +2 -4
- intentkit/skills/enso/route.py +6 -12
- intentkit/skills/enso/tokens.py +4 -16
- intentkit/skills/enso/wallet.py +6 -6
- intentkit/skills/erc20/__init__.py +5 -11
- intentkit/skills/erc721/__init__.py +5 -9
- intentkit/skills/firecrawl/__init__.py +5 -18
- intentkit/skills/firecrawl/base.py +4 -9
- intentkit/skills/firecrawl/clear.py +4 -8
- intentkit/skills/firecrawl/crawl.py +19 -19
- intentkit/skills/firecrawl/query.py +4 -3
- intentkit/skills/firecrawl/scrape.py +17 -22
- intentkit/skills/firecrawl/utils.py +50 -42
- intentkit/skills/github/__init__.py +2 -7
- intentkit/skills/github/base.py +1 -7
- intentkit/skills/github/github_search.py +1 -2
- intentkit/skills/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/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/lifi/__init__.py +5 -10
- intentkit/skills/lifi/base.py +1 -7
- intentkit/skills/lifi/token_execute.py +14 -17
- intentkit/skills/lifi/token_quote.py +7 -9
- intentkit/skills/lifi/utils.py +16 -16
- 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/morpho/__init__.py +5 -9
- intentkit/skills/nation/__init__.py +4 -9
- intentkit/skills/nation/base.py +5 -10
- intentkit/skills/nation/nft_check.py +3 -4
- 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 +32 -0
- intentkit/skills/portfolio/__init__.py +11 -35
- intentkit/skills/portfolio/base.py +33 -19
- 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 +4 -10
- intentkit/skills/skills.toml +4 -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/send_message.py +3 -5
- intentkit/skills/supabase/__init__.py +7 -23
- intentkit/skills/supabase/base.py +1 -7
- intentkit/skills/supabase/delete_data.py +4 -4
- intentkit/skills/supabase/fetch_data.py +12 -12
- intentkit/skills/supabase/insert_data.py +4 -4
- intentkit/skills/supabase/invoke_function.py +6 -6
- intentkit/skills/supabase/update_data.py +6 -6
- intentkit/skills/supabase/upsert_data.py +4 -4
- intentkit/skills/superfluid/__init__.py +5 -9
- 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/tavily/__init__.py +3 -12
- intentkit/skills/tavily/base.py +4 -9
- 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/token_analytics.py +3 -3
- intentkit/skills/token/token_price.py +13 -13
- intentkit/skills/token/token_search.py +9 -9
- intentkit/skills/twitter/__init__.py +11 -35
- intentkit/skills/twitter/base.py +22 -34
- intentkit/skills/twitter/follow_user.py +2 -6
- intentkit/skills/twitter/get_mentions.py +5 -12
- intentkit/skills/twitter/get_timeline.py +4 -12
- intentkit/skills/twitter/get_user_by_username.py +2 -6
- intentkit/skills/twitter/get_user_tweets.py +5 -13
- intentkit/skills/twitter/like_tweet.py +2 -6
- intentkit/skills/twitter/post_tweet.py +6 -9
- intentkit/skills/twitter/reply_tweet.py +6 -9
- intentkit/skills/twitter/retweet.py +2 -6
- intentkit/skills/twitter/search_tweets.py +4 -12
- intentkit/skills/unrealspeech/__init__.py +2 -7
- intentkit/skills/unrealspeech/base.py +2 -8
- 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/venice_audio.py +7 -11
- 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/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/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 +5 -11
- intentkit/skills/wow/__init__.py +5 -11
- 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 +5 -5
- intentkit/skills/xmtp/price.py +6 -6
- intentkit/skills/xmtp/swap.py +6 -8
- intentkit/skills/xmtp/transfer.py +4 -6
- intentkit/utils/error.py +2 -2
- intentkit/utils/logging.py +2 -4
- intentkit/utils/s3.py +8 -9
- intentkit/utils/schema.py +100 -0
- intentkit/utils/slack_alert.py +7 -8
- {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +3 -4
- intentkit-0.8.17.dist-info/RECORD +466 -0
- intentkit/models/generator.py +0 -347
- intentkit-0.8.6.dev2.dist-info/RECORD +0 -457
- {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
- {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""DALL-E image generation skill for OpenAI."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import Type
|
|
5
4
|
|
|
6
5
|
import openai
|
|
7
6
|
from epyxid import XID
|
|
@@ -53,7 +52,7 @@ class DALLEImageGeneration(OpenAIBaseTool):
|
|
|
53
52
|
"high-quality images from text descriptions.\n"
|
|
54
53
|
"You can specify size, quality, and style parameters for more control.\n"
|
|
55
54
|
)
|
|
56
|
-
args_schema:
|
|
55
|
+
args_schema: type[BaseModel] = DALLEImageGenerationInput
|
|
57
56
|
|
|
58
57
|
async def _arun(
|
|
59
58
|
self,
|
|
@@ -71,7 +70,6 @@ class DALLEImageGeneration(OpenAIBaseTool):
|
|
|
71
70
|
quality: Quality of the generated image. Options: standard, hd
|
|
72
71
|
style: Style of the generated image. Options: vivid, natural
|
|
73
72
|
|
|
74
|
-
|
|
75
73
|
Returns:
|
|
76
74
|
str: URL of the generated image.
|
|
77
75
|
|
|
@@ -79,12 +77,9 @@ class DALLEImageGeneration(OpenAIBaseTool):
|
|
|
79
77
|
Exception: If the image generation fails.
|
|
80
78
|
"""
|
|
81
79
|
context = self.get_context()
|
|
82
|
-
skill_config = context.agent.skill_config(self.category)
|
|
83
80
|
|
|
84
|
-
# Get the OpenAI API key from
|
|
85
|
-
api_key =
|
|
86
|
-
"openai_api_key"
|
|
87
|
-
)
|
|
81
|
+
# Get the OpenAI API key from configuration or agent settings
|
|
82
|
+
api_key = self.get_api_key()
|
|
88
83
|
|
|
89
84
|
# Generate a unique job ID
|
|
90
85
|
job_id = str(XID())
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""GPT avatar generator skill for OpenAI."""
|
|
2
|
+
|
|
3
|
+
import base64
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
import openai
|
|
7
|
+
from epyxid import XID
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
from intentkit.skills.openai.base import OpenAIBaseTool
|
|
11
|
+
from intentkit.utils.s3 import store_image_bytes
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
AVATAR_PROMPT_PREFIX = (
|
|
16
|
+
"Create a single, centered portrait that works perfectly as a profile avatar. "
|
|
17
|
+
"Use flattering, even lighting, a simple soft-focus background, and a composition from shoulders up. "
|
|
18
|
+
"Avoid text, logos, watermarks, and distracting elements so the result feels polished and personable."
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class GPTAvatarGeneratorInput(BaseModel):
|
|
23
|
+
"""Input schema for the GPT avatar generator skill."""
|
|
24
|
+
|
|
25
|
+
prompt: str = Field(
|
|
26
|
+
description="Description of the avatar or profile image to generate.",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class GPTAvatarGenerator(OpenAIBaseTool):
|
|
31
|
+
"""Tool for generating avatar-friendly images using OpenAI's GPT-Image-1-Mini model."""
|
|
32
|
+
|
|
33
|
+
name: str = "gpt_avatar_generator"
|
|
34
|
+
description: str = (
|
|
35
|
+
"Generate avatar-ready profile images using OpenAI's GPT-Image-1-Mini model."
|
|
36
|
+
)
|
|
37
|
+
args_schema = GPTAvatarGeneratorInput
|
|
38
|
+
|
|
39
|
+
async def _arun(self, prompt: str, **kwargs) -> str:
|
|
40
|
+
"""Generate avatar-friendly images using OpenAI's GPT-Image-1-Mini model."""
|
|
41
|
+
context = self.get_context()
|
|
42
|
+
api_key = self.get_api_key()
|
|
43
|
+
job_id = str(XID())
|
|
44
|
+
|
|
45
|
+
composed_prompt = (
|
|
46
|
+
f"{AVATAR_PROMPT_PREFIX}\n{prompt.strip()}"
|
|
47
|
+
if prompt
|
|
48
|
+
else AVATAR_PROMPT_PREFIX
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
client = openai.OpenAI(api_key=api_key)
|
|
53
|
+
|
|
54
|
+
response = client.images.generate(
|
|
55
|
+
model="gpt-image-1-mini",
|
|
56
|
+
prompt=composed_prompt,
|
|
57
|
+
size="1024x1024",
|
|
58
|
+
quality="medium",
|
|
59
|
+
background="opaque",
|
|
60
|
+
moderation="low",
|
|
61
|
+
n=1,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
base64_image = response.data[0].b64_json
|
|
65
|
+
|
|
66
|
+
if hasattr(response, "usage") and response.usage:
|
|
67
|
+
usage = response.usage
|
|
68
|
+
logger.info(
|
|
69
|
+
"GPT-Image-1-Mini avatar generation usage: "
|
|
70
|
+
f"input_tokens={usage.input_tokens}, "
|
|
71
|
+
f"output_tokens={usage.output_tokens}, "
|
|
72
|
+
f"total_tokens={usage.total_tokens}"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
if (
|
|
76
|
+
hasattr(usage, "input_tokens_details")
|
|
77
|
+
and usage.input_tokens_details
|
|
78
|
+
):
|
|
79
|
+
details = usage.input_tokens_details
|
|
80
|
+
logger.info(f"Input tokens details: {details}")
|
|
81
|
+
|
|
82
|
+
image_bytes = base64.b64decode(base64_image)
|
|
83
|
+
|
|
84
|
+
image_key = f"{context.agent_id}/gpt-avatar/{job_id}"
|
|
85
|
+
|
|
86
|
+
stored_url = await store_image_bytes(
|
|
87
|
+
image_bytes,
|
|
88
|
+
image_key,
|
|
89
|
+
"image/jpeg",
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
return stored_url
|
|
93
|
+
|
|
94
|
+
except openai.OpenAIError as e:
|
|
95
|
+
error_message = f"OpenAI API error: {str(e)}"
|
|
96
|
+
logger.error(error_message)
|
|
97
|
+
raise Exception(error_message)
|
|
98
|
+
|
|
99
|
+
except Exception as e:
|
|
100
|
+
error_message = f"Error generating avatar with GPT-Image-1-Mini: {str(e)}"
|
|
101
|
+
logger.error(error_message)
|
|
102
|
+
raise Exception(error_message)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import base64
|
|
4
4
|
import logging
|
|
5
|
-
from typing import Literal
|
|
5
|
+
from typing import Literal
|
|
6
6
|
|
|
7
7
|
import openai
|
|
8
8
|
from epyxid import XID
|
|
@@ -54,7 +54,7 @@ class GPTImageGeneration(OpenAIBaseTool):
|
|
|
54
54
|
"high-quality images from text descriptions.\n"
|
|
55
55
|
"You can specify size, quality, and background parameters for more control.\n"
|
|
56
56
|
)
|
|
57
|
-
args_schema:
|
|
57
|
+
args_schema: type[BaseModel] = GPTImageGenerationInput
|
|
58
58
|
|
|
59
59
|
async def _arun(
|
|
60
60
|
self,
|
|
@@ -72,7 +72,6 @@ class GPTImageGeneration(OpenAIBaseTool):
|
|
|
72
72
|
quality: Quality of the generated image. Options: high, medium, low, auto
|
|
73
73
|
background: Background transparency. Options: transparent, opaque, auto
|
|
74
74
|
|
|
75
|
-
|
|
76
75
|
Returns:
|
|
77
76
|
str: URL of the generated image.
|
|
78
77
|
|
|
@@ -80,12 +79,9 @@ class GPTImageGeneration(OpenAIBaseTool):
|
|
|
80
79
|
Exception: If the image generation fails.
|
|
81
80
|
"""
|
|
82
81
|
context = self.get_context()
|
|
83
|
-
skill_config = context.agent.skill_config(self.category)
|
|
84
82
|
|
|
85
|
-
# Get the OpenAI API key from
|
|
86
|
-
api_key =
|
|
87
|
-
"openai_api_key"
|
|
88
|
-
)
|
|
83
|
+
# Get the OpenAI API key from configuration or agent settings
|
|
84
|
+
api_key = self.get_api_key()
|
|
89
85
|
|
|
90
86
|
# Generate a unique job ID
|
|
91
87
|
job_id = str(XID())
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""GPT image mini generator skill for OpenAI."""
|
|
2
|
+
|
|
3
|
+
import base64
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
import openai
|
|
8
|
+
from epyxid import XID
|
|
9
|
+
|
|
10
|
+
from intentkit.skills.openai.base import OpenAIBaseTool
|
|
11
|
+
from intentkit.skills.openai.gpt_image_generation import GPTImageGenerationInput
|
|
12
|
+
from intentkit.utils.s3 import store_image_bytes
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class GPTImageMiniGenerator(OpenAIBaseTool):
|
|
18
|
+
"""Tool for generating images using OpenAI's GPT-Image-1-Mini model."""
|
|
19
|
+
|
|
20
|
+
name: str = "gpt_image_mini_generator"
|
|
21
|
+
description: str = (
|
|
22
|
+
"Generate images using OpenAI's GPT-Image-1-Mini model.\n"
|
|
23
|
+
"Provide a text prompt describing the image you want to generate.\n"
|
|
24
|
+
"GPT-Image-1-Mini delivers high-quality images with faster performance at a lower cost.\n"
|
|
25
|
+
"You can specify size, quality, and background parameters for more control.\n"
|
|
26
|
+
)
|
|
27
|
+
args_schema = GPTImageGenerationInput
|
|
28
|
+
|
|
29
|
+
async def _arun(
|
|
30
|
+
self,
|
|
31
|
+
prompt: str,
|
|
32
|
+
size: Literal["1024x1024", "1536x1024", "1024x1536", "auto"] = "auto",
|
|
33
|
+
quality: Literal["high", "medium", "low", "auto"] = "auto",
|
|
34
|
+
background: Literal["transparent", "opaque", "auto"] = "auto",
|
|
35
|
+
**kwargs,
|
|
36
|
+
) -> str:
|
|
37
|
+
"""Generate images using OpenAI's GPT-Image-1-Mini model."""
|
|
38
|
+
context = self.get_context()
|
|
39
|
+
api_key = self.get_api_key()
|
|
40
|
+
job_id = str(XID())
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
client = openai.OpenAI(api_key=api_key)
|
|
44
|
+
|
|
45
|
+
content_type = "image/png" if background == "transparent" else "image/jpeg"
|
|
46
|
+
|
|
47
|
+
response = client.images.generate(
|
|
48
|
+
model="gpt-image-1-mini",
|
|
49
|
+
prompt=prompt,
|
|
50
|
+
size=size,
|
|
51
|
+
quality=quality,
|
|
52
|
+
background=background,
|
|
53
|
+
moderation="low",
|
|
54
|
+
n=1,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
base64_image = response.data[0].b64_json
|
|
58
|
+
|
|
59
|
+
if hasattr(response, "usage") and response.usage:
|
|
60
|
+
usage = response.usage
|
|
61
|
+
logger.info(
|
|
62
|
+
"GPT-Image-1-Mini generation usage: "
|
|
63
|
+
f"input_tokens={usage.input_tokens}, "
|
|
64
|
+
f"output_tokens={usage.output_tokens}, "
|
|
65
|
+
f"total_tokens={usage.total_tokens}"
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if (
|
|
69
|
+
hasattr(usage, "input_tokens_details")
|
|
70
|
+
and usage.input_tokens_details
|
|
71
|
+
):
|
|
72
|
+
details = usage.input_tokens_details
|
|
73
|
+
logger.info(f"Input tokens details: {details}")
|
|
74
|
+
|
|
75
|
+
image_bytes = base64.b64decode(base64_image)
|
|
76
|
+
|
|
77
|
+
image_key = f"{context.agent_id}/gpt-image-mini/{job_id}"
|
|
78
|
+
|
|
79
|
+
stored_url = await store_image_bytes(image_bytes, image_key, content_type)
|
|
80
|
+
|
|
81
|
+
return stored_url
|
|
82
|
+
|
|
83
|
+
except openai.OpenAIError as e:
|
|
84
|
+
error_message = f"OpenAI API error: {str(e)}"
|
|
85
|
+
logger.error(error_message)
|
|
86
|
+
raise Exception(error_message)
|
|
87
|
+
|
|
88
|
+
except Exception as e:
|
|
89
|
+
error_message = f"Error generating image with GPT-Image-1-Mini: {str(e)}"
|
|
90
|
+
logger.error(error_message)
|
|
91
|
+
raise Exception(error_message)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import base64
|
|
4
4
|
import logging
|
|
5
5
|
from io import BytesIO
|
|
6
|
-
from typing import Literal
|
|
6
|
+
from typing import Literal
|
|
7
7
|
|
|
8
8
|
import httpx
|
|
9
9
|
import openai
|
|
@@ -55,7 +55,7 @@ class GPTImageToImage(OpenAIBaseTool):
|
|
|
55
55
|
"based on text descriptions.\n"
|
|
56
56
|
"You can specify size and quality parameters for more control.\n"
|
|
57
57
|
)
|
|
58
|
-
args_schema:
|
|
58
|
+
args_schema: type[BaseModel] = GPTImageToImageInput
|
|
59
59
|
|
|
60
60
|
async def _arun(
|
|
61
61
|
self,
|
|
@@ -73,7 +73,6 @@ class GPTImageToImage(OpenAIBaseTool):
|
|
|
73
73
|
size: Size of the generated image. Options: 1024x1024, 1536x1024, 1024x1536, auto
|
|
74
74
|
quality: Quality of the generated image. Options: high, medium, low, auto
|
|
75
75
|
|
|
76
|
-
|
|
77
76
|
Returns:
|
|
78
77
|
str: URL of the edited image.
|
|
79
78
|
|
|
@@ -81,12 +80,9 @@ class GPTImageToImage(OpenAIBaseTool):
|
|
|
81
80
|
Exception: If the image editing fails.
|
|
82
81
|
"""
|
|
83
82
|
context = self.get_context()
|
|
84
|
-
skill_config = context.agent.skill_config(self.category)
|
|
85
83
|
|
|
86
|
-
# Get the OpenAI API key from
|
|
87
|
-
api_key =
|
|
88
|
-
"openai_api_key"
|
|
89
|
-
)
|
|
84
|
+
# Get the OpenAI API key from configuration or agent settings
|
|
85
|
+
api_key = self.get_api_key()
|
|
90
86
|
|
|
91
87
|
# Generate a unique job ID
|
|
92
88
|
job_id = str(XID())
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import io
|
|
2
2
|
import logging
|
|
3
|
-
from typing import Type
|
|
4
3
|
|
|
5
4
|
import aiohttp
|
|
6
5
|
import openai
|
|
@@ -46,7 +45,7 @@ class ImageToText(OpenAIBaseTool):
|
|
|
46
45
|
"Provide a URL to the image to analyze and get a comprehensive textual description.\n"
|
|
47
46
|
"Optimized for DALL-E generated images and preserves as many details as possible."
|
|
48
47
|
)
|
|
49
|
-
args_schema:
|
|
48
|
+
args_schema: type[BaseModel] = ImageToTextInput
|
|
50
49
|
|
|
51
50
|
async def _arun(self, image: str, **kwargs) -> ImageToTextOutput:
|
|
52
51
|
"""Implementation of the tool to convert images to text.
|
|
@@ -58,13 +57,10 @@ class ImageToText(OpenAIBaseTool):
|
|
|
58
57
|
ImageToTextOutput: Object containing the text description and image dimensions.
|
|
59
58
|
"""
|
|
60
59
|
context = self.get_context()
|
|
61
|
-
skill_config = context.agent.skill_config(self.category)
|
|
62
60
|
logger.debug(f"context: {context}")
|
|
63
61
|
|
|
64
|
-
# Get the OpenAI client from
|
|
65
|
-
api_key =
|
|
66
|
-
"openai_api_key"
|
|
67
|
-
)
|
|
62
|
+
# Get the OpenAI client from configuration or agent settings
|
|
63
|
+
api_key = self.get_api_key()
|
|
68
64
|
client = openai.AsyncOpenAI(api_key=api_key)
|
|
69
65
|
|
|
70
66
|
try:
|
|
@@ -66,6 +66,38 @@
|
|
|
66
66
|
"description": "Generate images using OpenAI's GPT-Image-1 model based on text prompts",
|
|
67
67
|
"default": "private"
|
|
68
68
|
},
|
|
69
|
+
"gpt_image_mini_generator": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"title": "Image Generation by GPT Mini",
|
|
72
|
+
"enum": [
|
|
73
|
+
"disabled",
|
|
74
|
+
"public",
|
|
75
|
+
"private"
|
|
76
|
+
],
|
|
77
|
+
"x-enum-title": [
|
|
78
|
+
"Disabled",
|
|
79
|
+
"Agent Owner + All Users",
|
|
80
|
+
"Agent Owner Only"
|
|
81
|
+
],
|
|
82
|
+
"description": "Generate images using OpenAI's GPT-Image-1-Mini model based on text prompts",
|
|
83
|
+
"default": "private"
|
|
84
|
+
},
|
|
85
|
+
"gpt_avatar_generator": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"title": "Avatar Generation by GPT Mini",
|
|
88
|
+
"enum": [
|
|
89
|
+
"disabled",
|
|
90
|
+
"public",
|
|
91
|
+
"private"
|
|
92
|
+
],
|
|
93
|
+
"x-enum-title": [
|
|
94
|
+
"Disabled",
|
|
95
|
+
"Agent Owner + All Users",
|
|
96
|
+
"Agent Owner Only"
|
|
97
|
+
],
|
|
98
|
+
"description": "Generate avatar-ready profile images using OpenAI's GPT-Image-1-Mini model",
|
|
99
|
+
"default": "private"
|
|
100
|
+
},
|
|
69
101
|
"gpt_image_to_image": {
|
|
70
102
|
"type": "string",
|
|
71
103
|
"title": "Image Editing by GPT",
|
|
@@ -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, SkillState
|
|
8
7
|
from intentkit.skills.portfolio.base import PortfolioBaseTool
|
|
9
8
|
from intentkit.skills.portfolio.token_balances import TokenBalances
|
|
@@ -51,7 +50,6 @@ class Config(SkillConfig):
|
|
|
51
50
|
async def get_skills(
|
|
52
51
|
config: "Config",
|
|
53
52
|
is_private: bool,
|
|
54
|
-
store: SkillStoreABC,
|
|
55
53
|
**_,
|
|
56
54
|
) -> list[PortfolioBaseTool]:
|
|
57
55
|
"""Get all Portfolio blockchain analysis skills.
|
|
@@ -59,7 +57,6 @@ async def get_skills(
|
|
|
59
57
|
Args:
|
|
60
58
|
config: The configuration for Portfolio skills.
|
|
61
59
|
is_private: Whether to include private skills.
|
|
62
|
-
store: The skill store for persisting data.
|
|
63
60
|
|
|
64
61
|
Returns:
|
|
65
62
|
A list of Portfolio blockchain analysis skills.
|
|
@@ -76,7 +73,7 @@ async def get_skills(
|
|
|
76
73
|
# Get each skill using the cached getter
|
|
77
74
|
result = []
|
|
78
75
|
for name in available_skills:
|
|
79
|
-
skill = get_portfolio_skill(name
|
|
76
|
+
skill = get_portfolio_skill(name)
|
|
80
77
|
if skill:
|
|
81
78
|
result.append(skill)
|
|
82
79
|
return result
|
|
@@ -84,68 +81,47 @@ async def get_skills(
|
|
|
84
81
|
|
|
85
82
|
def get_portfolio_skill(
|
|
86
83
|
name: str,
|
|
87
|
-
store: SkillStoreABC,
|
|
88
84
|
) -> PortfolioBaseTool:
|
|
89
85
|
"""Get a portfolio skill by name."""
|
|
90
86
|
if name == "wallet_history":
|
|
91
87
|
if name not in _cache:
|
|
92
|
-
_cache[name] = WalletHistory(
|
|
93
|
-
skill_store=store,
|
|
94
|
-
)
|
|
88
|
+
_cache[name] = WalletHistory()
|
|
95
89
|
return _cache[name]
|
|
96
90
|
elif name == "token_balances":
|
|
97
91
|
if name not in _cache:
|
|
98
|
-
_cache[name] = TokenBalances(
|
|
99
|
-
skill_store=store,
|
|
100
|
-
)
|
|
92
|
+
_cache[name] = TokenBalances()
|
|
101
93
|
return _cache[name]
|
|
102
94
|
elif name == "wallet_approvals":
|
|
103
95
|
if name not in _cache:
|
|
104
|
-
_cache[name] = WalletApprovals(
|
|
105
|
-
skill_store=store,
|
|
106
|
-
)
|
|
96
|
+
_cache[name] = WalletApprovals()
|
|
107
97
|
return _cache[name]
|
|
108
98
|
elif name == "wallet_swaps":
|
|
109
99
|
if name not in _cache:
|
|
110
|
-
_cache[name] = WalletSwaps(
|
|
111
|
-
skill_store=store,
|
|
112
|
-
)
|
|
100
|
+
_cache[name] = WalletSwaps()
|
|
113
101
|
return _cache[name]
|
|
114
102
|
elif name == "wallet_net_worth":
|
|
115
103
|
if name not in _cache:
|
|
116
|
-
_cache[name] = WalletNetWorth(
|
|
117
|
-
skill_store=store,
|
|
118
|
-
)
|
|
104
|
+
_cache[name] = WalletNetWorth()
|
|
119
105
|
return _cache[name]
|
|
120
106
|
elif name == "wallet_profitability_summary":
|
|
121
107
|
if name not in _cache:
|
|
122
|
-
_cache[name] = WalletProfitabilitySummary(
|
|
123
|
-
skill_store=store,
|
|
124
|
-
)
|
|
108
|
+
_cache[name] = WalletProfitabilitySummary()
|
|
125
109
|
return _cache[name]
|
|
126
110
|
elif name == "wallet_profitability":
|
|
127
111
|
if name not in _cache:
|
|
128
|
-
_cache[name] = WalletProfitability(
|
|
129
|
-
skill_store=store,
|
|
130
|
-
)
|
|
112
|
+
_cache[name] = WalletProfitability()
|
|
131
113
|
return _cache[name]
|
|
132
114
|
elif name == "wallet_stats":
|
|
133
115
|
if name not in _cache:
|
|
134
|
-
_cache[name] = WalletStats(
|
|
135
|
-
skill_store=store,
|
|
136
|
-
)
|
|
116
|
+
_cache[name] = WalletStats()
|
|
137
117
|
return _cache[name]
|
|
138
118
|
elif name == "wallet_defi_positions":
|
|
139
119
|
if name not in _cache:
|
|
140
|
-
_cache[name] = WalletDefiPositions(
|
|
141
|
-
skill_store=store,
|
|
142
|
-
)
|
|
120
|
+
_cache[name] = WalletDefiPositions()
|
|
143
121
|
return _cache[name]
|
|
144
122
|
elif name == "wallet_nfts":
|
|
145
123
|
if name not in _cache:
|
|
146
|
-
_cache[name] = WalletNFTs(
|
|
147
|
-
skill_store=store,
|
|
148
|
-
)
|
|
124
|
+
_cache[name] = WalletNFTs()
|
|
149
125
|
return _cache[name]
|
|
150
126
|
else:
|
|
151
127
|
raise ValueError(f"Unknown portfolio skill: {name}")
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
5
|
from abc import ABC
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any
|
|
7
7
|
|
|
8
8
|
import aiohttp
|
|
9
|
+
from langchain_core.tools import ToolException
|
|
9
10
|
from pydantic import BaseModel, Field
|
|
10
11
|
|
|
11
|
-
from intentkit.
|
|
12
|
+
from intentkit.config.config import config
|
|
12
13
|
from intentkit.skills.base import IntentKitSkill
|
|
13
14
|
from intentkit.skills.portfolio.constants import MORALIS_API_BASE_URL
|
|
14
15
|
|
|
@@ -20,23 +21,26 @@ class PortfolioBaseTool(IntentKitSkill, ABC):
|
|
|
20
21
|
|
|
21
22
|
name: str = Field(description="The name of the tool")
|
|
22
23
|
description: str = Field(description="A description of what the tool does")
|
|
23
|
-
args_schema:
|
|
24
|
-
skill_store: SkillStoreABC = Field(
|
|
25
|
-
description="The skill store for persisting data"
|
|
26
|
-
)
|
|
24
|
+
args_schema: type[BaseModel]
|
|
27
25
|
|
|
28
26
|
def get_api_key(self) -> str:
|
|
29
27
|
context = self.get_context()
|
|
30
28
|
skill_config = context.agent.skill_config(self.category)
|
|
31
29
|
if skill_config.get("api_key_provider") == "agent_owner":
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
api_key = skill_config.get("api_key")
|
|
31
|
+
else:
|
|
32
|
+
api_key = config.moralis_api_key
|
|
33
|
+
|
|
34
|
+
if not api_key:
|
|
35
|
+
raise ToolException("Moralis API key is not configured.")
|
|
36
|
+
|
|
37
|
+
return api_key
|
|
34
38
|
|
|
35
39
|
@property
|
|
36
40
|
def category(self) -> str:
|
|
37
41
|
return "portfolio"
|
|
38
42
|
|
|
39
|
-
def _prepare_params(self, params:
|
|
43
|
+
def _prepare_params(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
40
44
|
"""Convert boolean values to lowercase strings for API compatibility.
|
|
41
45
|
|
|
42
46
|
Args:
|
|
@@ -61,9 +65,9 @@ class PortfolioBaseTool(IntentKitSkill, ABC):
|
|
|
61
65
|
method: str,
|
|
62
66
|
endpoint: str,
|
|
63
67
|
api_key: str,
|
|
64
|
-
params:
|
|
65
|
-
data:
|
|
66
|
-
) ->
|
|
68
|
+
params: dict[str, Any] = None,
|
|
69
|
+
data: dict[str, Any] = None,
|
|
70
|
+
) -> dict[str, Any]:
|
|
67
71
|
"""Make a request to the Moralis API.
|
|
68
72
|
|
|
69
73
|
Args:
|
|
@@ -95,13 +99,23 @@ class PortfolioBaseTool(IntentKitSkill, ABC):
|
|
|
95
99
|
) as response:
|
|
96
100
|
if response.status >= 400:
|
|
97
101
|
error_text = await response.text()
|
|
98
|
-
logger.error(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
logger.error(
|
|
103
|
+
"portfolio/base.py: API error %s for %s", response.status, url
|
|
104
|
+
)
|
|
105
|
+
raise ToolException(
|
|
106
|
+
f"Moralis API error: {response.status} - {error_text}"
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
return await response.json()
|
|
111
|
+
except aiohttp.ContentTypeError as exc:
|
|
112
|
+
await response.text()
|
|
113
|
+
logger.error(
|
|
114
|
+
"portfolio/base.py: Failed to decode JSON response from %s", url
|
|
115
|
+
)
|
|
116
|
+
raise ToolException(
|
|
117
|
+
"Moralis API returned invalid JSON payload."
|
|
118
|
+
) from exc
|
|
105
119
|
|
|
106
120
|
def _run(self, *args: Any, **kwargs: Any) -> Any:
|
|
107
121
|
"""Execute the tool synchronously by running the async version in a loop."""
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
@@ -20,39 +20,39 @@ class TokenBalancesInput(BaseModel):
|
|
|
20
20
|
description="The chain to query (e.g., 'eth', 'bsc', 'polygon').",
|
|
21
21
|
default=DEFAULT_CHAIN,
|
|
22
22
|
)
|
|
23
|
-
to_block:
|
|
23
|
+
to_block: int | None = Field(
|
|
24
24
|
description="The block number up to which the balances will be checked.",
|
|
25
25
|
default=None,
|
|
26
26
|
)
|
|
27
|
-
token_addresses:
|
|
27
|
+
token_addresses: list[str] | None = Field(
|
|
28
28
|
description="The specific token addresses to get balances for.",
|
|
29
29
|
default=None,
|
|
30
30
|
)
|
|
31
|
-
exclude_spam:
|
|
31
|
+
exclude_spam: bool | None = Field(
|
|
32
32
|
description="Exclude spam tokens from the result.",
|
|
33
33
|
default=True,
|
|
34
34
|
)
|
|
35
|
-
exclude_unverified_contracts:
|
|
35
|
+
exclude_unverified_contracts: bool | None = Field(
|
|
36
36
|
description="Exclude unverified contracts from the result.",
|
|
37
37
|
default=True,
|
|
38
38
|
)
|
|
39
|
-
cursor:
|
|
39
|
+
cursor: str | None = Field(
|
|
40
40
|
description="The cursor for pagination.",
|
|
41
41
|
default=None,
|
|
42
42
|
)
|
|
43
|
-
limit:
|
|
43
|
+
limit: int | None = Field(
|
|
44
44
|
description="The number of results per page.",
|
|
45
45
|
default=DEFAULT_LIMIT,
|
|
46
46
|
)
|
|
47
|
-
exclude_native:
|
|
47
|
+
exclude_native: bool | None = Field(
|
|
48
48
|
description="Exclude native balance from the result.",
|
|
49
49
|
default=None,
|
|
50
50
|
)
|
|
51
|
-
max_token_inactivity:
|
|
51
|
+
max_token_inactivity: int | None = Field(
|
|
52
52
|
description="Exclude tokens inactive for more than the given amount of days.",
|
|
53
53
|
default=None,
|
|
54
54
|
)
|
|
55
|
-
min_pair_side_liquidity_usd:
|
|
55
|
+
min_pair_side_liquidity_usd: float | None = Field(
|
|
56
56
|
description="Exclude tokens with liquidity less than the specified amount in USD.",
|
|
57
57
|
default=None,
|
|
58
58
|
)
|
|
@@ -70,23 +70,23 @@ class TokenBalances(PortfolioBaseTool):
|
|
|
70
70
|
"Get token balances for a specific wallet address and their token prices in USD. "
|
|
71
71
|
"Includes options to exclude spam and unverified contracts."
|
|
72
72
|
)
|
|
73
|
-
args_schema:
|
|
73
|
+
args_schema: type[BaseModel] = TokenBalancesInput
|
|
74
74
|
|
|
75
75
|
async def _arun(
|
|
76
76
|
self,
|
|
77
77
|
address: str,
|
|
78
78
|
chain: str = DEFAULT_CHAIN,
|
|
79
|
-
to_block:
|
|
80
|
-
token_addresses:
|
|
81
|
-
exclude_spam:
|
|
82
|
-
exclude_unverified_contracts:
|
|
83
|
-
cursor:
|
|
84
|
-
limit:
|
|
85
|
-
exclude_native:
|
|
86
|
-
max_token_inactivity:
|
|
87
|
-
min_pair_side_liquidity_usd:
|
|
79
|
+
to_block: int | None = None,
|
|
80
|
+
token_addresses: list[str] | None = None,
|
|
81
|
+
exclude_spam: bool | None = True,
|
|
82
|
+
exclude_unverified_contracts: bool | None = True,
|
|
83
|
+
cursor: str | None = None,
|
|
84
|
+
limit: int | None = DEFAULT_LIMIT,
|
|
85
|
+
exclude_native: bool | None = None,
|
|
86
|
+
max_token_inactivity: int | None = None,
|
|
87
|
+
min_pair_side_liquidity_usd: float | None = None,
|
|
88
88
|
**kwargs,
|
|
89
|
-
) ->
|
|
89
|
+
) -> dict[str, Any]:
|
|
90
90
|
"""Fetch token balances from Moralis.
|
|
91
91
|
|
|
92
92
|
Args:
|