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
intentkit/core/node.py
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any, Sequence
|
|
3
|
+
|
|
4
|
+
from langchain_core.language_models import LanguageModelLike
|
|
5
|
+
from langchain_core.messages import (
|
|
6
|
+
AIMessage,
|
|
7
|
+
AnyMessage,
|
|
8
|
+
BaseMessage,
|
|
9
|
+
HumanMessage,
|
|
10
|
+
RemoveMessage,
|
|
11
|
+
ToolMessage,
|
|
12
|
+
)
|
|
13
|
+
from langchain_core.messages.utils import count_tokens_approximately, trim_messages
|
|
14
|
+
from langchain_core.runnables import RunnableConfig
|
|
15
|
+
from langgraph.graph.message import REMOVE_ALL_MESSAGES
|
|
16
|
+
from langgraph.utils.runnable import RunnableCallable
|
|
17
|
+
from langmem.short_term.summarization import (
|
|
18
|
+
DEFAULT_EXISTING_SUMMARY_PROMPT,
|
|
19
|
+
DEFAULT_FINAL_SUMMARY_PROMPT,
|
|
20
|
+
DEFAULT_INITIAL_SUMMARY_PROMPT,
|
|
21
|
+
SummarizationResult,
|
|
22
|
+
asummarize_messages,
|
|
23
|
+
)
|
|
24
|
+
from pydantic import BaseModel
|
|
25
|
+
|
|
26
|
+
from intentkit.abstracts.graph import AgentError, AgentState
|
|
27
|
+
from intentkit.core.credit import skill_cost
|
|
28
|
+
from intentkit.models.credit import CreditAccount, OwnerType
|
|
29
|
+
from intentkit.models.skill import Skill
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger(__name__)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _validate_chat_history(
|
|
35
|
+
messages: Sequence[BaseMessage],
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Validate that all tool calls in AIMessages have a corresponding ToolMessage."""
|
|
38
|
+
all_tool_calls = [
|
|
39
|
+
tool_call
|
|
40
|
+
for message in messages
|
|
41
|
+
if isinstance(message, AIMessage)
|
|
42
|
+
for tool_call in message.tool_calls
|
|
43
|
+
]
|
|
44
|
+
tool_call_ids_with_results = {
|
|
45
|
+
message.tool_call_id for message in messages if isinstance(message, ToolMessage)
|
|
46
|
+
}
|
|
47
|
+
tool_calls_without_results = [
|
|
48
|
+
tool_call
|
|
49
|
+
for tool_call in all_tool_calls
|
|
50
|
+
if tool_call["id"] not in tool_call_ids_with_results
|
|
51
|
+
]
|
|
52
|
+
if not tool_calls_without_results:
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
message = "Found AIMessages with tool_calls that do not have a corresponding ToolMessage. "
|
|
56
|
+
f"Here are the first few of those tool calls: {tool_calls_without_results[:3]}"
|
|
57
|
+
raise ValueError(message)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class PreModelNode(RunnableCallable):
|
|
61
|
+
"""LangGraph node that run before the LLM is called."""
|
|
62
|
+
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
65
|
+
*,
|
|
66
|
+
model: LanguageModelLike,
|
|
67
|
+
short_term_memory_strategy: str,
|
|
68
|
+
max_tokens: int,
|
|
69
|
+
max_summary_tokens: int = 1024,
|
|
70
|
+
) -> None:
|
|
71
|
+
super().__init__(self._func, self._afunc, name="pre_model_node", trace=False)
|
|
72
|
+
self.model = model
|
|
73
|
+
self.short_term_memory_strategy = short_term_memory_strategy
|
|
74
|
+
self.max_tokens = max_tokens
|
|
75
|
+
self.max_tokens_before_summary = max_tokens
|
|
76
|
+
self.max_summary_tokens = max_summary_tokens
|
|
77
|
+
self.token_counter = count_tokens_approximately
|
|
78
|
+
self.initial_summary_prompt = DEFAULT_INITIAL_SUMMARY_PROMPT
|
|
79
|
+
self.existing_summary_prompt = DEFAULT_EXISTING_SUMMARY_PROMPT
|
|
80
|
+
self.final_prompt = DEFAULT_FINAL_SUMMARY_PROMPT
|
|
81
|
+
self.func_accepts_config = True
|
|
82
|
+
|
|
83
|
+
def _parse_input(
|
|
84
|
+
self, input: AgentState
|
|
85
|
+
) -> tuple[list[AnyMessage], dict[str, Any]]:
|
|
86
|
+
messages = input.get("messages")
|
|
87
|
+
context = input.get("context", {})
|
|
88
|
+
if messages is None or not isinstance(messages, list) or len(messages) == 0:
|
|
89
|
+
raise ValueError("Missing required field `messages` in the input.")
|
|
90
|
+
return messages, context
|
|
91
|
+
|
|
92
|
+
# overwrite old messages if summarization is used
|
|
93
|
+
def _prepare_state_update(
|
|
94
|
+
self, context: dict[str, Any], summarization_result: SummarizationResult
|
|
95
|
+
) -> dict[str, Any]:
|
|
96
|
+
state_update = {
|
|
97
|
+
"messages": [RemoveMessage(REMOVE_ALL_MESSAGES)]
|
|
98
|
+
+ summarization_result.messages
|
|
99
|
+
}
|
|
100
|
+
if summarization_result.running_summary:
|
|
101
|
+
state_update["context"] = {
|
|
102
|
+
**context,
|
|
103
|
+
"running_summary": summarization_result.running_summary,
|
|
104
|
+
}
|
|
105
|
+
return state_update
|
|
106
|
+
|
|
107
|
+
def _func(self, AgentState) -> dict[str, Any]:
|
|
108
|
+
raise NotImplementedError("Not implemented yet")
|
|
109
|
+
|
|
110
|
+
async def _afunc(
|
|
111
|
+
self,
|
|
112
|
+
input: AgentState,
|
|
113
|
+
config: RunnableConfig,
|
|
114
|
+
) -> dict[str, Any]:
|
|
115
|
+
messages, context = self._parse_input(input)
|
|
116
|
+
try:
|
|
117
|
+
_validate_chat_history(messages)
|
|
118
|
+
except ValueError as e:
|
|
119
|
+
logger.error(f"Invalid chat history: {e}")
|
|
120
|
+
logger.info(input)
|
|
121
|
+
# delete all messages
|
|
122
|
+
return {"messages": [RemoveMessage(REMOVE_ALL_MESSAGES)]}
|
|
123
|
+
if self.short_term_memory_strategy == "trim":
|
|
124
|
+
trimmed_messages = trim_messages(
|
|
125
|
+
messages,
|
|
126
|
+
strategy="last",
|
|
127
|
+
token_counter=self.token_counter,
|
|
128
|
+
max_tokens=self.max_summary_tokens,
|
|
129
|
+
start_on="human",
|
|
130
|
+
end_on=("human", "tool"),
|
|
131
|
+
)
|
|
132
|
+
if len(trimmed_messages) < len(messages):
|
|
133
|
+
logger.info(
|
|
134
|
+
f"Trimmed messages: {len(messages)} -> {len(trimmed_messages)}"
|
|
135
|
+
)
|
|
136
|
+
if len(trimmed_messages) <= 3:
|
|
137
|
+
logger.error(
|
|
138
|
+
f"Too few messages after trim: {len(trimmed_messages)}"
|
|
139
|
+
)
|
|
140
|
+
return {}
|
|
141
|
+
return {
|
|
142
|
+
"messages": [RemoveMessage(REMOVE_ALL_MESSAGES)] + trimmed_messages,
|
|
143
|
+
}
|
|
144
|
+
if self.short_term_memory_strategy == "summarize":
|
|
145
|
+
# if last message is not human message, skip summarize
|
|
146
|
+
if not isinstance(messages[-1], HumanMessage):
|
|
147
|
+
return {}
|
|
148
|
+
# summarization is from outside, sometimes it is not stable, so we need to try-catch it
|
|
149
|
+
try:
|
|
150
|
+
summarization_result = await asummarize_messages(
|
|
151
|
+
messages,
|
|
152
|
+
running_summary=context.get("running_summary"),
|
|
153
|
+
model=self.model,
|
|
154
|
+
max_tokens=self.max_tokens,
|
|
155
|
+
max_tokens_before_summary=self.max_tokens_before_summary,
|
|
156
|
+
max_summary_tokens=self.max_summary_tokens,
|
|
157
|
+
token_counter=self.token_counter,
|
|
158
|
+
initial_summary_prompt=self.initial_summary_prompt,
|
|
159
|
+
existing_summary_prompt=self.existing_summary_prompt,
|
|
160
|
+
final_prompt=self.final_prompt,
|
|
161
|
+
)
|
|
162
|
+
if summarization_result.running_summary:
|
|
163
|
+
logger.debug(f"Summarization result: {summarization_result}")
|
|
164
|
+
else:
|
|
165
|
+
logger.debug("Summarization not run")
|
|
166
|
+
return self._prepare_state_update(context, summarization_result)
|
|
167
|
+
except ValueError as e:
|
|
168
|
+
logger.error(f"Invalid chat history: {e}")
|
|
169
|
+
logger.info(input)
|
|
170
|
+
# delete all messages
|
|
171
|
+
return {"messages": [RemoveMessage(REMOVE_ALL_MESSAGES)]}
|
|
172
|
+
raise ValueError(
|
|
173
|
+
f"Invalid short_term_memory_strategy: {self.short_term_memory_strategy}"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class PostModelNode(RunnableCallable):
|
|
178
|
+
def __init__(self) -> None:
|
|
179
|
+
super().__init__(self._func, self._afunc, name="post_model_node", trace=False)
|
|
180
|
+
self.func_accepts_config = True
|
|
181
|
+
|
|
182
|
+
def _func(self, input: dict[str, Any] | BaseModel) -> dict[str, Any]:
|
|
183
|
+
raise NotImplementedError("Not implemented yet")
|
|
184
|
+
|
|
185
|
+
async def _afunc(
|
|
186
|
+
self,
|
|
187
|
+
input: AgentState,
|
|
188
|
+
config: RunnableConfig,
|
|
189
|
+
) -> dict[str, Any]:
|
|
190
|
+
logger.debug(f"Running PostModelNode, input: {input}, config: {config}")
|
|
191
|
+
state_update = {}
|
|
192
|
+
messages = input.get("messages")
|
|
193
|
+
if messages is None or not isinstance(messages, list) or len(messages) == 0:
|
|
194
|
+
raise ValueError("Missing required field `messages` in the input.")
|
|
195
|
+
cfg = config.get("configurable")
|
|
196
|
+
if not config:
|
|
197
|
+
raise ValueError("Missing required field `configurable` in the config.")
|
|
198
|
+
payer = cfg.get("payer")
|
|
199
|
+
if not payer:
|
|
200
|
+
return state_update
|
|
201
|
+
logger.debug(f"last: {messages[-1]}")
|
|
202
|
+
msg = messages[-1]
|
|
203
|
+
agent = cfg.get("agent")
|
|
204
|
+
account = await CreditAccount.get_or_create(OwnerType.USER, payer)
|
|
205
|
+
if hasattr(msg, "tool_calls") and msg.tool_calls:
|
|
206
|
+
for tool_call in msg.tool_calls:
|
|
207
|
+
skill_meta = await Skill.get(tool_call.get("name"))
|
|
208
|
+
if skill_meta:
|
|
209
|
+
skill_cost_info = await skill_cost(skill_meta.name, payer, agent)
|
|
210
|
+
total_paid = skill_cost_info.total_amount
|
|
211
|
+
if not account.has_sufficient_credits(total_paid):
|
|
212
|
+
state_update["error"] = AgentError.INSUFFICIENT_CREDITS
|
|
213
|
+
state_update["messages"] = [RemoveMessage(id=msg.id)]
|
|
214
|
+
state_update["messages"].append(
|
|
215
|
+
AIMessage(
|
|
216
|
+
content=f"Insufficient credits. Please top up your account. You need {total_paid} credits, but you only have {account.balance} credits.",
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
return state_update
|
|
220
|
+
return state_update
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
post_model_node = PostModelNode()
|
intentkit/core/prompt.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from intentkit.config.config import config
|
|
4
|
+
from intentkit.models.agent import Agent
|
|
5
|
+
from intentkit.models.agent_data import AgentData
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def agent_prompt(agent: Agent, agent_data: AgentData) -> str:
|
|
9
|
+
prompt = "# SYSTEM PROMPT\n\n"
|
|
10
|
+
if config.system_prompt:
|
|
11
|
+
prompt += config.system_prompt + "\n\n"
|
|
12
|
+
prompt += "You are an AI agent built using IntentKit.\n"
|
|
13
|
+
prompt += "Your tools are called 'skills'.\n"
|
|
14
|
+
prompt += "If your skill fails to execute due to a technical error ask the user to try again later, don't retry by yourself. If someone asks you to do something you can't do with your currently available skills, you must say so, recommend them to submit their feedback to the IntentKit team at https://github.com/crestalnetwork/intentkit. Be concise and helpful with your responses.\n"
|
|
15
|
+
if agent.name:
|
|
16
|
+
prompt += f"Your name is {agent.name}.\n"
|
|
17
|
+
if agent.ticker:
|
|
18
|
+
prompt += f"Your ticker symbol is {agent.ticker}.\n"
|
|
19
|
+
if agent_data:
|
|
20
|
+
if agent_data.twitter_id:
|
|
21
|
+
prompt += f"Your twitter id is {agent_data.twitter_id}, never reply or retweet yourself.\n"
|
|
22
|
+
if agent_data.twitter_username:
|
|
23
|
+
prompt += f"Your twitter username is {agent_data.twitter_username}.\n"
|
|
24
|
+
if agent_data.twitter_name:
|
|
25
|
+
prompt += f"Your twitter name is {agent_data.twitter_name}.\n"
|
|
26
|
+
if agent_data.twitter_is_verified:
|
|
27
|
+
prompt += "Your twitter account is verified.\n"
|
|
28
|
+
else:
|
|
29
|
+
prompt += "Your twitter account is not verified.\n"
|
|
30
|
+
if agent_data.telegram_id:
|
|
31
|
+
prompt += f"Your telegram bot id is {agent_data.telegram_id}.\n"
|
|
32
|
+
if agent_data.telegram_username:
|
|
33
|
+
prompt += f"Your telegram bot username is {agent_data.telegram_username}.\n"
|
|
34
|
+
if agent_data.telegram_name:
|
|
35
|
+
prompt += f"Your telegram bot name is {agent_data.telegram_name}.\n"
|
|
36
|
+
# CDP
|
|
37
|
+
if agent_data.cdp_wallet_data:
|
|
38
|
+
network_id = agent.network_id or agent.cdp_network_id
|
|
39
|
+
wallet_data = json.loads(agent_data.cdp_wallet_data)
|
|
40
|
+
prompt += f"Your wallet address in {network_id} is {wallet_data['default_address_id']} .\n"
|
|
41
|
+
prompt += "\n"
|
|
42
|
+
if agent.purpose:
|
|
43
|
+
prompt += f"## Purpose\n\n{agent.purpose}\n\n"
|
|
44
|
+
if agent.personality:
|
|
45
|
+
prompt += f"## Personality\n\n{agent.personality}\n\n"
|
|
46
|
+
if agent.principles:
|
|
47
|
+
prompt += f"## Principles\n\n{agent.principles}\n\n"
|
|
48
|
+
if agent.prompt:
|
|
49
|
+
prompt += f"## Initial Rules\n\n{agent.prompt}\n\n"
|
|
50
|
+
if agent.skills and "enso" in agent.skills and agent.skills["enso"].get("enabled"):
|
|
51
|
+
prompt += """## ENSO Skills Guide\n\nYou are integrated with the Enso API. You can use enso_get_tokens to retrieve token information,
|
|
52
|
+
including APY, Protocol Slug, Symbol, Address, Decimals, and underlying tokens. When interacting with token amounts,
|
|
53
|
+
ensure to multiply input amounts by the token's decimal places and divide output amounts by the token's decimals.
|
|
54
|
+
Utilize enso_route_shortcut to find the best swap or deposit route. Set broadcast_request to True only when the
|
|
55
|
+
user explicitly requests a transaction broadcast. Insufficient funds or insufficient spending approval can cause
|
|
56
|
+
Route Shortcut broadcasts to fail. To avoid this, use the enso_broadcast_wallet_approve tool that requires explicit
|
|
57
|
+
user confirmation before broadcasting any approval transactions for security reasons.\n\n"""
|
|
58
|
+
return prompt
|
intentkit/core/skill.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional
|
|
2
|
+
|
|
3
|
+
from intentkit.abstracts.skill import SkillStoreABC
|
|
4
|
+
from intentkit.config.config import config
|
|
5
|
+
from intentkit.models.agent import Agent
|
|
6
|
+
from intentkit.models.agent_data import AgentData, AgentQuota
|
|
7
|
+
from intentkit.models.skill import (
|
|
8
|
+
AgentSkillData,
|
|
9
|
+
AgentSkillDataCreate,
|
|
10
|
+
ThreadSkillData,
|
|
11
|
+
ThreadSkillDataCreate,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SkillStore(SkillStoreABC):
|
|
16
|
+
"""Implementation of skill data storage operations.
|
|
17
|
+
|
|
18
|
+
This class provides concrete implementations for storing and retrieving
|
|
19
|
+
skill-related data for both agents and threads.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def get_system_config(key: str) -> Any:
|
|
24
|
+
# TODO: maybe need a whitelist here
|
|
25
|
+
if hasattr(config, key):
|
|
26
|
+
return getattr(config, key)
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
async def get_agent_config(agent_id: str) -> Optional[Agent]:
|
|
31
|
+
return await Agent.get(agent_id)
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
async def get_agent_data(agent_id: str) -> Optional[AgentData]:
|
|
35
|
+
return await AgentData.get(agent_id)
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
async def set_agent_data(agent_id: str, data: Dict) -> None:
|
|
39
|
+
return await AgentData.patch(agent_id, data)
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
async def get_agent_quota(agent_id: str) -> Optional[AgentQuota]:
|
|
43
|
+
return await AgentQuota.get(agent_id)
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
async def get_agent_skill_data(
|
|
47
|
+
agent_id: str, skill: str, key: str
|
|
48
|
+
) -> Optional[Dict[str, Any]]:
|
|
49
|
+
"""Get skill data for an agent.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
agent_id: ID of the agent
|
|
53
|
+
skill: Name of the skill
|
|
54
|
+
key: Data key
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Dictionary containing the skill data if found, None otherwise
|
|
58
|
+
"""
|
|
59
|
+
return await AgentSkillData.get(agent_id, skill, key)
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
async def save_agent_skill_data(
|
|
63
|
+
agent_id: str, skill: str, key: str, data: Dict[str, Any]
|
|
64
|
+
) -> None:
|
|
65
|
+
"""Save or update skill data for an agent.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
agent_id: ID of the agent
|
|
69
|
+
skill: Name of the skill
|
|
70
|
+
key: Data key
|
|
71
|
+
data: JSON data to store
|
|
72
|
+
"""
|
|
73
|
+
skill_data = AgentSkillDataCreate(
|
|
74
|
+
agent_id=agent_id,
|
|
75
|
+
skill=skill,
|
|
76
|
+
key=key,
|
|
77
|
+
data=data,
|
|
78
|
+
)
|
|
79
|
+
await skill_data.save()
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
async def get_thread_skill_data(
|
|
83
|
+
thread_id: str, skill: str, key: str
|
|
84
|
+
) -> Optional[Dict[str, Any]]:
|
|
85
|
+
"""Get skill data for a thread.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
thread_id: ID of the thread
|
|
89
|
+
skill: Name of the skill
|
|
90
|
+
key: Data key
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Dictionary containing the skill data if found, None otherwise
|
|
94
|
+
"""
|
|
95
|
+
return await ThreadSkillData.get(thread_id, skill, key)
|
|
96
|
+
|
|
97
|
+
@staticmethod
|
|
98
|
+
async def save_thread_skill_data(
|
|
99
|
+
thread_id: str,
|
|
100
|
+
agent_id: str,
|
|
101
|
+
skill: str,
|
|
102
|
+
key: str,
|
|
103
|
+
data: Dict[str, Any],
|
|
104
|
+
) -> None:
|
|
105
|
+
"""Save or update skill data for a thread.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
thread_id: ID of the thread
|
|
109
|
+
agent_id: ID of the agent that owns this thread
|
|
110
|
+
skill: Name of the skill
|
|
111
|
+
key: Data key
|
|
112
|
+
data: JSON data to store
|
|
113
|
+
"""
|
|
114
|
+
skill_data = ThreadSkillDataCreate(
|
|
115
|
+
thread_id=thread_id,
|
|
116
|
+
agent_id=agent_id,
|
|
117
|
+
skill=skill,
|
|
118
|
+
key=key,
|
|
119
|
+
data=data,
|
|
120
|
+
)
|
|
121
|
+
await skill_data.save()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
skill_store = SkillStore()
|