intentkit 0.6.13.dev2__py3-none-any.whl → 0.8.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of intentkit might be problematic. Click here for more details.
- intentkit/__init__.py +1 -1
- intentkit/abstracts/agent.py +4 -5
- intentkit/abstracts/engine.py +5 -5
- intentkit/abstracts/graph.py +14 -7
- intentkit/abstracts/skill.py +6 -144
- intentkit/abstracts/twitter.py +4 -5
- intentkit/clients/__init__.py +5 -2
- intentkit/clients/cdp.py +101 -141
- intentkit/clients/twitter.py +83 -62
- intentkit/clients/web3.py +29 -0
- intentkit/config/config.py +8 -5
- intentkit/core/agent.py +472 -195
- intentkit/core/asset.py +253 -0
- intentkit/core/chat.py +51 -0
- intentkit/core/client.py +1 -1
- intentkit/core/credit.py +460 -130
- intentkit/core/engine.py +262 -233
- intentkit/core/node.py +15 -16
- intentkit/core/prompt.py +62 -28
- intentkit/core/scheduler.py +92 -0
- intentkit/core/statistics.py +168 -0
- intentkit/models/agent.py +1096 -949
- intentkit/models/agent_data.py +68 -38
- intentkit/models/agent_public.json +98 -0
- intentkit/models/agent_schema.json +54 -439
- intentkit/models/app_setting.py +96 -33
- intentkit/models/chat.py +74 -27
- intentkit/models/conversation.py +8 -8
- intentkit/models/credit.py +362 -74
- intentkit/models/db.py +26 -8
- intentkit/models/db_mig.py +2 -2
- intentkit/models/llm.csv +28 -0
- intentkit/models/llm.py +185 -350
- intentkit/models/redis.py +6 -4
- intentkit/models/skill.py +186 -72
- intentkit/models/skills.csv +174 -0
- intentkit/models/user.py +82 -24
- intentkit/skills/acolyt/__init__.py +2 -9
- intentkit/skills/acolyt/ask.py +3 -4
- intentkit/skills/acolyt/base.py +4 -9
- intentkit/skills/acolyt/schema.json +4 -3
- intentkit/skills/aixbt/__init__.py +2 -13
- intentkit/skills/aixbt/base.py +1 -7
- intentkit/skills/aixbt/projects.py +14 -15
- intentkit/skills/aixbt/schema.json +4 -4
- intentkit/skills/allora/__init__.py +2 -9
- intentkit/skills/allora/base.py +4 -9
- intentkit/skills/allora/price.py +3 -4
- intentkit/skills/allora/schema.json +3 -2
- intentkit/skills/base.py +248 -85
- intentkit/skills/basename/__init__.py +51 -0
- intentkit/skills/basename/base.py +11 -0
- intentkit/skills/basename/basename.svg +11 -0
- intentkit/skills/basename/schema.json +58 -0
- intentkit/skills/carv/__init__.py +115 -121
- intentkit/skills/carv/base.py +184 -185
- intentkit/skills/carv/fetch_news.py +3 -3
- intentkit/skills/carv/onchain_query.py +4 -4
- intentkit/skills/carv/schema.json +134 -137
- intentkit/skills/carv/token_info_and_price.py +5 -5
- intentkit/skills/casino/README.md +254 -0
- intentkit/skills/casino/__init__.py +86 -0
- intentkit/skills/casino/base.py +17 -0
- intentkit/skills/casino/casino.png +0 -0
- intentkit/skills/casino/deck_draw.py +127 -0
- intentkit/skills/casino/deck_shuffle.py +118 -0
- intentkit/skills/casino/dice_roll.py +100 -0
- intentkit/skills/casino/schema.json +77 -0
- intentkit/skills/casino/utils.py +107 -0
- intentkit/skills/cdp/__init__.py +22 -84
- intentkit/skills/cdp/base.py +1 -7
- intentkit/skills/cdp/schema.json +11 -314
- intentkit/skills/chainlist/__init__.py +2 -7
- intentkit/skills/chainlist/base.py +1 -7
- intentkit/skills/chainlist/chain_lookup.py +18 -18
- intentkit/skills/chainlist/schema.json +3 -5
- intentkit/skills/common/__init__.py +2 -9
- intentkit/skills/common/base.py +1 -7
- intentkit/skills/common/current_time.py +1 -2
- intentkit/skills/common/schema.json +2 -2
- intentkit/skills/cookiefun/__init__.py +6 -9
- intentkit/skills/cookiefun/base.py +2 -7
- intentkit/skills/cookiefun/get_account_details.py +7 -7
- intentkit/skills/cookiefun/get_account_feed.py +19 -19
- intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
- intentkit/skills/cookiefun/get_sectors.py +3 -3
- intentkit/skills/cookiefun/schema.json +1 -3
- intentkit/skills/cookiefun/search_accounts.py +9 -9
- intentkit/skills/cryptocompare/__init__.py +7 -24
- intentkit/skills/cryptocompare/api.py +2 -3
- intentkit/skills/cryptocompare/base.py +11 -25
- intentkit/skills/cryptocompare/fetch_news.py +4 -5
- intentkit/skills/cryptocompare/fetch_price.py +6 -7
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
- intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
- intentkit/skills/cryptocompare/schema.json +3 -3
- intentkit/skills/cryptopanic/__init__.py +7 -10
- intentkit/skills/cryptopanic/base.py +51 -55
- intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
- intentkit/skills/cryptopanic/schema.json +105 -103
- intentkit/skills/dapplooker/__init__.py +2 -9
- intentkit/skills/dapplooker/base.py +4 -9
- intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
- intentkit/skills/dapplooker/schema.json +3 -5
- intentkit/skills/defillama/__init__.py +24 -74
- intentkit/skills/defillama/api.py +6 -9
- intentkit/skills/defillama/base.py +11 -21
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_block.py +6 -8
- intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
- intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
- intentkit/skills/defillama/config/chains.py +1 -3
- intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
- intentkit/skills/defillama/schema.json +5 -1
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
- intentkit/skills/defillama/tests/api_integration.test.py +1 -1
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
- intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
- intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
- intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
- intentkit/skills/defillama/yields/fetch_pools.py +26 -30
- intentkit/skills/dexscreener/README.md +154 -0
- intentkit/skills/dexscreener/__init__.py +97 -93
- intentkit/skills/dexscreener/base.py +125 -133
- intentkit/skills/dexscreener/get_pair_info.py +158 -0
- intentkit/skills/dexscreener/get_token_pairs.py +165 -0
- intentkit/skills/dexscreener/get_tokens_info.py +212 -0
- intentkit/skills/dexscreener/model/search_token_response.py +80 -82
- intentkit/skills/dexscreener/schema.json +91 -48
- intentkit/skills/dexscreener/search_token.py +182 -321
- intentkit/skills/dexscreener/utils.py +420 -0
- intentkit/skills/dune_analytics/__init__.py +7 -9
- intentkit/skills/dune_analytics/base.py +48 -52
- intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
- intentkit/skills/dune_analytics/schema.json +104 -99
- intentkit/skills/elfa/__init__.py +5 -18
- intentkit/skills/elfa/base.py +10 -14
- intentkit/skills/elfa/mention.py +19 -21
- intentkit/skills/elfa/schema.json +3 -2
- intentkit/skills/elfa/stats.py +4 -4
- intentkit/skills/elfa/tokens.py +12 -12
- intentkit/skills/elfa/utils.py +26 -28
- intentkit/skills/enso/__init__.py +11 -31
- intentkit/skills/enso/base.py +50 -35
- intentkit/skills/enso/best_yield.py +16 -24
- intentkit/skills/enso/networks.py +6 -11
- intentkit/skills/enso/prices.py +11 -13
- intentkit/skills/enso/route.py +34 -38
- intentkit/skills/enso/schema.json +3 -2
- intentkit/skills/enso/tokens.py +29 -38
- intentkit/skills/enso/wallet.py +76 -191
- intentkit/skills/erc20/__init__.py +50 -0
- intentkit/skills/erc20/base.py +11 -0
- intentkit/skills/erc20/erc20.svg +5 -0
- intentkit/skills/erc20/schema.json +74 -0
- intentkit/skills/erc721/__init__.py +53 -0
- intentkit/skills/erc721/base.py +11 -0
- intentkit/skills/erc721/erc721.svg +5 -0
- intentkit/skills/erc721/schema.json +90 -0
- intentkit/skills/firecrawl/README.md +11 -5
- intentkit/skills/firecrawl/__init__.py +5 -18
- intentkit/skills/firecrawl/base.py +4 -11
- intentkit/skills/firecrawl/clear.py +4 -8
- intentkit/skills/firecrawl/crawl.py +19 -19
- intentkit/skills/firecrawl/query.py +4 -3
- intentkit/skills/firecrawl/schema.json +6 -8
- intentkit/skills/firecrawl/scrape.py +150 -40
- intentkit/skills/firecrawl/utils.py +50 -42
- intentkit/skills/github/__init__.py +2 -7
- intentkit/skills/github/base.py +1 -7
- intentkit/skills/github/github_search.py +1 -2
- intentkit/skills/github/schema.json +3 -4
- intentkit/skills/heurist/__init__.py +8 -27
- intentkit/skills/heurist/base.py +4 -9
- intentkit/skills/heurist/image_generation_animagine_xl.py +12 -13
- intentkit/skills/heurist/image_generation_arthemy_comics.py +12 -13
- intentkit/skills/heurist/image_generation_arthemy_real.py +12 -13
- intentkit/skills/heurist/image_generation_braindance.py +12 -13
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +12 -13
- intentkit/skills/heurist/image_generation_flux_1_dev.py +12 -13
- intentkit/skills/heurist/image_generation_sdxl.py +12 -13
- intentkit/skills/heurist/schema.json +2 -2
- intentkit/skills/http/__init__.py +4 -15
- intentkit/skills/http/base.py +1 -7
- intentkit/skills/http/get.py +21 -16
- intentkit/skills/http/post.py +23 -18
- intentkit/skills/http/put.py +23 -18
- intentkit/skills/http/schema.json +4 -5
- intentkit/skills/lifi/__init__.py +8 -13
- intentkit/skills/lifi/base.py +1 -7
- intentkit/skills/lifi/schema.json +17 -8
- intentkit/skills/lifi/token_execute.py +36 -30
- intentkit/skills/lifi/token_quote.py +8 -10
- intentkit/skills/lifi/utils.py +104 -51
- intentkit/skills/moralis/__init__.py +6 -10
- intentkit/skills/moralis/api.py +6 -7
- intentkit/skills/moralis/base.py +5 -10
- intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
- intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
- intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
- intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
- intentkit/skills/moralis/schema.json +7 -2
- intentkit/skills/morpho/__init__.py +52 -0
- intentkit/skills/morpho/base.py +11 -0
- intentkit/skills/morpho/morpho.svg +12 -0
- intentkit/skills/morpho/schema.json +73 -0
- intentkit/skills/nation/__init__.py +4 -9
- intentkit/skills/nation/base.py +5 -10
- intentkit/skills/nation/nft_check.py +3 -4
- intentkit/skills/nation/schema.json +4 -3
- intentkit/skills/onchain.py +23 -0
- intentkit/skills/openai/__init__.py +17 -18
- intentkit/skills/openai/base.py +10 -14
- intentkit/skills/openai/dalle_image_generation.py +3 -8
- intentkit/skills/openai/gpt_avatar_generator.py +102 -0
- intentkit/skills/openai/gpt_image_generation.py +4 -8
- intentkit/skills/openai/gpt_image_mini_generator.py +91 -0
- intentkit/skills/openai/gpt_image_to_image.py +4 -8
- intentkit/skills/openai/image_to_text.py +3 -7
- intentkit/skills/openai/schema.json +34 -3
- intentkit/skills/portfolio/__init__.py +11 -35
- intentkit/skills/portfolio/base.py +33 -19
- intentkit/skills/portfolio/schema.json +3 -5
- intentkit/skills/portfolio/token_balances.py +21 -21
- intentkit/skills/portfolio/wallet_approvals.py +17 -18
- intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
- intentkit/skills/portfolio/wallet_history.py +31 -31
- intentkit/skills/portfolio/wallet_net_worth.py +13 -13
- intentkit/skills/portfolio/wallet_nfts.py +19 -19
- intentkit/skills/portfolio/wallet_profitability.py +18 -18
- intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
- intentkit/skills/portfolio/wallet_stats.py +3 -3
- intentkit/skills/portfolio/wallet_swaps.py +19 -19
- intentkit/skills/pyth/__init__.py +50 -0
- intentkit/skills/pyth/base.py +11 -0
- intentkit/skills/pyth/pyth.svg +6 -0
- intentkit/skills/pyth/schema.json +75 -0
- intentkit/skills/skills.toml +40 -0
- intentkit/skills/slack/__init__.py +5 -17
- intentkit/skills/slack/base.py +3 -9
- intentkit/skills/slack/get_channel.py +8 -8
- intentkit/skills/slack/get_message.py +9 -9
- intentkit/skills/slack/schedule_message.py +5 -5
- intentkit/skills/slack/schema.json +2 -2
- intentkit/skills/slack/send_message.py +3 -5
- intentkit/skills/supabase/__init__.py +7 -23
- intentkit/skills/supabase/base.py +9 -13
- intentkit/skills/supabase/delete_data.py +5 -6
- intentkit/skills/supabase/fetch_data.py +13 -14
- intentkit/skills/supabase/insert_data.py +5 -6
- intentkit/skills/supabase/invoke_function.py +7 -8
- intentkit/skills/supabase/schema.json +2 -3
- intentkit/skills/supabase/update_data.py +7 -8
- intentkit/skills/supabase/upsert_data.py +5 -6
- intentkit/skills/superfluid/__init__.py +53 -0
- intentkit/skills/superfluid/base.py +11 -0
- intentkit/skills/superfluid/schema.json +89 -0
- intentkit/skills/superfluid/superfluid.svg +6 -0
- intentkit/skills/system/__init__.py +7 -24
- intentkit/skills/system/add_autonomous_task.py +10 -12
- intentkit/skills/system/delete_autonomous_task.py +2 -2
- intentkit/skills/system/edit_autonomous_task.py +14 -18
- intentkit/skills/system/list_autonomous_tasks.py +3 -5
- intentkit/skills/system/read_agent_api_key.py +6 -4
- intentkit/skills/system/regenerate_agent_api_key.py +6 -4
- intentkit/skills/system/schema.json +6 -8
- intentkit/skills/tavily/__init__.py +3 -12
- intentkit/skills/tavily/base.py +4 -9
- intentkit/skills/tavily/schema.json +3 -5
- intentkit/skills/tavily/tavily_extract.py +2 -4
- intentkit/skills/tavily/tavily_search.py +4 -6
- intentkit/skills/token/__init__.py +5 -10
- intentkit/skills/token/base.py +7 -11
- intentkit/skills/token/erc20_transfers.py +19 -19
- intentkit/skills/token/schema.json +3 -6
- intentkit/skills/token/token_analytics.py +3 -3
- intentkit/skills/token/token_price.py +13 -13
- intentkit/skills/token/token_search.py +9 -9
- intentkit/skills/twitter/__init__.py +11 -35
- intentkit/skills/twitter/base.py +23 -35
- intentkit/skills/twitter/follow_user.py +3 -7
- intentkit/skills/twitter/get_mentions.py +6 -13
- intentkit/skills/twitter/get_timeline.py +5 -13
- intentkit/skills/twitter/get_user_by_username.py +3 -7
- intentkit/skills/twitter/get_user_tweets.py +6 -14
- intentkit/skills/twitter/like_tweet.py +3 -7
- intentkit/skills/twitter/post_tweet.py +23 -12
- intentkit/skills/twitter/reply_tweet.py +21 -12
- intentkit/skills/twitter/retweet.py +3 -7
- intentkit/skills/twitter/schema.json +1 -0
- intentkit/skills/twitter/search_tweets.py +5 -13
- intentkit/skills/unrealspeech/__init__.py +2 -7
- intentkit/skills/unrealspeech/base.py +2 -8
- intentkit/skills/unrealspeech/schema.json +2 -5
- intentkit/skills/unrealspeech/text_to_speech.py +8 -8
- intentkit/skills/venice_audio/__init__.py +98 -106
- intentkit/skills/venice_audio/base.py +117 -121
- intentkit/skills/venice_audio/input.py +41 -41
- intentkit/skills/venice_audio/schema.json +151 -152
- intentkit/skills/venice_audio/venice_audio.py +38 -21
- intentkit/skills/venice_image/__init__.py +147 -154
- intentkit/skills/venice_image/api.py +138 -138
- intentkit/skills/venice_image/base.py +185 -192
- intentkit/skills/venice_image/config.py +33 -35
- intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
- intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
- intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
- intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
- intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
- intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
- intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
- intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
- intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
- intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
- intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
- intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
- intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
- intentkit/skills/venice_image/schema.json +267 -267
- intentkit/skills/venice_image/utils.py +77 -78
- intentkit/skills/web_scraper/__init__.py +5 -18
- intentkit/skills/web_scraper/base.py +21 -7
- intentkit/skills/web_scraper/document_indexer.py +7 -6
- intentkit/skills/web_scraper/schema.json +2 -6
- intentkit/skills/web_scraper/scrape_and_index.py +15 -15
- intentkit/skills/web_scraper/utils.py +62 -63
- intentkit/skills/web_scraper/website_indexer.py +17 -19
- intentkit/skills/weth/__init__.py +49 -0
- intentkit/skills/weth/base.py +11 -0
- intentkit/skills/weth/schema.json +58 -0
- intentkit/skills/weth/weth.svg +6 -0
- intentkit/skills/wow/__init__.py +51 -0
- intentkit/skills/wow/base.py +11 -0
- intentkit/skills/wow/schema.json +89 -0
- intentkit/skills/wow/wow.svg +7 -0
- intentkit/skills/x402/__init__.py +61 -0
- intentkit/skills/x402/ask_agent.py +98 -0
- intentkit/skills/x402/base.py +99 -0
- intentkit/skills/x402/http_request.py +117 -0
- intentkit/skills/x402/schema.json +45 -0
- intentkit/skills/x402/x402.webp +0 -0
- intentkit/skills/xmtp/__init__.py +4 -15
- intentkit/skills/xmtp/base.py +61 -2
- intentkit/skills/xmtp/price.py +18 -13
- intentkit/skills/xmtp/schema.json +69 -71
- intentkit/skills/xmtp/swap.py +22 -25
- intentkit/skills/xmtp/transfer.py +71 -32
- intentkit/utils/chain.py +3 -3
- intentkit/utils/error.py +14 -1
- intentkit/utils/logging.py +2 -4
- intentkit/utils/s3.py +59 -7
- intentkit/utils/schema.py +100 -0
- intentkit/utils/slack_alert.py +7 -8
- {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +14 -16
- intentkit-0.8.17.dist-info/RECORD +466 -0
- intentkit/abstracts/exception.py +0 -9
- intentkit/core/skill.py +0 -200
- intentkit/models/generator.py +0 -347
- intentkit/skills/cdp/get_balance.py +0 -110
- intentkit/skills/cdp/swap.py +0 -121
- intentkit/skills/moralis/tests/__init__.py +0 -0
- intentkit/skills/moralis/tests/test_wallet.py +0 -511
- intentkit-0.6.13.dev2.dist-info/RECORD +0 -409
- {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
- {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
intentkit/core/engine.py
CHANGED
|
@@ -17,11 +17,10 @@ import textwrap
|
|
|
17
17
|
import time
|
|
18
18
|
import traceback
|
|
19
19
|
from datetime import datetime
|
|
20
|
-
from typing import Optional
|
|
21
20
|
|
|
22
21
|
import sqlalchemy
|
|
23
22
|
from epyxid import XID
|
|
24
|
-
from
|
|
23
|
+
from langchain_core.language_models import BaseChatModel
|
|
25
24
|
from langchain_core.messages import (
|
|
26
25
|
BaseMessage,
|
|
27
26
|
HumanMessage,
|
|
@@ -30,21 +29,22 @@ from langchain_core.tools import BaseTool
|
|
|
30
29
|
from langgraph.errors import GraphRecursionError
|
|
31
30
|
from langgraph.graph.state import CompiledStateGraph
|
|
32
31
|
from langgraph.prebuilt import create_react_agent
|
|
32
|
+
from langgraph.runtime import Runtime
|
|
33
33
|
from sqlalchemy import func, update
|
|
34
34
|
from sqlalchemy.exc import SQLAlchemyError
|
|
35
35
|
|
|
36
36
|
from intentkit.abstracts.graph import AgentContext, AgentError, AgentState
|
|
37
37
|
from intentkit.config.config import config
|
|
38
|
+
from intentkit.core.chat import clear_thread_memory
|
|
38
39
|
from intentkit.core.credit import expense_message, expense_skill
|
|
39
40
|
from intentkit.core.node import PreModelNode, post_model_node
|
|
40
41
|
from intentkit.core.prompt import (
|
|
41
42
|
create_formatted_prompt_function,
|
|
42
43
|
explain_prompt,
|
|
43
44
|
)
|
|
44
|
-
from intentkit.core.skill import skill_store
|
|
45
45
|
from intentkit.models.agent import Agent, AgentTable
|
|
46
46
|
from intentkit.models.agent_data import AgentData, AgentQuota
|
|
47
|
-
from intentkit.models.app_setting import AppSetting
|
|
47
|
+
from intentkit.models.app_setting import AppSetting, SystemMessageType
|
|
48
48
|
from intentkit.models.chat import (
|
|
49
49
|
AuthorType,
|
|
50
50
|
ChatMessage,
|
|
@@ -53,27 +53,24 @@ from intentkit.models.chat import (
|
|
|
53
53
|
)
|
|
54
54
|
from intentkit.models.credit import CreditAccount, OwnerType
|
|
55
55
|
from intentkit.models.db import get_langgraph_checkpointer, get_session
|
|
56
|
-
from intentkit.models.llm import LLMModelInfo, LLMProvider
|
|
57
|
-
from intentkit.models.skill import AgentSkillData,
|
|
56
|
+
from intentkit.models.llm import LLMModelInfo, LLMProvider, create_llm_model
|
|
57
|
+
from intentkit.models.skill import AgentSkillData, ChatSkillData, Skill
|
|
58
58
|
from intentkit.models.user import User
|
|
59
59
|
from intentkit.utils.error import IntentKitAPIError
|
|
60
60
|
|
|
61
61
|
logger = logging.getLogger(__name__)
|
|
62
62
|
|
|
63
|
-
|
|
64
63
|
# Global variable to cache all agent executors
|
|
65
64
|
_agents: dict[str, CompiledStateGraph] = {}
|
|
66
|
-
_private_agents: dict[str, CompiledStateGraph] = {}
|
|
67
65
|
|
|
68
66
|
# Global dictionaries to cache agent update times
|
|
69
67
|
_agents_updated: dict[str, datetime] = {}
|
|
70
|
-
_private_agents_updated: dict[str, datetime] = {}
|
|
71
68
|
|
|
72
69
|
|
|
73
|
-
async def
|
|
74
|
-
agent: Agent,
|
|
70
|
+
async def build_agent(
|
|
71
|
+
agent: Agent, agent_data: AgentData, custom_skills: list[BaseTool] = []
|
|
75
72
|
) -> CompiledStateGraph:
|
|
76
|
-
"""
|
|
73
|
+
"""Build an AI agent with specified configuration and tools.
|
|
77
74
|
|
|
78
75
|
This function:
|
|
79
76
|
1. Initializes LLM with specified model
|
|
@@ -83,16 +80,13 @@ async def create_agent(
|
|
|
83
80
|
|
|
84
81
|
Args:
|
|
85
82
|
agent (Agent): Agent configuration object
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
agent_data (AgentData): Agent data object
|
|
84
|
+
custom_skills (list[BaseTool], optional): Designed for advanced user who directly
|
|
85
|
+
call this function to inject custom skills into the agent tool node.
|
|
88
86
|
|
|
89
87
|
Returns:
|
|
90
88
|
CompiledStateGraph: Initialized LangChain agent
|
|
91
89
|
"""
|
|
92
|
-
agent_data = await AgentData.get(agent.id)
|
|
93
|
-
|
|
94
|
-
# ==== Initialize LLM using the LLM abstraction.
|
|
95
|
-
from intentkit.models.llm import create_llm_model
|
|
96
90
|
|
|
97
91
|
# Create the LLM model instance
|
|
98
92
|
llm_model = await create_llm_model(
|
|
@@ -102,17 +96,12 @@ async def create_agent(
|
|
|
102
96
|
presence_penalty=agent.presence_penalty,
|
|
103
97
|
)
|
|
104
98
|
|
|
105
|
-
# Get the LLM instance
|
|
106
|
-
llm = await llm_model.create_instance(config)
|
|
107
|
-
|
|
108
|
-
# Get the token limit from the model info
|
|
109
|
-
input_token_limit = min(config.input_token_limit, llm_model.info.context_length)
|
|
110
|
-
|
|
111
99
|
# ==== Store buffered conversation history in memory.
|
|
112
100
|
memory = get_langgraph_checkpointer()
|
|
113
101
|
|
|
114
102
|
# ==== Load skills
|
|
115
103
|
tools: list[BaseTool | dict] = []
|
|
104
|
+
private_tools: list[BaseTool | dict] = []
|
|
116
105
|
|
|
117
106
|
if agent.skills:
|
|
118
107
|
for k, v in agent.skills.items():
|
|
@@ -121,50 +110,75 @@ async def create_agent(
|
|
|
121
110
|
try:
|
|
122
111
|
skill_module = importlib.import_module(f"intentkit.skills.{k}")
|
|
123
112
|
if hasattr(skill_module, "get_skills"):
|
|
113
|
+
# all
|
|
124
114
|
skill_tools = await skill_module.get_skills(
|
|
125
|
-
v,
|
|
115
|
+
v, False, agent_id=agent.id, agent=agent
|
|
126
116
|
)
|
|
127
117
|
if skill_tools and len(skill_tools) > 0:
|
|
128
118
|
tools.extend(skill_tools)
|
|
119
|
+
# private
|
|
120
|
+
skill_private_tools = await skill_module.get_skills(
|
|
121
|
+
v, True, agent_id=agent.id, agent=agent
|
|
122
|
+
)
|
|
123
|
+
if skill_private_tools and len(skill_private_tools) > 0:
|
|
124
|
+
private_tools.extend(skill_private_tools)
|
|
129
125
|
else:
|
|
130
126
|
logger.error(f"Skill {k} does not have get_skills function")
|
|
131
127
|
except ImportError as e:
|
|
132
128
|
logger.error(f"Could not import skill module: {k} ({e})")
|
|
133
129
|
|
|
130
|
+
# add custom skills to private tools
|
|
131
|
+
if custom_skills and len(custom_skills) > 0:
|
|
132
|
+
private_tools.extend(custom_skills)
|
|
133
|
+
|
|
134
134
|
# filter the duplicate tools
|
|
135
135
|
tools = list({tool.name: tool for tool in tools}.values())
|
|
136
|
-
|
|
137
|
-
# Add search tools if requested
|
|
138
|
-
if (
|
|
139
|
-
has_search
|
|
140
|
-
and llm_model.info.provider == LLMProvider.OPENAI
|
|
141
|
-
and llm_model.info.supports_search
|
|
142
|
-
and not agent.model.startswith(
|
|
143
|
-
"gpt-5"
|
|
144
|
-
) # tmp disable gpt-5 search since package bugs
|
|
145
|
-
):
|
|
146
|
-
tools.append({"type": "web_search_preview"})
|
|
136
|
+
private_tools = list({tool.name: tool for tool in private_tools}.values())
|
|
147
137
|
|
|
148
138
|
# Create the formatted_prompt function using the refactored prompt module
|
|
149
139
|
formatted_prompt = create_formatted_prompt_function(agent, agent_data)
|
|
150
140
|
|
|
151
|
-
|
|
141
|
+
# bind tools to llm
|
|
142
|
+
async def select_model(
|
|
143
|
+
state: AgentState, runtime: Runtime[AgentContext]
|
|
144
|
+
) -> BaseChatModel:
|
|
145
|
+
llm_params = {}
|
|
146
|
+
context = runtime.context
|
|
147
|
+
if context.search:
|
|
148
|
+
if llm_model.info.supports_search:
|
|
149
|
+
if llm_model.info.provider == LLMProvider.OPENAI:
|
|
150
|
+
tools.append({"type": "web_search"})
|
|
151
|
+
private_tools.append({"type": "web_search"})
|
|
152
|
+
if agent.model.startswith("gpt-5-"):
|
|
153
|
+
llm_params["reasoning_effort"] = "low"
|
|
154
|
+
if llm_model.info.provider == LLMProvider.XAI:
|
|
155
|
+
llm_params["search_parameters"] = {"mode": "auto"}
|
|
156
|
+
# TODO: else use a search skill
|
|
157
|
+
# build llm now
|
|
158
|
+
llm = await llm_model.create_instance(llm_params)
|
|
159
|
+
if context.is_private:
|
|
160
|
+
return llm.bind_tools(private_tools)
|
|
161
|
+
return llm.bind_tools(tools)
|
|
162
|
+
|
|
163
|
+
for tool in private_tools:
|
|
152
164
|
logger.info(
|
|
153
|
-
f"[{agent.id}
|
|
165
|
+
f"[{agent.id}] loaded tool: {tool.name if isinstance(tool, BaseTool) else tool}"
|
|
154
166
|
)
|
|
155
167
|
|
|
156
168
|
# Pre model hook
|
|
169
|
+
summarize_llm = await create_llm_model(model_name="gpt-5-mini")
|
|
170
|
+
summarize_model = await summarize_llm.create_instance()
|
|
157
171
|
pre_model_hook = PreModelNode(
|
|
158
|
-
model=
|
|
172
|
+
model=summarize_model,
|
|
159
173
|
short_term_memory_strategy=agent.short_term_memory_strategy,
|
|
160
|
-
max_tokens=
|
|
161
|
-
max_summary_tokens=2048,
|
|
174
|
+
max_tokens=llm_model.info.context_length // 2,
|
|
175
|
+
max_summary_tokens=2048,
|
|
162
176
|
)
|
|
163
177
|
|
|
164
178
|
# Create ReAct Agent using the LLM and CDP Agentkit tools.
|
|
165
179
|
executor = create_react_agent(
|
|
166
|
-
model=
|
|
167
|
-
tools=
|
|
180
|
+
model=select_model,
|
|
181
|
+
tools=private_tools,
|
|
168
182
|
prompt=formatted_prompt,
|
|
169
183
|
pre_model_hook=pre_model_hook,
|
|
170
184
|
post_model_hook=post_model_node if config.payment_enabled else None,
|
|
@@ -178,7 +192,23 @@ async def create_agent(
|
|
|
178
192
|
return executor
|
|
179
193
|
|
|
180
194
|
|
|
181
|
-
async def
|
|
195
|
+
async def create_agent(agent: Agent) -> CompiledStateGraph:
|
|
196
|
+
"""Create an AI agent with specified configuration and tools.
|
|
197
|
+
|
|
198
|
+
This function maintains backward compatibility by calling build_agent internally.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
agent (Agent): Agent configuration object
|
|
202
|
+
is_private (bool, optional): Flag indicating whether the agent is private. Defaults to False.
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
CompiledStateGraph: Initialized LangChain agent
|
|
206
|
+
"""
|
|
207
|
+
agent_data = await AgentData.get(agent.id)
|
|
208
|
+
return await build_agent(agent, agent_data)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
async def initialize_agent(aid):
|
|
182
212
|
"""Initialize an AI agent with specified configuration and tools.
|
|
183
213
|
|
|
184
214
|
This function:
|
|
@@ -197,63 +227,41 @@ async def initialize_agent(aid, is_private=False):
|
|
|
197
227
|
HTTPException: If agent not found (404) or database error (500)
|
|
198
228
|
"""
|
|
199
229
|
# get the agent from the database
|
|
200
|
-
agent:
|
|
230
|
+
agent: Agent | None = await Agent.get(aid)
|
|
201
231
|
if not agent:
|
|
202
|
-
raise
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
from intentkit.models.llm import create_llm_model
|
|
206
|
-
|
|
207
|
-
llm_model = await create_llm_model(
|
|
208
|
-
model_name=agent.model,
|
|
209
|
-
temperature=agent.temperature,
|
|
210
|
-
frequency_penalty=agent.frequency_penalty,
|
|
211
|
-
presence_penalty=agent.presence_penalty,
|
|
212
|
-
)
|
|
213
|
-
has_search = (
|
|
214
|
-
llm_model.info.provider == LLMProvider.OPENAI and llm_model.info.supports_search
|
|
215
|
-
)
|
|
232
|
+
raise IntentKitAPIError(
|
|
233
|
+
status_code=404, key="AgentNotFound", message="Agent not found"
|
|
234
|
+
)
|
|
216
235
|
|
|
217
236
|
# Create the agent using the new create_agent function
|
|
218
|
-
executor = await create_agent(agent
|
|
237
|
+
executor = await create_agent(agent)
|
|
219
238
|
|
|
220
239
|
# Cache the agent executor
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
_private_agents_updated[aid] = agent.updated_at
|
|
224
|
-
else:
|
|
225
|
-
_agents[aid] = executor
|
|
226
|
-
_agents_updated[aid] = agent.updated_at
|
|
240
|
+
_agents[aid] = executor
|
|
241
|
+
_agents_updated[aid] = agent.deployed_at if agent.deployed_at else agent.updated_at
|
|
227
242
|
|
|
228
243
|
|
|
229
|
-
async def agent_executor(
|
|
230
|
-
agent_id: str, is_private: bool
|
|
231
|
-
) -> (CompiledStateGraph, float):
|
|
244
|
+
async def agent_executor(agent_id: str) -> tuple[CompiledStateGraph, float]:
|
|
232
245
|
start = time.perf_counter()
|
|
233
246
|
agent = await Agent.get(agent_id)
|
|
234
247
|
if not agent:
|
|
235
|
-
raise
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
248
|
+
raise IntentKitAPIError(
|
|
249
|
+
status_code=404, key="AgentNotFound", message="Agent not found"
|
|
250
|
+
)
|
|
251
|
+
updated_at = agent.deployed_at if agent.deployed_at else agent.updated_at
|
|
239
252
|
# Check if agent needs reinitialization due to updates
|
|
240
253
|
needs_reinit = False
|
|
241
|
-
if agent_id in
|
|
242
|
-
if
|
|
243
|
-
agent_id not in agents_updated
|
|
244
|
-
or agent.updated_at != agents_updated[agent_id]
|
|
245
|
-
):
|
|
254
|
+
if agent_id in _agents:
|
|
255
|
+
if agent_id not in _agents_updated or updated_at != _agents_updated[agent_id]:
|
|
246
256
|
needs_reinit = True
|
|
247
|
-
logger.info(
|
|
248
|
-
f"Reinitializing agent {agent_id} due to updates, private mode: {is_private}"
|
|
249
|
-
)
|
|
257
|
+
logger.info(f"Reinitializing agent {agent_id} due to updates")
|
|
250
258
|
|
|
251
259
|
# cold start or needs reinitialization
|
|
252
260
|
cold_start_cost = 0.0
|
|
253
|
-
if (agent_id not in
|
|
254
|
-
await initialize_agent(agent_id
|
|
261
|
+
if (agent_id not in _agents) or needs_reinit:
|
|
262
|
+
await initialize_agent(agent_id)
|
|
255
263
|
cold_start_cost = time.perf_counter() - start
|
|
256
|
-
return
|
|
264
|
+
return _agents[agent_id], cold_start_cost
|
|
257
265
|
|
|
258
266
|
|
|
259
267
|
async def stream_agent(message: ChatMessageCreate):
|
|
@@ -272,24 +280,62 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
272
280
|
Yields:
|
|
273
281
|
ChatMessage: Individual response messages including timing information
|
|
274
282
|
"""
|
|
283
|
+
agent = await Agent.get(message.agent_id)
|
|
284
|
+
executor, cold_start_cost = await agent_executor(message.agent_id)
|
|
285
|
+
message.cold_start_cost = cold_start_cost
|
|
286
|
+
async for chat_message in stream_agent_raw(message, agent, executor):
|
|
287
|
+
yield chat_message
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
async def stream_agent_raw(
|
|
291
|
+
message: ChatMessageCreate, agent: Agent, executor: CompiledStateGraph
|
|
292
|
+
):
|
|
275
293
|
start = time.perf_counter()
|
|
276
294
|
# make sure reply_to is set
|
|
277
295
|
message.reply_to = message.id
|
|
278
296
|
|
|
279
297
|
# save input message first
|
|
280
|
-
|
|
298
|
+
user_message = await message.save()
|
|
299
|
+
|
|
300
|
+
# temporary debug logging for telegram messages
|
|
301
|
+
if user_message.author_type == AuthorType.TELEGRAM:
|
|
302
|
+
logger.info(
|
|
303
|
+
f"[TELEGRAM DEBUG] Agent: {user_message.agent_id} | Chat: {user_message.chat_id} | Message: {user_message.message}"
|
|
304
|
+
)
|
|
281
305
|
|
|
282
|
-
|
|
283
|
-
|
|
306
|
+
if re.search(
|
|
307
|
+
r"(@clear|/clear)(?!\w)",
|
|
308
|
+
user_message.message.strip(),
|
|
309
|
+
re.IGNORECASE,
|
|
310
|
+
):
|
|
311
|
+
await clear_thread_memory(user_message.agent_id, user_message.chat_id)
|
|
312
|
+
|
|
313
|
+
confirmation_message = ChatMessageCreate(
|
|
314
|
+
id=str(XID()),
|
|
315
|
+
agent_id=user_message.agent_id,
|
|
316
|
+
chat_id=user_message.chat_id,
|
|
317
|
+
user_id=user_message.user_id,
|
|
318
|
+
author_id=user_message.agent_id,
|
|
319
|
+
author_type=AuthorType.AGENT,
|
|
320
|
+
model=agent.model,
|
|
321
|
+
thread_type=user_message.author_type,
|
|
322
|
+
reply_to=user_message.id,
|
|
323
|
+
message="Memory in context has been cleared.",
|
|
324
|
+
time_cost=time.perf_counter() - start,
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
yield await confirmation_message.save()
|
|
328
|
+
return
|
|
284
329
|
|
|
285
|
-
# model
|
|
286
330
|
model = await LLMModelInfo.get(agent.model)
|
|
287
331
|
|
|
288
332
|
payment_enabled = config.payment_enabled
|
|
333
|
+
if user_message.author_type == AuthorType.X402:
|
|
334
|
+
payment_enabled = False
|
|
289
335
|
|
|
290
336
|
# check user balance
|
|
291
337
|
if payment_enabled:
|
|
292
|
-
if not
|
|
338
|
+
if not user_message.user_id or not agent.owner:
|
|
293
339
|
raise IntentKitAPIError(
|
|
294
340
|
500,
|
|
295
341
|
"PaymentError",
|
|
@@ -298,24 +344,22 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
298
344
|
if agent.fee_percentage and agent.fee_percentage > 100:
|
|
299
345
|
owner = await User.get(agent.owner)
|
|
300
346
|
if owner and agent.fee_percentage > 100 + owner.nft_count * 10:
|
|
301
|
-
error_message_create = ChatMessageCreate(
|
|
302
|
-
|
|
303
|
-
agent_id=
|
|
304
|
-
chat_id=
|
|
305
|
-
user_id=
|
|
306
|
-
author_id=
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
reply_to=input.id,
|
|
310
|
-
message="If you are the owner of this agent, please Update the Service Fee % to be in compliance with the Nation guidelines (Max 100% + 10% per Nation Pass NFT held)",
|
|
347
|
+
error_message_create = await ChatMessageCreate.from_system_message(
|
|
348
|
+
SystemMessageType.SERVICE_FEE_ERROR,
|
|
349
|
+
agent_id=user_message.agent_id,
|
|
350
|
+
chat_id=user_message.chat_id,
|
|
351
|
+
user_id=user_message.user_id,
|
|
352
|
+
author_id=user_message.agent_id,
|
|
353
|
+
thread_type=user_message.author_type,
|
|
354
|
+
reply_to=user_message.id,
|
|
311
355
|
time_cost=time.perf_counter() - start,
|
|
312
356
|
)
|
|
313
357
|
error_message = await error_message_create.save()
|
|
314
358
|
yield error_message
|
|
315
359
|
return
|
|
316
360
|
# payer
|
|
317
|
-
payer =
|
|
318
|
-
if
|
|
361
|
+
payer = user_message.user_id
|
|
362
|
+
if user_message.author_type in [
|
|
319
363
|
AuthorType.TELEGRAM,
|
|
320
364
|
AuthorType.TWITTER,
|
|
321
365
|
AuthorType.API,
|
|
@@ -336,16 +380,14 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
336
380
|
abuse_check = False
|
|
337
381
|
if abuse_check and payer != agent.owner and user_account.free_credits > 0:
|
|
338
382
|
if quota and quota.free_income_daily > 24000:
|
|
339
|
-
error_message_create = ChatMessageCreate(
|
|
340
|
-
|
|
341
|
-
agent_id=
|
|
342
|
-
chat_id=
|
|
343
|
-
user_id=
|
|
344
|
-
author_id=
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
reply_to=input.id,
|
|
348
|
-
message="This Agent has reached its free CAP income limit for today! Start using paid CAPs or wait until this limit expires in less than 24 hours.",
|
|
383
|
+
error_message_create = await ChatMessageCreate.from_system_message(
|
|
384
|
+
SystemMessageType.DAILY_USAGE_LIMIT_EXCEEDED,
|
|
385
|
+
agent_id=user_message.agent_id,
|
|
386
|
+
chat_id=user_message.chat_id,
|
|
387
|
+
user_id=user_message.user_id,
|
|
388
|
+
author_id=user_message.agent_id,
|
|
389
|
+
thread_type=user_message.author_type,
|
|
390
|
+
reply_to=user_message.id,
|
|
349
391
|
time_cost=time.perf_counter() - start,
|
|
350
392
|
)
|
|
351
393
|
error_message = await error_message_create.save()
|
|
@@ -356,16 +398,14 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
356
398
|
if quota and quota.avg_action_cost > 0:
|
|
357
399
|
avg_count = quota.avg_action_cost
|
|
358
400
|
if not user_account.has_sufficient_credits(avg_count):
|
|
359
|
-
error_message_create = ChatMessageCreate(
|
|
360
|
-
|
|
361
|
-
agent_id=
|
|
362
|
-
chat_id=
|
|
363
|
-
user_id=
|
|
364
|
-
author_id=
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
reply_to=input.id,
|
|
368
|
-
message="Insufficient balance.",
|
|
401
|
+
error_message_create = await ChatMessageCreate.from_system_message(
|
|
402
|
+
SystemMessageType.INSUFFICIENT_BALANCE,
|
|
403
|
+
agent_id=user_message.agent_id,
|
|
404
|
+
chat_id=user_message.chat_id,
|
|
405
|
+
user_id=user_message.user_id,
|
|
406
|
+
author_id=user_message.agent_id,
|
|
407
|
+
thread_type=user_message.author_type,
|
|
408
|
+
reply_to=user_message.id,
|
|
369
409
|
time_cost=time.perf_counter() - start,
|
|
370
410
|
)
|
|
371
411
|
error_message = await error_message_create.save()
|
|
@@ -373,26 +413,22 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
373
413
|
return
|
|
374
414
|
|
|
375
415
|
is_private = False
|
|
376
|
-
if
|
|
416
|
+
if user_message.user_id == agent.owner:
|
|
377
417
|
is_private = True
|
|
378
418
|
|
|
379
|
-
|
|
380
|
-
last = start + cold_start_cost
|
|
419
|
+
last = start
|
|
381
420
|
|
|
382
421
|
# Extract images from attachments
|
|
383
422
|
image_urls = []
|
|
384
|
-
if
|
|
423
|
+
if user_message.attachments:
|
|
385
424
|
image_urls = [
|
|
386
425
|
att["url"]
|
|
387
|
-
for att in
|
|
426
|
+
for att in user_message.attachments
|
|
388
427
|
if "type" in att and att["type"] == "image" and "url" in att
|
|
389
428
|
]
|
|
390
429
|
|
|
391
430
|
# Process input message to handle @skill patterns
|
|
392
|
-
|
|
393
|
-
input_message = await explain_prompt(input.message)
|
|
394
|
-
else:
|
|
395
|
-
input_message = input.message
|
|
431
|
+
input_message = await explain_prompt(user_message.message)
|
|
396
432
|
|
|
397
433
|
# super mode
|
|
398
434
|
recursion_limit = 30
|
|
@@ -402,9 +438,11 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
402
438
|
input_message = re.sub(r"\b@super\b", "", input_message).strip()
|
|
403
439
|
|
|
404
440
|
# llm native search
|
|
441
|
+
search = False
|
|
405
442
|
if re.search(r"\b@search\b", input_message) or re.search(
|
|
406
443
|
r"\b@web\b", input_message
|
|
407
444
|
):
|
|
445
|
+
search = True
|
|
408
446
|
if model.supports_search:
|
|
409
447
|
input_message = re.sub(
|
|
410
448
|
r"\b@search\b",
|
|
@@ -421,8 +459,8 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
421
459
|
input_message = re.sub(r"\b@web\b", "", input_message).strip()
|
|
422
460
|
|
|
423
461
|
# content to llm
|
|
424
|
-
|
|
425
|
-
|
|
462
|
+
messages = [
|
|
463
|
+
HumanMessage(content=input_message),
|
|
426
464
|
]
|
|
427
465
|
# if the model doesn't natively support image parsing, add the image URLs to the message
|
|
428
466
|
if image_urls:
|
|
@@ -430,25 +468,24 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
430
468
|
agent.has_image_parser_skill(is_private=is_private)
|
|
431
469
|
and not model.supports_image_input
|
|
432
470
|
):
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
471
|
+
image_urls_text = "\n".join(image_urls)
|
|
472
|
+
input_message += f"\n\nImages:\n{image_urls_text}"
|
|
473
|
+
messages = [
|
|
474
|
+
HumanMessage(content=input_message),
|
|
436
475
|
]
|
|
437
476
|
else:
|
|
438
477
|
# anyway, pass it directly to LLM
|
|
439
|
-
|
|
478
|
+
messages.extend(
|
|
440
479
|
[
|
|
441
|
-
|
|
480
|
+
HumanMessage(
|
|
481
|
+
content={"type": "image_url", "image_url": {"url": image_url}}
|
|
482
|
+
)
|
|
442
483
|
for image_url in image_urls
|
|
443
484
|
]
|
|
444
485
|
)
|
|
445
486
|
|
|
446
|
-
messages = [
|
|
447
|
-
HumanMessage(content=content),
|
|
448
|
-
]
|
|
449
|
-
|
|
450
487
|
# stream config
|
|
451
|
-
thread_id = f"{
|
|
488
|
+
thread_id = f"{user_message.agent_id}-{user_message.chat_id}"
|
|
452
489
|
stream_config = {
|
|
453
490
|
"configurable": {
|
|
454
491
|
"thread_id": thread_id,
|
|
@@ -456,13 +493,18 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
456
493
|
"recursion_limit": recursion_limit,
|
|
457
494
|
}
|
|
458
495
|
|
|
496
|
+
def get_agent() -> Agent:
|
|
497
|
+
return agent
|
|
498
|
+
|
|
459
499
|
context = AgentContext(
|
|
460
|
-
agent_id=
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
500
|
+
agent_id=user_message.agent_id,
|
|
501
|
+
get_agent=get_agent,
|
|
502
|
+
chat_id=user_message.chat_id,
|
|
503
|
+
user_id=user_message.user_id,
|
|
504
|
+
app_id=user_message.app_id,
|
|
505
|
+
entrypoint=user_message.author_type,
|
|
465
506
|
is_private=is_private,
|
|
507
|
+
search=search,
|
|
466
508
|
payer=payer if payment_enabled else None,
|
|
467
509
|
)
|
|
468
510
|
|
|
@@ -498,14 +540,14 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
498
540
|
# agent message
|
|
499
541
|
chat_message_create = ChatMessageCreate(
|
|
500
542
|
id=str(XID()),
|
|
501
|
-
agent_id=
|
|
502
|
-
chat_id=
|
|
503
|
-
user_id=
|
|
504
|
-
author_id=
|
|
543
|
+
agent_id=user_message.agent_id,
|
|
544
|
+
chat_id=user_message.chat_id,
|
|
545
|
+
user_id=user_message.user_id,
|
|
546
|
+
author_id=user_message.agent_id,
|
|
505
547
|
author_type=AuthorType.AGENT,
|
|
506
548
|
model=agent.model,
|
|
507
|
-
thread_type=
|
|
508
|
-
reply_to=
|
|
549
|
+
thread_type=user_message.author_type,
|
|
550
|
+
reply_to=user_message.id,
|
|
509
551
|
message=content,
|
|
510
552
|
input_tokens=(
|
|
511
553
|
msg.usage_metadata.get("input_tokens", 0)
|
|
@@ -520,9 +562,6 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
520
562
|
time_cost=this_time - last,
|
|
521
563
|
)
|
|
522
564
|
last = this_time
|
|
523
|
-
if cold_start_cost > 0:
|
|
524
|
-
chat_message_create.cold_start_cost = cold_start_cost
|
|
525
|
-
cold_start_cost = 0
|
|
526
565
|
# handle message and payment in one transaction
|
|
527
566
|
async with get_session() as session:
|
|
528
567
|
# payment
|
|
@@ -543,7 +582,7 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
543
582
|
for tool_output in tool_outputs:
|
|
544
583
|
if tool_output.get("type") == "web_search_call":
|
|
545
584
|
logger.info(
|
|
546
|
-
f"[{
|
|
585
|
+
f"[{user_message.agent_id}] Found web_search_call in additional_kwargs"
|
|
547
586
|
)
|
|
548
587
|
amount += 35
|
|
549
588
|
break
|
|
@@ -551,11 +590,13 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
551
590
|
session,
|
|
552
591
|
payer,
|
|
553
592
|
chat_message_create.id,
|
|
554
|
-
|
|
593
|
+
user_message.id,
|
|
555
594
|
amount,
|
|
556
595
|
agent,
|
|
557
596
|
)
|
|
558
|
-
logger.info(
|
|
597
|
+
logger.info(
|
|
598
|
+
f"[{user_message.agent_id}] expense message: {amount}"
|
|
599
|
+
)
|
|
559
600
|
chat_message_create.credit_event_id = credit_event.id
|
|
560
601
|
chat_message_create.credit_cost = credit_event.total_amount
|
|
561
602
|
chat_message = await chat_message_create.save_in_session(
|
|
@@ -606,14 +647,14 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
606
647
|
break
|
|
607
648
|
skill_message_create = ChatMessageCreate(
|
|
608
649
|
id=str(XID()),
|
|
609
|
-
agent_id=
|
|
610
|
-
chat_id=
|
|
611
|
-
user_id=
|
|
612
|
-
author_id=
|
|
650
|
+
agent_id=user_message.agent_id,
|
|
651
|
+
chat_id=user_message.chat_id,
|
|
652
|
+
user_id=user_message.user_id,
|
|
653
|
+
author_id=user_message.agent_id,
|
|
613
654
|
author_type=AuthorType.SKILL,
|
|
614
655
|
model=agent.model,
|
|
615
|
-
thread_type=
|
|
616
|
-
reply_to=
|
|
656
|
+
thread_type=user_message.author_type,
|
|
657
|
+
reply_to=user_message.id,
|
|
617
658
|
message="",
|
|
618
659
|
skill_calls=skill_calls,
|
|
619
660
|
attachments=cached_attachments,
|
|
@@ -634,9 +675,6 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
634
675
|
time_cost=this_time - last,
|
|
635
676
|
)
|
|
636
677
|
last = this_time
|
|
637
|
-
if cold_start_cost > 0:
|
|
638
|
-
skill_message_create.cold_start_cost = cold_start_cost
|
|
639
|
-
cold_start_cost = 0
|
|
640
678
|
# save message and credit in one transaction
|
|
641
679
|
async with get_session() as session:
|
|
642
680
|
if payment_enabled:
|
|
@@ -650,7 +688,7 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
650
688
|
session,
|
|
651
689
|
payer,
|
|
652
690
|
skill_message_create.id,
|
|
653
|
-
|
|
691
|
+
user_message.id,
|
|
654
692
|
message_amount,
|
|
655
693
|
agent,
|
|
656
694
|
)
|
|
@@ -664,11 +702,14 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
664
702
|
for skill_call in skill_calls:
|
|
665
703
|
if not skill_call["success"]:
|
|
666
704
|
continue
|
|
705
|
+
skill = await Skill.get(skill_call["name"])
|
|
706
|
+
if not skill:
|
|
707
|
+
continue
|
|
667
708
|
payment_event = await expense_skill(
|
|
668
709
|
session,
|
|
669
710
|
payer,
|
|
670
711
|
skill_message_create.id,
|
|
671
|
-
|
|
712
|
+
user_message.id,
|
|
672
713
|
skill_call["id"],
|
|
673
714
|
skill_call["name"],
|
|
674
715
|
agent,
|
|
@@ -676,7 +717,7 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
676
717
|
skill_call["credit_event_id"] = payment_event.id
|
|
677
718
|
skill_call["credit_cost"] = payment_event.total_amount
|
|
678
719
|
logger.info(
|
|
679
|
-
f"[{
|
|
720
|
+
f"[{user_message.agent_id}] skill payment: {skill_call}"
|
|
680
721
|
)
|
|
681
722
|
skill_message_create.skill_calls = skill_calls
|
|
682
723
|
skill_message = await skill_message_create.save_in_session(session)
|
|
@@ -702,38 +743,33 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
702
743
|
content = msg.content[0]
|
|
703
744
|
post_model_message_create = ChatMessageCreate(
|
|
704
745
|
id=str(XID()),
|
|
705
|
-
agent_id=
|
|
706
|
-
chat_id=
|
|
707
|
-
user_id=
|
|
708
|
-
author_id=
|
|
746
|
+
agent_id=user_message.agent_id,
|
|
747
|
+
chat_id=user_message.chat_id,
|
|
748
|
+
user_id=user_message.user_id,
|
|
749
|
+
author_id=user_message.agent_id,
|
|
709
750
|
author_type=AuthorType.AGENT,
|
|
710
751
|
model=agent.model,
|
|
711
|
-
thread_type=
|
|
712
|
-
reply_to=
|
|
752
|
+
thread_type=user_message.author_type,
|
|
753
|
+
reply_to=user_message.id,
|
|
713
754
|
message=content,
|
|
714
755
|
input_tokens=0,
|
|
715
756
|
output_tokens=0,
|
|
716
757
|
time_cost=this_time - last,
|
|
717
758
|
)
|
|
718
759
|
last = this_time
|
|
719
|
-
if cold_start_cost > 0:
|
|
720
|
-
post_model_message_create.cold_start_cost = (
|
|
721
|
-
cold_start_cost
|
|
722
|
-
)
|
|
723
|
-
cold_start_cost = 0
|
|
724
760
|
post_model_message = await post_model_message_create.save()
|
|
725
761
|
yield post_model_message
|
|
726
|
-
error_message_create =
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
762
|
+
error_message_create = (
|
|
763
|
+
await ChatMessageCreate.from_system_message(
|
|
764
|
+
SystemMessageType.INSUFFICIENT_BALANCE,
|
|
765
|
+
agent_id=user_message.agent_id,
|
|
766
|
+
chat_id=user_message.chat_id,
|
|
767
|
+
user_id=user_message.user_id,
|
|
768
|
+
author_id=user_message.agent_id,
|
|
769
|
+
thread_type=user_message.author_type,
|
|
770
|
+
reply_to=user_message.id,
|
|
771
|
+
time_cost=0,
|
|
772
|
+
)
|
|
737
773
|
)
|
|
738
774
|
error_message = await error_message_create.save()
|
|
739
775
|
yield error_message
|
|
@@ -749,16 +785,14 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
749
785
|
f"failed to execute agent: {str(e)}\n{error_traceback}",
|
|
750
786
|
extra={"thread_id": thread_id},
|
|
751
787
|
)
|
|
752
|
-
error_message_create = ChatMessageCreate(
|
|
753
|
-
|
|
754
|
-
agent_id=
|
|
755
|
-
chat_id=
|
|
756
|
-
user_id=
|
|
757
|
-
author_id=
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
reply_to=input.id,
|
|
761
|
-
message="Agent Internal Error",
|
|
788
|
+
error_message_create = await ChatMessageCreate.from_system_message(
|
|
789
|
+
SystemMessageType.AGENT_INTERNAL_ERROR,
|
|
790
|
+
agent_id=user_message.agent_id,
|
|
791
|
+
chat_id=user_message.chat_id,
|
|
792
|
+
user_id=user_message.user_id,
|
|
793
|
+
author_id=user_message.agent_id,
|
|
794
|
+
thread_type=user_message.author_type,
|
|
795
|
+
reply_to=user_message.id,
|
|
762
796
|
time_cost=time.perf_counter() - start,
|
|
763
797
|
)
|
|
764
798
|
error_message = await error_message_create.save()
|
|
@@ -768,18 +802,16 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
768
802
|
error_traceback = traceback.format_exc()
|
|
769
803
|
logger.error(
|
|
770
804
|
f"reached recursion limit: {str(e)}\n{error_traceback}",
|
|
771
|
-
extra={"thread_id": thread_id, "agent_id":
|
|
805
|
+
extra={"thread_id": thread_id, "agent_id": user_message.agent_id},
|
|
772
806
|
)
|
|
773
|
-
error_message_create = ChatMessageCreate(
|
|
774
|
-
|
|
775
|
-
agent_id=
|
|
776
|
-
chat_id=
|
|
777
|
-
user_id=
|
|
778
|
-
author_id=
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
reply_to=input.id,
|
|
782
|
-
message="Step Limit Error",
|
|
807
|
+
error_message_create = await ChatMessageCreate.from_system_message(
|
|
808
|
+
SystemMessageType.STEP_LIMIT_EXCEEDED,
|
|
809
|
+
agent_id=user_message.agent_id,
|
|
810
|
+
chat_id=user_message.chat_id,
|
|
811
|
+
user_id=user_message.user_id,
|
|
812
|
+
author_id=user_message.agent_id,
|
|
813
|
+
thread_type=user_message.author_type,
|
|
814
|
+
reply_to=user_message.id,
|
|
783
815
|
time_cost=time.perf_counter() - start,
|
|
784
816
|
)
|
|
785
817
|
error_message = await error_message_create.save()
|
|
@@ -789,22 +821,21 @@ async def stream_agent(message: ChatMessageCreate):
|
|
|
789
821
|
error_traceback = traceback.format_exc()
|
|
790
822
|
logger.error(
|
|
791
823
|
f"failed to execute agent: {str(e)}\n{error_traceback}",
|
|
792
|
-
extra={"thread_id": thread_id, "agent_id":
|
|
824
|
+
extra={"thread_id": thread_id, "agent_id": user_message.agent_id},
|
|
793
825
|
)
|
|
794
|
-
error_message_create = ChatMessageCreate(
|
|
795
|
-
|
|
796
|
-
agent_id=
|
|
797
|
-
chat_id=
|
|
798
|
-
user_id=
|
|
799
|
-
author_id=
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
reply_to=input.id,
|
|
803
|
-
message="Agent Internal Error",
|
|
826
|
+
error_message_create = await ChatMessageCreate.from_system_message(
|
|
827
|
+
SystemMessageType.AGENT_INTERNAL_ERROR,
|
|
828
|
+
agent_id=user_message.agent_id,
|
|
829
|
+
chat_id=user_message.chat_id,
|
|
830
|
+
user_id=user_message.user_id,
|
|
831
|
+
author_id=user_message.agent_id,
|
|
832
|
+
thread_type=user_message.author_type,
|
|
833
|
+
reply_to=user_message.id,
|
|
804
834
|
time_cost=time.perf_counter() - start,
|
|
805
835
|
)
|
|
806
836
|
error_message = await error_message_create.save()
|
|
807
837
|
yield error_message
|
|
838
|
+
await clear_thread_memory(user_message.agent_id, user_message.chat_id)
|
|
808
839
|
return
|
|
809
840
|
|
|
810
841
|
|
|
@@ -859,14 +890,15 @@ async def clean_agent_memory(
|
|
|
859
890
|
# get the agent from the database
|
|
860
891
|
try:
|
|
861
892
|
if not clean_skill and not clean_agent:
|
|
862
|
-
raise
|
|
893
|
+
raise IntentKitAPIError(
|
|
863
894
|
status_code=400,
|
|
864
|
-
|
|
895
|
+
key="InvalidCleanupParameters",
|
|
896
|
+
message="at least one of skills data or agent memory should be true",
|
|
865
897
|
)
|
|
866
898
|
|
|
867
899
|
if clean_skill:
|
|
868
900
|
await AgentSkillData.clean_data(agent_id)
|
|
869
|
-
await
|
|
901
|
+
await ChatSkillData.clean_data(agent_id, chat_id)
|
|
870
902
|
|
|
871
903
|
async with get_session() as db:
|
|
872
904
|
if clean_agent:
|
|
@@ -908,7 +940,7 @@ async def clean_agent_memory(
|
|
|
908
940
|
except SQLAlchemyError as e:
|
|
909
941
|
# Handle other SQLAlchemy-related errors
|
|
910
942
|
logger.error(e)
|
|
911
|
-
raise
|
|
943
|
+
raise IntentKitAPIError(status_code=500, key="DatabaseError", message=str(e))
|
|
912
944
|
except Exception as e:
|
|
913
945
|
logger.error("failed to cleanup the agent memory: " + str(e))
|
|
914
946
|
raise e
|
|
@@ -917,10 +949,7 @@ async def clean_agent_memory(
|
|
|
917
949
|
async def thread_stats(agent_id: str, chat_id: str) -> list[BaseMessage]:
|
|
918
950
|
thread_id = f"{agent_id}-{chat_id}"
|
|
919
951
|
stream_config = {"configurable": {"thread_id": thread_id}}
|
|
920
|
-
|
|
921
|
-
if chat_id.startswith("owner") or chat_id.startswith("autonomous"):
|
|
922
|
-
is_private = True
|
|
923
|
-
executor, _ = await agent_executor(agent_id, is_private)
|
|
952
|
+
executor, _ = await agent_executor(agent_id)
|
|
924
953
|
snap = await executor.aget_state(stream_config)
|
|
925
954
|
if snap.values and "messages" in snap.values:
|
|
926
955
|
return snap.values["messages"]
|