intentkit 0.7.5.dev3__py3-none-any.whl → 0.8.34.dev7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- intentkit/MANIFEST.in +14 -0
- intentkit/README.md +88 -0
- intentkit/__init__.py +6 -4
- intentkit/abstracts/agent.py +4 -5
- intentkit/abstracts/engine.py +5 -5
- intentkit/abstracts/graph.py +15 -8
- intentkit/abstracts/skill.py +6 -144
- intentkit/abstracts/twitter.py +4 -5
- intentkit/clients/__init__.py +9 -2
- intentkit/clients/cdp.py +129 -153
- intentkit/{utils → clients}/s3.py +109 -34
- intentkit/clients/twitter.py +83 -62
- intentkit/clients/web3.py +4 -7
- intentkit/config/config.py +123 -90
- intentkit/core/account_checking.py +802 -0
- intentkit/core/agent.py +313 -498
- intentkit/core/asset.py +267 -0
- intentkit/core/chat.py +5 -3
- intentkit/core/client.py +1 -1
- intentkit/core/credit.py +49 -41
- intentkit/core/draft.py +201 -0
- intentkit/core/draft_chat.py +118 -0
- intentkit/core/engine.py +378 -287
- intentkit/core/manager/__init__.py +25 -0
- intentkit/core/manager/engine.py +220 -0
- intentkit/core/manager/service.py +172 -0
- intentkit/core/manager/skills.py +178 -0
- intentkit/core/middleware.py +231 -0
- intentkit/core/prompt.py +74 -114
- intentkit/core/scheduler.py +143 -0
- intentkit/core/statistics.py +168 -0
- intentkit/models/agent.py +931 -518
- intentkit/models/agent_data.py +165 -106
- intentkit/models/agent_schema.json +38 -251
- intentkit/models/app_setting.py +15 -13
- intentkit/models/chat.py +86 -140
- intentkit/models/credit.py +182 -162
- intentkit/models/db.py +42 -23
- intentkit/models/db_mig.py +120 -3
- intentkit/models/draft.py +222 -0
- intentkit/models/llm.csv +31 -0
- intentkit/models/llm.py +262 -370
- intentkit/models/redis.py +6 -4
- intentkit/models/skill.py +222 -101
- intentkit/models/skills.csv +173 -0
- intentkit/models/team.py +189 -0
- intentkit/models/user.py +103 -31
- intentkit/skills/acolyt/__init__.py +2 -9
- intentkit/skills/acolyt/ask.py +3 -4
- intentkit/skills/acolyt/base.py +4 -9
- intentkit/skills/acolyt/schema.json +4 -3
- intentkit/skills/aixbt/__init__.py +2 -13
- intentkit/skills/aixbt/base.py +1 -7
- intentkit/skills/aixbt/projects.py +14 -15
- intentkit/skills/aixbt/schema.json +4 -4
- intentkit/skills/allora/__init__.py +2 -9
- intentkit/skills/allora/base.py +4 -9
- intentkit/skills/allora/price.py +3 -4
- intentkit/skills/allora/schema.json +3 -2
- intentkit/skills/base.py +241 -41
- intentkit/skills/basename/__init__.py +51 -0
- intentkit/skills/basename/base.py +11 -0
- intentkit/skills/basename/basename.svg +11 -0
- intentkit/skills/basename/schema.json +58 -0
- intentkit/skills/carv/__init__.py +115 -121
- intentkit/skills/carv/base.py +184 -185
- intentkit/skills/carv/fetch_news.py +3 -3
- intentkit/skills/carv/onchain_query.py +4 -4
- intentkit/skills/carv/schema.json +134 -137
- intentkit/skills/carv/token_info_and_price.py +6 -6
- intentkit/skills/casino/__init__.py +4 -15
- intentkit/skills/casino/base.py +1 -7
- intentkit/skills/casino/deck_draw.py +5 -8
- intentkit/skills/casino/deck_shuffle.py +6 -6
- intentkit/skills/casino/dice_roll.py +2 -4
- intentkit/skills/casino/schema.json +0 -1
- intentkit/skills/cdp/__init__.py +22 -84
- intentkit/skills/cdp/base.py +1 -7
- intentkit/skills/cdp/schema.json +11 -314
- intentkit/skills/chainlist/__init__.py +2 -7
- intentkit/skills/chainlist/base.py +1 -7
- intentkit/skills/chainlist/chain_lookup.py +18 -18
- intentkit/skills/chainlist/schema.json +3 -5
- intentkit/skills/common/__init__.py +2 -9
- intentkit/skills/common/base.py +1 -7
- intentkit/skills/common/current_time.py +1 -2
- intentkit/skills/common/schema.json +2 -2
- intentkit/skills/cookiefun/__init__.py +6 -9
- intentkit/skills/cookiefun/base.py +2 -7
- intentkit/skills/cookiefun/get_account_details.py +7 -7
- intentkit/skills/cookiefun/get_account_feed.py +19 -19
- intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
- intentkit/skills/cookiefun/get_sectors.py +3 -3
- intentkit/skills/cookiefun/schema.json +1 -3
- intentkit/skills/cookiefun/search_accounts.py +9 -9
- intentkit/skills/cryptocompare/__init__.py +7 -24
- intentkit/skills/cryptocompare/api.py +2 -3
- intentkit/skills/cryptocompare/base.py +10 -24
- intentkit/skills/cryptocompare/fetch_news.py +4 -5
- intentkit/skills/cryptocompare/fetch_price.py +6 -7
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
- intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
- intentkit/skills/cryptocompare/schema.json +3 -3
- intentkit/skills/cryptopanic/__init__.py +7 -10
- intentkit/skills/cryptopanic/base.py +51 -55
- intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
- intentkit/skills/cryptopanic/schema.json +105 -103
- intentkit/skills/dapplooker/__init__.py +2 -9
- intentkit/skills/dapplooker/base.py +4 -9
- intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
- intentkit/skills/dapplooker/schema.json +3 -5
- intentkit/skills/defillama/__init__.py +24 -74
- intentkit/skills/defillama/api.py +6 -9
- intentkit/skills/defillama/base.py +8 -19
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_block.py +6 -8
- intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
- intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
- intentkit/skills/defillama/config/chains.py +1 -3
- intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
- intentkit/skills/defillama/schema.json +5 -1
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
- intentkit/skills/defillama/tests/api_integration.test.py +1 -1
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
- intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
- intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
- intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
- intentkit/skills/defillama/yields/fetch_pools.py +26 -30
- intentkit/skills/dexscreener/__init__.py +97 -102
- intentkit/skills/dexscreener/base.py +125 -130
- intentkit/skills/dexscreener/get_pair_info.py +4 -5
- intentkit/skills/dexscreener/get_token_pairs.py +4 -5
- intentkit/skills/dexscreener/get_tokens_info.py +7 -8
- intentkit/skills/dexscreener/model/search_token_response.py +80 -82
- intentkit/skills/dexscreener/schema.json +91 -93
- intentkit/skills/dexscreener/search_token.py +182 -184
- intentkit/skills/dexscreener/utils.py +15 -14
- intentkit/skills/dune_analytics/__init__.py +7 -9
- intentkit/skills/dune_analytics/base.py +48 -52
- intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
- intentkit/skills/dune_analytics/schema.json +104 -99
- intentkit/skills/elfa/__init__.py +5 -18
- intentkit/skills/elfa/base.py +10 -14
- intentkit/skills/elfa/mention.py +19 -21
- intentkit/skills/elfa/schema.json +3 -2
- intentkit/skills/elfa/stats.py +4 -4
- intentkit/skills/elfa/tokens.py +12 -12
- intentkit/skills/elfa/utils.py +26 -28
- intentkit/skills/enso/__init__.py +11 -31
- intentkit/skills/enso/base.py +54 -35
- intentkit/skills/enso/best_yield.py +16 -24
- intentkit/skills/enso/networks.py +6 -11
- intentkit/skills/enso/prices.py +11 -13
- intentkit/skills/enso/route.py +34 -38
- intentkit/skills/enso/schema.json +3 -2
- intentkit/skills/enso/tokens.py +29 -38
- intentkit/skills/enso/wallet.py +76 -191
- intentkit/skills/erc20/__init__.py +50 -0
- intentkit/skills/erc20/base.py +11 -0
- intentkit/skills/erc20/erc20.svg +5 -0
- intentkit/skills/erc20/schema.json +74 -0
- intentkit/skills/erc721/__init__.py +53 -0
- intentkit/skills/erc721/base.py +11 -0
- intentkit/skills/erc721/erc721.svg +5 -0
- intentkit/skills/erc721/schema.json +90 -0
- intentkit/skills/firecrawl/__init__.py +5 -18
- intentkit/skills/firecrawl/base.py +4 -9
- intentkit/skills/firecrawl/clear.py +4 -8
- intentkit/skills/firecrawl/crawl.py +19 -19
- intentkit/skills/firecrawl/query.py +4 -3
- intentkit/skills/firecrawl/schema.json +2 -6
- intentkit/skills/firecrawl/scrape.py +17 -22
- intentkit/skills/firecrawl/utils.py +50 -42
- intentkit/skills/github/__init__.py +2 -7
- intentkit/skills/github/base.py +1 -7
- intentkit/skills/github/github_search.py +1 -2
- intentkit/skills/github/schema.json +3 -4
- intentkit/skills/heurist/__init__.py +8 -27
- intentkit/skills/heurist/base.py +4 -9
- intentkit/skills/heurist/image_generation_animagine_xl.py +13 -15
- intentkit/skills/heurist/image_generation_arthemy_comics.py +13 -15
- intentkit/skills/heurist/image_generation_arthemy_real.py +13 -15
- intentkit/skills/heurist/image_generation_braindance.py +13 -15
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +13 -15
- intentkit/skills/heurist/image_generation_flux_1_dev.py +13 -15
- intentkit/skills/heurist/image_generation_sdxl.py +13 -15
- intentkit/skills/heurist/schema.json +2 -2
- intentkit/skills/http/__init__.py +4 -15
- intentkit/skills/http/base.py +1 -7
- intentkit/skills/http/get.py +21 -16
- intentkit/skills/http/post.py +23 -18
- intentkit/skills/http/put.py +23 -18
- intentkit/skills/http/schema.json +4 -5
- intentkit/skills/lifi/__init__.py +8 -13
- intentkit/skills/lifi/base.py +3 -9
- intentkit/skills/lifi/schema.json +17 -8
- intentkit/skills/lifi/token_execute.py +150 -60
- intentkit/skills/lifi/token_quote.py +8 -10
- intentkit/skills/lifi/utils.py +104 -51
- intentkit/skills/moralis/__init__.py +6 -10
- intentkit/skills/moralis/api.py +6 -7
- intentkit/skills/moralis/base.py +5 -10
- intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
- intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
- intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
- intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
- intentkit/skills/moralis/schema.json +7 -2
- intentkit/skills/morpho/__init__.py +52 -0
- intentkit/skills/morpho/base.py +11 -0
- intentkit/skills/morpho/morpho.svg +12 -0
- intentkit/skills/morpho/schema.json +73 -0
- intentkit/skills/nation/__init__.py +4 -9
- intentkit/skills/nation/base.py +5 -10
- intentkit/skills/nation/nft_check.py +3 -4
- intentkit/skills/nation/schema.json +4 -3
- intentkit/skills/onchain.py +30 -0
- intentkit/skills/openai/__init__.py +17 -18
- intentkit/skills/openai/base.py +10 -14
- intentkit/skills/openai/dalle_image_generation.py +4 -9
- intentkit/skills/openai/gpt_avatar_generator.py +102 -0
- intentkit/skills/openai/gpt_image_generation.py +5 -9
- intentkit/skills/openai/gpt_image_mini_generator.py +92 -0
- intentkit/skills/openai/gpt_image_to_image.py +5 -9
- intentkit/skills/openai/image_to_text.py +3 -7
- intentkit/skills/openai/schema.json +34 -3
- intentkit/skills/portfolio/__init__.py +11 -35
- intentkit/skills/portfolio/base.py +33 -19
- intentkit/skills/portfolio/schema.json +3 -5
- intentkit/skills/portfolio/token_balances.py +21 -21
- intentkit/skills/portfolio/wallet_approvals.py +17 -18
- intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
- intentkit/skills/portfolio/wallet_history.py +31 -31
- intentkit/skills/portfolio/wallet_net_worth.py +13 -13
- intentkit/skills/portfolio/wallet_nfts.py +19 -19
- intentkit/skills/portfolio/wallet_profitability.py +18 -18
- intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
- intentkit/skills/portfolio/wallet_stats.py +3 -3
- intentkit/skills/portfolio/wallet_swaps.py +19 -19
- intentkit/skills/pyth/__init__.py +50 -0
- intentkit/skills/pyth/base.py +11 -0
- intentkit/skills/pyth/pyth.svg +6 -0
- intentkit/skills/pyth/schema.json +75 -0
- intentkit/skills/skills.toml +36 -0
- intentkit/skills/slack/__init__.py +5 -17
- intentkit/skills/slack/base.py +3 -9
- intentkit/skills/slack/get_channel.py +8 -8
- intentkit/skills/slack/get_message.py +9 -9
- intentkit/skills/slack/schedule_message.py +5 -5
- intentkit/skills/slack/schema.json +2 -2
- intentkit/skills/slack/send_message.py +3 -5
- intentkit/skills/supabase/__init__.py +7 -23
- intentkit/skills/supabase/base.py +1 -7
- intentkit/skills/supabase/delete_data.py +4 -4
- intentkit/skills/supabase/fetch_data.py +12 -12
- intentkit/skills/supabase/insert_data.py +4 -4
- intentkit/skills/supabase/invoke_function.py +6 -6
- intentkit/skills/supabase/schema.json +2 -3
- intentkit/skills/supabase/update_data.py +6 -6
- intentkit/skills/supabase/upsert_data.py +4 -4
- intentkit/skills/superfluid/__init__.py +53 -0
- intentkit/skills/superfluid/base.py +11 -0
- intentkit/skills/superfluid/schema.json +89 -0
- intentkit/skills/superfluid/superfluid.svg +6 -0
- intentkit/skills/system/__init__.py +7 -24
- intentkit/skills/system/add_autonomous_task.py +10 -12
- intentkit/skills/system/delete_autonomous_task.py +2 -2
- intentkit/skills/system/edit_autonomous_task.py +14 -18
- intentkit/skills/system/list_autonomous_tasks.py +3 -5
- intentkit/skills/system/read_agent_api_key.py +6 -4
- intentkit/skills/system/regenerate_agent_api_key.py +6 -4
- intentkit/skills/system/schema.json +6 -8
- intentkit/skills/tavily/__init__.py +3 -12
- intentkit/skills/tavily/base.py +4 -9
- intentkit/skills/tavily/schema.json +3 -5
- intentkit/skills/tavily/tavily_extract.py +2 -4
- intentkit/skills/tavily/tavily_search.py +4 -6
- intentkit/skills/token/__init__.py +5 -10
- intentkit/skills/token/base.py +7 -11
- intentkit/skills/token/erc20_transfers.py +19 -19
- intentkit/skills/token/schema.json +3 -6
- intentkit/skills/token/token_analytics.py +3 -3
- intentkit/skills/token/token_price.py +13 -13
- intentkit/skills/token/token_search.py +9 -9
- intentkit/skills/twitter/__init__.py +11 -35
- intentkit/skills/twitter/base.py +22 -34
- intentkit/skills/twitter/follow_user.py +2 -6
- intentkit/skills/twitter/get_mentions.py +5 -12
- intentkit/skills/twitter/get_timeline.py +4 -12
- intentkit/skills/twitter/get_user_by_username.py +2 -6
- intentkit/skills/twitter/get_user_tweets.py +5 -13
- intentkit/skills/twitter/like_tweet.py +2 -6
- intentkit/skills/twitter/post_tweet.py +6 -9
- intentkit/skills/twitter/reply_tweet.py +6 -9
- intentkit/skills/twitter/retweet.py +2 -6
- intentkit/skills/twitter/schema.json +1 -0
- intentkit/skills/twitter/search_tweets.py +4 -12
- intentkit/skills/unrealspeech/__init__.py +2 -7
- intentkit/skills/unrealspeech/base.py +2 -8
- intentkit/skills/unrealspeech/schema.json +2 -5
- intentkit/skills/unrealspeech/text_to_speech.py +8 -8
- intentkit/skills/venice_audio/__init__.py +98 -106
- intentkit/skills/venice_audio/base.py +117 -121
- intentkit/skills/venice_audio/input.py +41 -41
- intentkit/skills/venice_audio/schema.json +151 -152
- intentkit/skills/venice_audio/venice_audio.py +38 -21
- intentkit/skills/venice_image/__init__.py +147 -154
- intentkit/skills/venice_image/api.py +138 -138
- intentkit/skills/venice_image/base.py +185 -192
- intentkit/skills/venice_image/config.py +33 -35
- intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
- intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
- intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
- intentkit/skills/venice_image/image_generation/image_generation_base.py +11 -10
- intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
- intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
- intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
- intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
- intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
- intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
- intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
- intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
- intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
- intentkit/skills/venice_image/schema.json +267 -267
- intentkit/skills/venice_image/utils.py +77 -78
- intentkit/skills/web_scraper/__init__.py +5 -18
- intentkit/skills/web_scraper/base.py +21 -7
- intentkit/skills/web_scraper/document_indexer.py +7 -6
- intentkit/skills/web_scraper/schema.json +2 -6
- intentkit/skills/web_scraper/scrape_and_index.py +15 -15
- intentkit/skills/web_scraper/utils.py +62 -63
- intentkit/skills/web_scraper/website_indexer.py +17 -19
- intentkit/skills/weth/__init__.py +49 -0
- intentkit/skills/weth/base.py +11 -0
- intentkit/skills/weth/schema.json +58 -0
- intentkit/skills/weth/weth.svg +6 -0
- intentkit/skills/wow/__init__.py +51 -0
- intentkit/skills/wow/base.py +11 -0
- intentkit/skills/wow/schema.json +89 -0
- intentkit/skills/wow/wow.svg +7 -0
- intentkit/skills/x402/__init__.py +58 -0
- intentkit/skills/x402/base.py +99 -0
- intentkit/skills/x402/http_request.py +117 -0
- intentkit/skills/x402/schema.json +40 -0
- intentkit/skills/x402/x402.webp +0 -0
- intentkit/skills/xmtp/__init__.py +4 -15
- intentkit/skills/xmtp/base.py +5 -5
- intentkit/skills/xmtp/price.py +7 -6
- intentkit/skills/xmtp/schema.json +69 -71
- intentkit/skills/xmtp/swap.py +6 -8
- intentkit/skills/xmtp/transfer.py +4 -6
- intentkit/utils/__init__.py +4 -0
- intentkit/utils/chain.py +198 -96
- intentkit/utils/ens.py +135 -0
- intentkit/utils/error.py +5 -2
- intentkit/utils/logging.py +9 -11
- intentkit/utils/schema.py +100 -0
- intentkit/utils/slack_alert.py +8 -8
- intentkit/utils/tx.py +16 -8
- intentkit/uv.lock +3377 -0
- {intentkit-0.7.5.dev3.dist-info → intentkit-0.8.34.dev7.dist-info}/METADATA +13 -15
- intentkit-0.8.34.dev7.dist-info/RECORD +478 -0
- intentkit-0.8.34.dev7.dist-info/licenses/LICENSE +21 -0
- intentkit/core/node.py +0 -215
- intentkit/models/conversation.py +0 -286
- intentkit/models/generator.py +0 -347
- intentkit/skills/cdp/get_balance.py +0 -110
- intentkit/skills/cdp/swap.py +0 -121
- intentkit/skills/moralis/tests/__init__.py +0 -0
- intentkit/skills/moralis/tests/test_wallet.py +0 -511
- intentkit-0.7.5.dev3.dist-info/RECORD +0 -424
- {intentkit-0.7.5.dev3.dist-info/licenses → intentkit}/LICENSE +0 -0
- {intentkit-0.7.5.dev3.dist-info → intentkit-0.8.34.dev7.dist-info}/WHEEL +0 -0
|
@@ -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.clients.s3 import store_image_bytes
|
|
11
|
+
from intentkit.skills.openai.base import OpenAIBaseTool
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
AVATAR_PROMPT_PREFIX = (
|
|
16
|
+
"Create an image suitable for a profile picture, with a clean background but not pure white, "
|
|
17
|
+
"and a clear subject that is recognizable even at small sizes. If there are no style requirements "
|
|
18
|
+
"in the subsequent description, use anime style. The content is as follows:"
|
|
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: type[BaseModel] = 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,14 +2,14 @@
|
|
|
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
|
|
9
9
|
from pydantic import BaseModel, Field
|
|
10
10
|
|
|
11
|
+
from intentkit.clients.s3 import store_image_bytes
|
|
11
12
|
from intentkit.skills.openai.base import OpenAIBaseTool
|
|
12
|
-
from intentkit.utils.s3 import store_image_bytes
|
|
13
13
|
|
|
14
14
|
logger = logging.getLogger(__name__)
|
|
15
15
|
|
|
@@ -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,92 @@
|
|
|
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
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
from intentkit.clients.s3 import store_image_bytes
|
|
12
|
+
from intentkit.skills.openai.base import OpenAIBaseTool
|
|
13
|
+
from intentkit.skills.openai.gpt_image_generation import GPTImageGenerationInput
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class GPTImageMiniGenerator(OpenAIBaseTool):
|
|
19
|
+
"""Tool for generating images using OpenAI's GPT-Image-1-Mini model."""
|
|
20
|
+
|
|
21
|
+
name: str = "gpt_image_mini_generator"
|
|
22
|
+
description: str = (
|
|
23
|
+
"Generate images using OpenAI's GPT-Image-1-Mini model.\n"
|
|
24
|
+
"Provide a text prompt describing the image you want to generate.\n"
|
|
25
|
+
"GPT-Image-1-Mini delivers high-quality images with faster performance at a lower cost.\n"
|
|
26
|
+
"You can specify size, quality, and background parameters for more control.\n"
|
|
27
|
+
)
|
|
28
|
+
args_schema: type[BaseModel] = GPTImageGenerationInput
|
|
29
|
+
|
|
30
|
+
async def _arun(
|
|
31
|
+
self,
|
|
32
|
+
prompt: str,
|
|
33
|
+
size: Literal["1024x1024", "1536x1024", "1024x1536", "auto"] = "auto",
|
|
34
|
+
quality: Literal["high", "medium", "low", "auto"] = "auto",
|
|
35
|
+
background: Literal["transparent", "opaque", "auto"] = "auto",
|
|
36
|
+
**kwargs,
|
|
37
|
+
) -> str:
|
|
38
|
+
"""Generate images using OpenAI's GPT-Image-1-Mini model."""
|
|
39
|
+
context = self.get_context()
|
|
40
|
+
api_key = self.get_api_key()
|
|
41
|
+
job_id = str(XID())
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
client = openai.OpenAI(api_key=api_key)
|
|
45
|
+
|
|
46
|
+
content_type = "image/png" if background == "transparent" else "image/jpeg"
|
|
47
|
+
|
|
48
|
+
response = client.images.generate(
|
|
49
|
+
model="gpt-image-1-mini",
|
|
50
|
+
prompt=prompt,
|
|
51
|
+
size=size,
|
|
52
|
+
quality=quality,
|
|
53
|
+
background=background,
|
|
54
|
+
moderation="low",
|
|
55
|
+
n=1,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
base64_image = response.data[0].b64_json
|
|
59
|
+
|
|
60
|
+
if hasattr(response, "usage") and response.usage:
|
|
61
|
+
usage = response.usage
|
|
62
|
+
logger.info(
|
|
63
|
+
"GPT-Image-1-Mini generation usage: "
|
|
64
|
+
f"input_tokens={usage.input_tokens}, "
|
|
65
|
+
f"output_tokens={usage.output_tokens}, "
|
|
66
|
+
f"total_tokens={usage.total_tokens}"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
if (
|
|
70
|
+
hasattr(usage, "input_tokens_details")
|
|
71
|
+
and usage.input_tokens_details
|
|
72
|
+
):
|
|
73
|
+
details = usage.input_tokens_details
|
|
74
|
+
logger.info(f"Input tokens details: {details}")
|
|
75
|
+
|
|
76
|
+
image_bytes = base64.b64decode(base64_image)
|
|
77
|
+
|
|
78
|
+
image_key = f"{context.agent_id}/gpt-image-mini/{job_id}"
|
|
79
|
+
|
|
80
|
+
stored_url = await store_image_bytes(image_bytes, image_key, content_type)
|
|
81
|
+
|
|
82
|
+
return stored_url
|
|
83
|
+
|
|
84
|
+
except openai.OpenAIError as e:
|
|
85
|
+
error_message = f"OpenAI API error: {str(e)}"
|
|
86
|
+
logger.error(error_message)
|
|
87
|
+
raise Exception(error_message)
|
|
88
|
+
|
|
89
|
+
except Exception as e:
|
|
90
|
+
error_message = f"Error generating image with GPT-Image-1-Mini: {str(e)}"
|
|
91
|
+
logger.error(error_message)
|
|
92
|
+
raise Exception(error_message)
|
|
@@ -3,15 +3,15 @@
|
|
|
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
|
|
10
10
|
from epyxid import XID
|
|
11
11
|
from pydantic import BaseModel, Field
|
|
12
12
|
|
|
13
|
+
from intentkit.clients.s3 import store_image_bytes
|
|
13
14
|
from intentkit.skills.openai.base import OpenAIBaseTool
|
|
14
|
-
from intentkit.utils.s3 import store_image_bytes
|
|
15
15
|
|
|
16
16
|
logger = logging.getLogger(__name__)
|
|
17
17
|
|
|
@@ -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:
|
|
@@ -6,15 +6,14 @@
|
|
|
6
6
|
"x-icon": "https://ai.service.crestal.dev/skills/openai/openai.png",
|
|
7
7
|
"x-tags": [
|
|
8
8
|
"AI",
|
|
9
|
-
"Image
|
|
10
|
-
"Image Analysis"
|
|
9
|
+
"Image"
|
|
11
10
|
],
|
|
12
11
|
"properties": {
|
|
13
12
|
"enabled": {
|
|
14
13
|
"type": "boolean",
|
|
15
14
|
"title": "Enabled",
|
|
16
15
|
"description": "Whether this skill is enabled",
|
|
17
|
-
"default":
|
|
16
|
+
"default": false
|
|
18
17
|
},
|
|
19
18
|
"states": {
|
|
20
19
|
"type": "object",
|
|
@@ -67,6 +66,38 @@
|
|
|
67
66
|
"description": "Generate images using OpenAI's GPT-Image-1 model based on text prompts",
|
|
68
67
|
"default": "private"
|
|
69
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
|
+
},
|
|
70
101
|
"gpt_image_to_image": {
|
|
71
102
|
"type": "string",
|
|
72
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."""
|
|
@@ -5,18 +5,16 @@
|
|
|
5
5
|
"description": "Access blockchain wallet data and analytics through Moralis APIs for portfolio tracking, token balances, and investment performance",
|
|
6
6
|
"x-icon": "https://ai.service.crestal.dev/skills/portfolio/moralis.png",
|
|
7
7
|
"x-tags": [
|
|
8
|
-
"
|
|
9
|
-
"Web3",
|
|
8
|
+
"Analytics",
|
|
10
9
|
"Crypto",
|
|
11
|
-
"
|
|
12
|
-
"Wallet"
|
|
10
|
+
"DeFi"
|
|
13
11
|
],
|
|
14
12
|
"properties": {
|
|
15
13
|
"enabled": {
|
|
16
14
|
"type": "boolean",
|
|
17
15
|
"title": "Enabled",
|
|
18
16
|
"description": "Whether this skill is enabled",
|
|
19
|
-
"default":
|
|
17
|
+
"default": false
|
|
20
18
|
},
|
|
21
19
|
"states": {
|
|
22
20
|
"type": "object",
|