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/node.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from
|
|
2
|
+
from collections.abc import Sequence
|
|
3
|
+
from typing import Any
|
|
3
4
|
|
|
4
5
|
from langchain_core.language_models import LanguageModelLike
|
|
5
6
|
from langchain_core.messages import (
|
|
@@ -24,7 +25,6 @@ from langmem.short_term.summarization import (
|
|
|
24
25
|
|
|
25
26
|
from intentkit.abstracts.graph import AgentContext, AgentError, AgentState
|
|
26
27
|
from intentkit.core.credit import skill_cost
|
|
27
|
-
from intentkit.models.agent import Agent
|
|
28
28
|
from intentkit.models.credit import CreditAccount, OwnerType
|
|
29
29
|
from intentkit.models.skill import Skill
|
|
30
30
|
|
|
@@ -66,7 +66,7 @@ class PreModelNode(RunnableCallable):
|
|
|
66
66
|
model: LanguageModelLike,
|
|
67
67
|
short_term_memory_strategy: str,
|
|
68
68
|
max_tokens: int,
|
|
69
|
-
max_summary_tokens: int =
|
|
69
|
+
max_summary_tokens: int = 2048,
|
|
70
70
|
) -> None:
|
|
71
71
|
super().__init__(self._func, self._afunc, name="pre_model_node", trace=False)
|
|
72
72
|
self.model = model
|
|
@@ -81,10 +81,10 @@ class PreModelNode(RunnableCallable):
|
|
|
81
81
|
self.func_accepts_config = True
|
|
82
82
|
|
|
83
83
|
def _parse_input(
|
|
84
|
-
self,
|
|
84
|
+
self, state: AgentState
|
|
85
85
|
) -> tuple[list[AnyMessage], dict[str, Any]]:
|
|
86
|
-
messages =
|
|
87
|
-
context =
|
|
86
|
+
messages = state.get("messages")
|
|
87
|
+
context = state.get("context", {})
|
|
88
88
|
if messages is None or not isinstance(messages, list) or len(messages) == 0:
|
|
89
89
|
raise ValueError("Missing required field `messages` in the input.")
|
|
90
90
|
return messages, context
|
|
@@ -107,13 +107,13 @@ class PreModelNode(RunnableCallable):
|
|
|
107
107
|
def _func(self, AgentState) -> dict[str, Any]:
|
|
108
108
|
raise NotImplementedError("Not implemented yet")
|
|
109
109
|
|
|
110
|
-
async def _afunc(self,
|
|
111
|
-
messages, context = self._parse_input(
|
|
110
|
+
async def _afunc(self, state: AgentState) -> dict[str, Any]:
|
|
111
|
+
messages, context = self._parse_input(state)
|
|
112
112
|
try:
|
|
113
113
|
_validate_chat_history(messages)
|
|
114
114
|
except ValueError as e:
|
|
115
115
|
logger.error(f"Invalid chat history: {e}")
|
|
116
|
-
logger.info(
|
|
116
|
+
logger.info(state)
|
|
117
117
|
# delete all messages
|
|
118
118
|
return {"messages": [RemoveMessage(REMOVE_ALL_MESSAGES)]}
|
|
119
119
|
if self.short_term_memory_strategy == "trim":
|
|
@@ -162,7 +162,7 @@ class PreModelNode(RunnableCallable):
|
|
|
162
162
|
return self._prepare_state_update(context, summarization_result)
|
|
163
163
|
except ValueError as e:
|
|
164
164
|
logger.error(f"Invalid chat history: {e}")
|
|
165
|
-
logger.info(
|
|
165
|
+
logger.info(state)
|
|
166
166
|
# delete all messages
|
|
167
167
|
return {"messages": [RemoveMessage(REMOVE_ALL_MESSAGES)]}
|
|
168
168
|
raise ValueError(
|
|
@@ -175,15 +175,15 @@ class PostModelNode(RunnableCallable):
|
|
|
175
175
|
super().__init__(self._func, self._afunc, name="post_model_node", trace=False)
|
|
176
176
|
self.func_accepts_config = True
|
|
177
177
|
|
|
178
|
-
def _func(self,
|
|
178
|
+
def _func(self, state: AgentState) -> dict[str, Any]:
|
|
179
179
|
raise NotImplementedError("Not implemented yet")
|
|
180
180
|
|
|
181
|
-
async def _afunc(self,
|
|
181
|
+
async def _afunc(self, state: AgentState) -> dict[str, Any]:
|
|
182
182
|
runtime = get_runtime(AgentContext)
|
|
183
183
|
context = runtime.context
|
|
184
|
-
logger.debug(f"Running PostModelNode, input: {
|
|
184
|
+
logger.debug(f"Running PostModelNode, input: {state}, context: {context}")
|
|
185
185
|
state_update = {}
|
|
186
|
-
messages =
|
|
186
|
+
messages = state.get("messages")
|
|
187
187
|
if messages is None or not isinstance(messages, list) or len(messages) == 0:
|
|
188
188
|
raise ValueError("Missing required field `messages` in the input.")
|
|
189
189
|
payer = context.payer
|
|
@@ -191,8 +191,7 @@ class PostModelNode(RunnableCallable):
|
|
|
191
191
|
return state_update
|
|
192
192
|
logger.debug(f"last: {messages[-1]}")
|
|
193
193
|
msg = messages[-1]
|
|
194
|
-
|
|
195
|
-
agent = await Agent.get(agent_id)
|
|
194
|
+
agent = context.agent
|
|
196
195
|
account = await CreditAccount.get_or_create(OwnerType.USER, payer)
|
|
197
196
|
if hasattr(msg, "tool_calls") and msg.tool_calls:
|
|
198
197
|
for tool_call in msg.tool_calls:
|
intentkit/core/prompt.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import re
|
|
2
|
-
from
|
|
2
|
+
from collections.abc import Callable
|
|
3
3
|
|
|
4
4
|
from eth_utils import is_address
|
|
5
5
|
from langchain_core.messages import BaseMessage
|
|
@@ -12,13 +12,14 @@ from intentkit.models.agent import Agent
|
|
|
12
12
|
from intentkit.models.agent_data import AgentData
|
|
13
13
|
from intentkit.models.chat import AuthorType
|
|
14
14
|
from intentkit.models.skill import Skill
|
|
15
|
+
from intentkit.models.user import User
|
|
15
16
|
|
|
16
17
|
# ============================================================================
|
|
17
18
|
# CONSTANTS AND CONFIGURATION
|
|
18
19
|
# ============================================================================
|
|
19
20
|
|
|
20
21
|
# Base system prompt components
|
|
21
|
-
|
|
22
|
+
INTENTKIT_PROMPT = """You are an AI agent built using IntentKit.
|
|
22
23
|
Your tools are called 'skills'.
|
|
23
24
|
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."""
|
|
24
25
|
|
|
@@ -34,7 +35,6 @@ user confirmation before broadcasting any approval transactions for security rea
|
|
|
34
35
|
|
|
35
36
|
"""
|
|
36
37
|
|
|
37
|
-
|
|
38
38
|
# ============================================================================
|
|
39
39
|
# CORE PROMPT BUILDING FUNCTIONS
|
|
40
40
|
# ============================================================================
|
|
@@ -45,7 +45,10 @@ def _build_system_header() -> str:
|
|
|
45
45
|
prompt = "# SYSTEM PROMPT\n\n"
|
|
46
46
|
if config.system_prompt:
|
|
47
47
|
prompt += config.system_prompt + "\n\n"
|
|
48
|
-
|
|
48
|
+
if config.intentkit_prompt:
|
|
49
|
+
prompt += config.intentkit_prompt + "\n\n"
|
|
50
|
+
else:
|
|
51
|
+
prompt += INTENTKIT_PROMPT + "\n\n"
|
|
49
52
|
return prompt
|
|
50
53
|
|
|
51
54
|
|
|
@@ -103,32 +106,70 @@ def _build_wallet_section(agent: Agent, agent_data: AgentData) -> str:
|
|
|
103
106
|
return ""
|
|
104
107
|
|
|
105
108
|
wallet_parts = []
|
|
106
|
-
network_id = agent.network_id
|
|
109
|
+
network_id = agent.network_id
|
|
107
110
|
|
|
108
111
|
if agent_data.evm_wallet_address and network_id != "solana":
|
|
109
112
|
wallet_parts.append(
|
|
110
|
-
f"Your wallet address
|
|
113
|
+
f"Your EVM wallet address is {agent_data.evm_wallet_address}."
|
|
114
|
+
f"You are now in {network_id} network."
|
|
111
115
|
)
|
|
112
116
|
if agent_data.solana_wallet_address and network_id == "solana":
|
|
113
117
|
wallet_parts.append(
|
|
114
|
-
f"Your wallet address
|
|
118
|
+
f"Your Solana wallet address is {agent_data.solana_wallet_address}."
|
|
119
|
+
f"You are now in {network_id} network."
|
|
115
120
|
)
|
|
116
121
|
|
|
122
|
+
# Add CDP skills prompt if CDP skills are enabled
|
|
123
|
+
if agent.skills and "cdp" in agent.skills:
|
|
124
|
+
cdp_config = agent.skills["cdp"]
|
|
125
|
+
if cdp_config and cdp_config.get("enabled") is True:
|
|
126
|
+
# Check if any CDP skills are in public or private state (not disabled)
|
|
127
|
+
states = cdp_config.get("states", {})
|
|
128
|
+
has_enabled_cdp_skills = any(
|
|
129
|
+
state in ["public", "private"] for state in states.values()
|
|
130
|
+
)
|
|
131
|
+
if has_enabled_cdp_skills:
|
|
132
|
+
wallet_parts.append(
|
|
133
|
+
"If a skill input parameter requires a token address but you only have the user-provided token symbol, "
|
|
134
|
+
"and the address cannot be found in the nearby context, you must use the `token_search` skill to query "
|
|
135
|
+
f"the address of that symbol on the current chain ({network_id}) and confirm this address with the user."
|
|
136
|
+
"If the `token_search` skill is not found, remind the user to enable it."
|
|
137
|
+
)
|
|
138
|
+
|
|
117
139
|
return "\n".join(wallet_parts) + ("\n" if wallet_parts else "")
|
|
118
140
|
|
|
119
141
|
|
|
120
|
-
def _build_user_info_section(context: AgentContext) -> str:
|
|
142
|
+
async def _build_user_info_section(context: AgentContext) -> str:
|
|
121
143
|
"""Build user information section when user_id is a valid EVM wallet address."""
|
|
122
144
|
if not context.user_id:
|
|
123
145
|
return ""
|
|
124
146
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
147
|
+
user = await User.get(context.user_id)
|
|
148
|
+
|
|
149
|
+
prompt_array = []
|
|
150
|
+
|
|
151
|
+
evm_wallet_address = ""
|
|
152
|
+
if user and user.evm_wallet_address:
|
|
153
|
+
evm_wallet_address = user.evm_wallet_address
|
|
154
|
+
elif is_address(context.user_id):
|
|
155
|
+
evm_wallet_address = context.user_id
|
|
156
|
+
|
|
157
|
+
if evm_wallet_address:
|
|
158
|
+
prompt_array.append(
|
|
159
|
+
f"The user you are talking to has EVM wallet address: {evm_wallet_address}\n"
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
if user:
|
|
163
|
+
if user.email:
|
|
164
|
+
prompt_array.append(f"User Email: {user.email}\n")
|
|
165
|
+
if user.x_username:
|
|
166
|
+
prompt_array.append(f"User X Username: {user.x_username}\n")
|
|
167
|
+
if user.telegram_username:
|
|
168
|
+
prompt_array.append(f"User Telegram Username: {user.telegram_username}\n")
|
|
169
|
+
|
|
170
|
+
if prompt_array:
|
|
171
|
+
prompt_array.append("\n")
|
|
172
|
+
return "## User Info\n\n" + "".join(prompt_array)
|
|
132
173
|
|
|
133
174
|
return ""
|
|
134
175
|
|
|
@@ -201,7 +242,6 @@ def agent_prompt(agent: Agent, agent_data: AgentData) -> str:
|
|
|
201
242
|
async def explain_prompt(message: str) -> str:
|
|
202
243
|
"""
|
|
203
244
|
Process message to replace @skill:*:* patterns with (call skill xxxxx) format.
|
|
204
|
-
This function is used when admin_llm_skill_control is enabled.
|
|
205
245
|
|
|
206
246
|
Args:
|
|
207
247
|
message (str): The input message to process
|
|
@@ -287,12 +327,11 @@ def _build_autonomous_task_prompt(agent: Agent, context: AgentContext) -> str:
|
|
|
287
327
|
return f"{task_info}. "
|
|
288
328
|
|
|
289
329
|
|
|
290
|
-
async def build_entrypoint_prompt(agent: Agent, context: AgentContext) ->
|
|
330
|
+
async def build_entrypoint_prompt(agent: Agent, context: AgentContext) -> str | None:
|
|
291
331
|
"""
|
|
292
332
|
Build entrypoint-specific prompt based on context.
|
|
293
333
|
|
|
294
334
|
Supports different entrypoint types:
|
|
295
|
-
- Twitter: Uses agent.twitter_entrypoint_prompt
|
|
296
335
|
- Telegram: Uses agent.telegram_entrypoint_prompt
|
|
297
336
|
- Autonomous tasks: Builds task-specific prompt with scheduling info
|
|
298
337
|
|
|
@@ -301,7 +340,7 @@ async def build_entrypoint_prompt(agent: Agent, context: AgentContext) -> Option
|
|
|
301
340
|
context: The agent context containing entrypoint information
|
|
302
341
|
|
|
303
342
|
Returns:
|
|
304
|
-
|
|
343
|
+
str | None: The entrypoint-specific prompt, or None if no entrypoint
|
|
305
344
|
"""
|
|
306
345
|
if not context.entrypoint:
|
|
307
346
|
return None
|
|
@@ -323,8 +362,7 @@ async def build_entrypoint_prompt(agent: Agent, context: AgentContext) -> Option
|
|
|
323
362
|
elif entrypoint == AuthorType.TRIGGER.value:
|
|
324
363
|
entrypoint_prompt = "\n\n" + _build_autonomous_task_prompt(agent, context)
|
|
325
364
|
|
|
326
|
-
|
|
327
|
-
if entrypoint_prompt and config.admin_llm_skill_control:
|
|
365
|
+
if entrypoint_prompt:
|
|
328
366
|
entrypoint_prompt = await explain_prompt(entrypoint_prompt)
|
|
329
367
|
|
|
330
368
|
return entrypoint_prompt
|
|
@@ -365,11 +403,8 @@ def create_formatted_prompt_function(agent: Agent, agent_data: AgentData) -> Cal
|
|
|
365
403
|
prompt = build_agent_prompt(agent, agent_data)
|
|
366
404
|
escaped_prompt = escape_prompt(prompt)
|
|
367
405
|
|
|
368
|
-
# Process with admin LLM skill control if enabled
|
|
369
406
|
async def get_base_prompt():
|
|
370
|
-
|
|
371
|
-
return await explain_prompt(escaped_prompt)
|
|
372
|
-
return escaped_prompt
|
|
407
|
+
return await explain_prompt(escaped_prompt)
|
|
373
408
|
|
|
374
409
|
# Build prompt array
|
|
375
410
|
prompt_array = [
|
|
@@ -400,7 +435,7 @@ def create_formatted_prompt_function(agent: Agent, agent_data: AgentData) -> Cal
|
|
|
400
435
|
)
|
|
401
436
|
|
|
402
437
|
# Add user info if user_id is a valid EVM wallet address
|
|
403
|
-
user_info = _build_user_info_section(context)
|
|
438
|
+
user_info = await _build_user_info_section(context)
|
|
404
439
|
if user_info:
|
|
405
440
|
final_system_prompt = f"{final_system_prompt}{user_info}"
|
|
406
441
|
|
|
@@ -408,8 +443,7 @@ def create_formatted_prompt_function(agent: Agent, agent_data: AgentData) -> Cal
|
|
|
408
443
|
internal_info = build_internal_info_prompt(context)
|
|
409
444
|
final_system_prompt = f"{final_system_prompt}{internal_info}"
|
|
410
445
|
|
|
411
|
-
|
|
412
|
-
if agent.prompt_append and config.admin_llm_skill_control:
|
|
446
|
+
if agent.prompt_append:
|
|
413
447
|
# Find the system message in prompt_array and process it
|
|
414
448
|
for i, (role, content) in enumerate(prompt_array):
|
|
415
449
|
if role == "system":
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""Core scheduler utilities."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Mapping, MutableMapping
|
|
6
|
+
|
|
7
|
+
from apscheduler.jobstores.base import BaseJobStore
|
|
8
|
+
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
|
9
|
+
from apscheduler.triggers.cron import CronTrigger
|
|
10
|
+
|
|
11
|
+
from intentkit.core.agent import (
|
|
12
|
+
update_agent_action_cost,
|
|
13
|
+
update_agents_account_snapshot,
|
|
14
|
+
update_agents_statistics,
|
|
15
|
+
)
|
|
16
|
+
from intentkit.core.credit import refill_all_free_credits
|
|
17
|
+
from intentkit.models.agent_data import AgentQuota
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def create_scheduler(
|
|
21
|
+
jobstores: Mapping[str, BaseJobStore]
|
|
22
|
+
| MutableMapping[str, BaseJobStore]
|
|
23
|
+
| None = None,
|
|
24
|
+
) -> AsyncIOScheduler:
|
|
25
|
+
"""Create and configure the APScheduler with all periodic tasks."""
|
|
26
|
+
scheduler = AsyncIOScheduler(jobstores=dict(jobstores or {}))
|
|
27
|
+
|
|
28
|
+
# Reset daily quotas at UTC 00:00
|
|
29
|
+
scheduler.add_job(
|
|
30
|
+
AgentQuota.reset_daily_quotas,
|
|
31
|
+
trigger=CronTrigger(hour=0, minute=0, timezone="UTC"),
|
|
32
|
+
id="reset_daily_quotas",
|
|
33
|
+
name="Reset daily quotas",
|
|
34
|
+
replace_existing=True,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Reset monthly quotas at UTC 00:00 on the first day of each month
|
|
38
|
+
scheduler.add_job(
|
|
39
|
+
AgentQuota.reset_monthly_quotas,
|
|
40
|
+
trigger=CronTrigger(day=1, hour=0, minute=0, timezone="UTC"),
|
|
41
|
+
id="reset_monthly_quotas",
|
|
42
|
+
name="Reset monthly quotas",
|
|
43
|
+
replace_existing=True,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Refill free credits every hour at minute 20
|
|
47
|
+
scheduler.add_job(
|
|
48
|
+
refill_all_free_credits,
|
|
49
|
+
trigger=CronTrigger(minute="20", timezone="UTC"),
|
|
50
|
+
id="refill_free_credits",
|
|
51
|
+
name="Refill free credits",
|
|
52
|
+
replace_existing=True,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Update agent account snapshots hourly
|
|
56
|
+
scheduler.add_job(
|
|
57
|
+
update_agents_account_snapshot,
|
|
58
|
+
trigger=CronTrigger(minute=0, timezone="UTC"),
|
|
59
|
+
id="update_agent_account_snapshot",
|
|
60
|
+
name="Update agent account snapshots",
|
|
61
|
+
replace_existing=True,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Update agent assets daily at UTC midnight
|
|
65
|
+
# This is too expensive to run daily, so it will only be triggered when detail page is visited
|
|
66
|
+
# scheduler.add_job(
|
|
67
|
+
# update_agents_assets,
|
|
68
|
+
# trigger=CronTrigger(hour=0, minute=0, timezone="UTC"),
|
|
69
|
+
# id="update_agent_assets",
|
|
70
|
+
# name="Update agent assets",
|
|
71
|
+
# replace_existing=True,
|
|
72
|
+
# )
|
|
73
|
+
|
|
74
|
+
# Update agent action costs hourly at minute 40
|
|
75
|
+
scheduler.add_job(
|
|
76
|
+
update_agent_action_cost,
|
|
77
|
+
trigger=CronTrigger(minute="40", timezone="UTC"),
|
|
78
|
+
id="update_agent_action_cost",
|
|
79
|
+
name="Update agent action costs",
|
|
80
|
+
replace_existing=True,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# Update agent statistics daily at UTC 00:01
|
|
84
|
+
scheduler.add_job(
|
|
85
|
+
update_agents_statistics,
|
|
86
|
+
trigger=CronTrigger(hour=0, minute=1, timezone="UTC"),
|
|
87
|
+
id="update_agent_statistics",
|
|
88
|
+
name="Update agent statistics",
|
|
89
|
+
replace_existing=True,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
return scheduler
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""Agent statistics utilities."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import UTC, datetime, timedelta
|
|
6
|
+
from decimal import Decimal
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
from sqlalchemy import func, select
|
|
10
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
11
|
+
|
|
12
|
+
from intentkit.models.agent_data import AgentQuota, AgentQuotaTable
|
|
13
|
+
from intentkit.models.credit import CreditAccount, CreditEventTable, OwnerType
|
|
14
|
+
from intentkit.models.db import get_session
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AgentStatistics(BaseModel):
|
|
18
|
+
"""Aggregated statistics for an agent credit account."""
|
|
19
|
+
|
|
20
|
+
agent_id: str = Field(description="ID of the agent")
|
|
21
|
+
account_id: str = Field(description="ID of the associated credit account")
|
|
22
|
+
balance: Decimal = Field(description="Current credit account balance")
|
|
23
|
+
total_income: Decimal = Field(description="Total income across all events")
|
|
24
|
+
net_income: Decimal = Field(description="Net income from fee allocations")
|
|
25
|
+
permanent_income: Decimal = Field(
|
|
26
|
+
description="Total permanent income across all events"
|
|
27
|
+
)
|
|
28
|
+
permanent_profit: Decimal = Field(
|
|
29
|
+
description="Permanent profit allocated to the agent"
|
|
30
|
+
)
|
|
31
|
+
last_24h_income: Decimal = Field(
|
|
32
|
+
description="Income generated during the last 24 hours"
|
|
33
|
+
)
|
|
34
|
+
last_24h_permanent_income: Decimal = Field(
|
|
35
|
+
description="Permanent income generated during the last 24 hours"
|
|
36
|
+
)
|
|
37
|
+
avg_action_cost: Decimal = Field(description="Average action cost")
|
|
38
|
+
min_action_cost: Decimal = Field(description="Minimum action cost")
|
|
39
|
+
max_action_cost: Decimal = Field(description="Maximum action cost")
|
|
40
|
+
low_action_cost: Decimal = Field(description="20th percentile action cost")
|
|
41
|
+
medium_action_cost: Decimal = Field(description="60th percentile action cost")
|
|
42
|
+
high_action_cost: Decimal = Field(description="80th percentile action cost")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
async def get_agent_statistics(
|
|
46
|
+
agent_id: str,
|
|
47
|
+
*,
|
|
48
|
+
end_time: datetime | None = None,
|
|
49
|
+
session: AsyncSession | None = None,
|
|
50
|
+
) -> AgentStatistics:
|
|
51
|
+
"""Calculate statistics for an agent credit account.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
agent_id: ID of the agent.
|
|
55
|
+
end_time: Optional end time used as the inclusive boundary for
|
|
56
|
+
time-windowed aggregations. Defaults to the current UTC time.
|
|
57
|
+
session: Optional database session to reuse. When omitted, a
|
|
58
|
+
standalone session will be created and committed automatically.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
Aggregated statistics for the agent.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
managed_session = session is None
|
|
65
|
+
if end_time is None:
|
|
66
|
+
end_time = datetime.now(UTC)
|
|
67
|
+
elif end_time.tzinfo is None:
|
|
68
|
+
end_time = end_time.replace(tzinfo=UTC)
|
|
69
|
+
else:
|
|
70
|
+
end_time = end_time.astimezone(UTC)
|
|
71
|
+
|
|
72
|
+
async def _compute(session: AsyncSession) -> AgentStatistics:
|
|
73
|
+
account = await CreditAccount.get_or_create_in_session(
|
|
74
|
+
session, OwnerType.AGENT, agent_id
|
|
75
|
+
)
|
|
76
|
+
balance = account.free_credits + account.reward_credits + account.credits
|
|
77
|
+
|
|
78
|
+
totals_stmt = select(
|
|
79
|
+
func.sum(CreditEventTable.total_amount).label("total_income"),
|
|
80
|
+
func.sum(CreditEventTable.fee_agent_amount).label("net_income"),
|
|
81
|
+
func.sum(CreditEventTable.permanent_amount).label("permanent_income"),
|
|
82
|
+
func.sum(CreditEventTable.fee_agent_permanent_amount).label(
|
|
83
|
+
"permanent_profit"
|
|
84
|
+
),
|
|
85
|
+
).where(CreditEventTable.agent_id == agent_id)
|
|
86
|
+
totals_result = await session.execute(totals_stmt)
|
|
87
|
+
totals_row = totals_result.first()
|
|
88
|
+
|
|
89
|
+
total_income = (
|
|
90
|
+
totals_row.total_income
|
|
91
|
+
if totals_row and totals_row.total_income
|
|
92
|
+
else Decimal("0")
|
|
93
|
+
)
|
|
94
|
+
net_income = (
|
|
95
|
+
totals_row.net_income
|
|
96
|
+
if totals_row and totals_row.net_income
|
|
97
|
+
else Decimal("0")
|
|
98
|
+
)
|
|
99
|
+
permanent_income = (
|
|
100
|
+
totals_row.permanent_income
|
|
101
|
+
if totals_row and totals_row.permanent_income
|
|
102
|
+
else Decimal("0")
|
|
103
|
+
)
|
|
104
|
+
permanent_profit = (
|
|
105
|
+
totals_row.permanent_profit
|
|
106
|
+
if totals_row and totals_row.permanent_profit
|
|
107
|
+
else Decimal("0")
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
window_start = end_time - timedelta(hours=24)
|
|
111
|
+
window_stmt = select(
|
|
112
|
+
func.sum(CreditEventTable.total_amount).label("last_24h_income"),
|
|
113
|
+
func.sum(CreditEventTable.permanent_amount).label(
|
|
114
|
+
"last_24h_permanent_income"
|
|
115
|
+
),
|
|
116
|
+
).where(
|
|
117
|
+
CreditEventTable.agent_id == agent_id,
|
|
118
|
+
CreditEventTable.created_at >= window_start,
|
|
119
|
+
CreditEventTable.created_at <= end_time,
|
|
120
|
+
)
|
|
121
|
+
window_result = await session.execute(window_stmt)
|
|
122
|
+
window_row = window_result.first()
|
|
123
|
+
|
|
124
|
+
last_24h_income = (
|
|
125
|
+
window_row.last_24h_income
|
|
126
|
+
if window_row and window_row.last_24h_income
|
|
127
|
+
else Decimal("0")
|
|
128
|
+
)
|
|
129
|
+
last_24h_permanent_income = (
|
|
130
|
+
window_row.last_24h_permanent_income
|
|
131
|
+
if window_row and window_row.last_24h_permanent_income
|
|
132
|
+
else Decimal("0")
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
quota_row = await session.get(AgentQuotaTable, agent_id)
|
|
136
|
+
quota = (
|
|
137
|
+
AgentQuota.model_validate(quota_row)
|
|
138
|
+
if quota_row
|
|
139
|
+
else AgentQuota(id=agent_id)
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
return AgentStatistics(
|
|
143
|
+
agent_id=agent_id,
|
|
144
|
+
account_id=account.id,
|
|
145
|
+
balance=balance,
|
|
146
|
+
total_income=total_income,
|
|
147
|
+
net_income=net_income,
|
|
148
|
+
permanent_income=permanent_income,
|
|
149
|
+
permanent_profit=permanent_profit,
|
|
150
|
+
last_24h_income=last_24h_income,
|
|
151
|
+
last_24h_permanent_income=last_24h_permanent_income,
|
|
152
|
+
avg_action_cost=quota.avg_action_cost,
|
|
153
|
+
min_action_cost=quota.min_action_cost,
|
|
154
|
+
max_action_cost=quota.max_action_cost,
|
|
155
|
+
low_action_cost=quota.low_action_cost,
|
|
156
|
+
medium_action_cost=quota.medium_action_cost,
|
|
157
|
+
high_action_cost=quota.high_action_cost,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
if managed_session:
|
|
161
|
+
async with get_session() as managed:
|
|
162
|
+
statistics = await _compute(managed)
|
|
163
|
+
await managed.commit()
|
|
164
|
+
return statistics
|
|
165
|
+
return await _compute(session)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
__all__ = ["AgentStatistics", "get_agent_statistics"]
|