intentkit 0.8.12rc0__py3-none-any.whl → 0.8.13__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/skill.py +2 -59
- intentkit/clients/__init__.py +3 -2
- intentkit/clients/cdp.py +63 -44
- intentkit/clients/twitter.py +35 -28
- intentkit/config/config.py +1 -0
- intentkit/core/agent.py +2 -279
- intentkit/core/asset.py +63 -16
- intentkit/core/engine.py +9 -5
- intentkit/core/scheduler.py +8 -8
- intentkit/models/agent.py +138 -94
- intentkit/models/agent_schema.json +6 -9
- intentkit/models/chat.py +1 -0
- intentkit/models/llm.csv +15 -12
- intentkit/models/skills.csv +5 -4
- intentkit/skills/acolyt/__init__.py +2 -9
- intentkit/skills/acolyt/base.py +2 -5
- intentkit/skills/aixbt/__init__.py +2 -13
- intentkit/skills/aixbt/base.py +0 -4
- intentkit/skills/aixbt/projects.py +1 -2
- intentkit/skills/allora/__init__.py +2 -9
- intentkit/skills/allora/base.py +2 -5
- intentkit/skills/base.py +101 -37
- intentkit/skills/basename/__init__.py +1 -3
- intentkit/skills/carv/__init__.py +116 -121
- intentkit/skills/carv/base.py +184 -185
- intentkit/skills/casino/__init__.py +4 -15
- intentkit/skills/casino/base.py +0 -4
- intentkit/skills/casino/deck_draw.py +1 -2
- intentkit/skills/casino/deck_shuffle.py +1 -2
- intentkit/skills/casino/dice_roll.py +1 -2
- intentkit/skills/cdp/__init__.py +0 -5
- intentkit/skills/cdp/base.py +0 -4
- intentkit/skills/cdp/schema.json +1 -17
- intentkit/skills/chainlist/__init__.py +2 -7
- intentkit/skills/chainlist/base.py +0 -4
- intentkit/skills/common/__init__.py +2 -9
- intentkit/skills/common/base.py +0 -4
- intentkit/skills/cookiefun/__init__.py +6 -9
- intentkit/skills/cookiefun/base.py +0 -4
- intentkit/skills/cryptocompare/__init__.py +7 -24
- intentkit/skills/cryptocompare/base.py +0 -5
- intentkit/skills/cryptopanic/__init__.py +3 -6
- intentkit/skills/cryptopanic/base.py +53 -55
- intentkit/skills/cryptopanic/fetch_crypto_news.py +0 -2
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +1 -3
- intentkit/skills/dapplooker/__init__.py +2 -9
- intentkit/skills/dapplooker/base.py +2 -5
- intentkit/skills/defillama/__init__.py +24 -74
- intentkit/skills/defillama/base.py +0 -4
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +2 -2
- intentkit/skills/defillama/coins/fetch_block.py +2 -2
- intentkit/skills/defillama/coins/fetch_current_prices.py +2 -2
- intentkit/skills/defillama/coins/fetch_first_price.py +2 -2
- intentkit/skills/defillama/coins/fetch_historical_prices.py +2 -2
- intentkit/skills/defillama/coins/fetch_price_chart.py +2 -2
- intentkit/skills/defillama/coins/fetch_price_percentage.py +2 -2
- intentkit/skills/defillama/fees/fetch_fees_overview.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +2 -2
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +2 -2
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +2 -2
- intentkit/skills/defillama/tvl/fetch_chains.py +2 -2
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +2 -2
- intentkit/skills/defillama/tvl/fetch_protocol.py +2 -2
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +2 -2
- intentkit/skills/defillama/tvl/fetch_protocols.py +2 -2
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +2 -2
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +2 -2
- intentkit/skills/defillama/volumes/fetch_options_overview.py +2 -2
- intentkit/skills/defillama/yields/fetch_pool_chart.py +2 -2
- intentkit/skills/defillama/yields/fetch_pools.py +2 -2
- intentkit/skills/dexscreener/__init__.py +97 -102
- intentkit/skills/dexscreener/base.py +125 -130
- intentkit/skills/dexscreener/get_pair_info.py +2 -3
- intentkit/skills/dexscreener/get_token_pairs.py +2 -3
- intentkit/skills/dexscreener/get_tokens_info.py +2 -3
- intentkit/skills/dexscreener/search_token.py +2 -4
- intentkit/skills/dune_analytics/__init__.py +4 -6
- intentkit/skills/dune_analytics/base.py +50 -52
- intentkit/skills/dune_analytics/fetch_kol_buys.py +0 -2
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +0 -2
- intentkit/skills/elfa/__init__.py +5 -18
- intentkit/skills/elfa/base.py +8 -10
- intentkit/skills/enso/__init__.py +9 -29
- intentkit/skills/enso/base.py +3 -6
- intentkit/skills/enso/route.py +1 -3
- intentkit/skills/erc20/__init__.py +1 -5
- intentkit/skills/erc721/__init__.py +1 -3
- intentkit/skills/firecrawl/__init__.py +5 -18
- intentkit/skills/firecrawl/base.py +2 -5
- intentkit/skills/firecrawl/crawl.py +10 -9
- intentkit/skills/firecrawl/query.py +3 -1
- intentkit/skills/firecrawl/scrape.py +8 -10
- intentkit/skills/firecrawl/utils.py +25 -26
- intentkit/skills/github/__init__.py +2 -7
- intentkit/skills/github/base.py +0 -4
- intentkit/skills/heurist/__init__.py +8 -27
- intentkit/skills/heurist/base.py +2 -5
- intentkit/skills/heurist/image_generation_animagine_xl.py +5 -5
- intentkit/skills/heurist/image_generation_arthemy_comics.py +5 -5
- intentkit/skills/heurist/image_generation_arthemy_real.py +5 -5
- intentkit/skills/heurist/image_generation_braindance.py +5 -5
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +5 -5
- intentkit/skills/heurist/image_generation_flux_1_dev.py +5 -5
- intentkit/skills/heurist/image_generation_sdxl.py +5 -5
- intentkit/skills/http/__init__.py +4 -15
- intentkit/skills/http/base.py +0 -4
- intentkit/skills/lifi/__init__.py +1 -6
- intentkit/skills/lifi/base.py +0 -4
- intentkit/skills/lifi/token_execute.py +1 -4
- intentkit/skills/lifi/token_quote.py +1 -3
- intentkit/skills/moralis/__init__.py +3 -7
- intentkit/skills/moralis/base.py +2 -5
- intentkit/skills/morpho/__init__.py +1 -3
- intentkit/skills/nation/__init__.py +2 -7
- intentkit/skills/nation/base.py +4 -7
- intentkit/skills/onchain.py +27 -0
- intentkit/skills/openai/__init__.py +5 -18
- intentkit/skills/openai/base.py +8 -10
- intentkit/skills/openai/dalle_image_generation.py +2 -5
- intentkit/skills/openai/gpt_image_generation.py +2 -5
- intentkit/skills/openai/gpt_image_to_image.py +2 -5
- intentkit/skills/openai/image_to_text.py +2 -5
- intentkit/skills/portfolio/__init__.py +11 -35
- intentkit/skills/portfolio/base.py +2 -5
- intentkit/skills/pyth/__init__.py +1 -5
- intentkit/skills/skills.toml +4 -0
- intentkit/skills/slack/__init__.py +5 -17
- intentkit/skills/slack/base.py +0 -4
- intentkit/skills/supabase/__init__.py +7 -23
- intentkit/skills/supabase/base.py +0 -4
- intentkit/skills/superfluid/__init__.py +1 -3
- intentkit/skills/system/__init__.py +7 -24
- intentkit/skills/system/add_autonomous_task.py +2 -2
- intentkit/skills/system/delete_autonomous_task.py +2 -2
- intentkit/skills/system/edit_autonomous_task.py +2 -4
- intentkit/skills/system/list_autonomous_tasks.py +2 -2
- intentkit/skills/system/read_agent_api_key.py +6 -4
- intentkit/skills/system/regenerate_agent_api_key.py +6 -4
- intentkit/skills/tavily/__init__.py +3 -12
- intentkit/skills/tavily/base.py +2 -5
- intentkit/skills/tavily/tavily_extract.py +1 -2
- intentkit/skills/tavily/tavily_search.py +3 -3
- intentkit/skills/token/__init__.py +5 -10
- intentkit/skills/token/base.py +2 -6
- intentkit/skills/twitter/__init__.py +11 -35
- intentkit/skills/twitter/base.py +14 -16
- intentkit/skills/twitter/follow_user.py +0 -1
- intentkit/skills/twitter/get_mentions.py +0 -1
- intentkit/skills/twitter/get_timeline.py +0 -1
- intentkit/skills/twitter/get_user_by_username.py +0 -1
- intentkit/skills/twitter/get_user_tweets.py +0 -1
- intentkit/skills/twitter/like_tweet.py +0 -1
- intentkit/skills/twitter/post_tweet.py +2 -2
- intentkit/skills/twitter/reply_tweet.py +2 -2
- intentkit/skills/twitter/retweet.py +0 -1
- intentkit/skills/twitter/search_tweets.py +0 -1
- intentkit/skills/unrealspeech/__init__.py +2 -7
- intentkit/skills/unrealspeech/base.py +0 -4
- intentkit/skills/venice_audio/__init__.py +99 -106
- intentkit/skills/venice_audio/base.py +118 -121
- intentkit/skills/venice_audio/venice_audio.py +1 -5
- intentkit/skills/venice_image/__init__.py +147 -154
- intentkit/skills/venice_image/base.py +185 -192
- intentkit/skills/web_scraper/__init__.py +5 -18
- intentkit/skills/web_scraper/base.py +20 -4
- intentkit/skills/web_scraper/document_indexer.py +6 -4
- intentkit/skills/web_scraper/scrape_and_index.py +11 -8
- intentkit/skills/web_scraper/utils.py +31 -27
- intentkit/skills/web_scraper/website_indexer.py +7 -8
- intentkit/skills/weth/__init__.py +1 -5
- intentkit/skills/wow/__init__.py +1 -5
- intentkit/skills/x402/__init__.py +53 -0
- intentkit/skills/x402/ask_agent.py +141 -0
- intentkit/skills/x402/base.py +9 -0
- intentkit/skills/x402/schema.json +40 -0
- intentkit/skills/x402/x402.png +0 -0
- intentkit/skills/xmtp/__init__.py +4 -15
- intentkit/skills/xmtp/base.py +2 -2
- intentkit/skills/xmtp/price.py +3 -3
- intentkit/skills/xmtp/swap.py +4 -4
- intentkit/utils/schema.py +100 -0
- {intentkit-0.8.12rc0.dist-info → intentkit-0.8.13.dist-info}/METADATA +1 -1
- {intentkit-0.8.12rc0.dist-info → intentkit-0.8.13.dist-info}/RECORD +188 -181
- {intentkit-0.8.12rc0.dist-info → intentkit-0.8.13.dist-info}/WHEEL +0 -0
- {intentkit-0.8.12rc0.dist-info → intentkit-0.8.13.dist-info}/licenses/LICENSE +0 -0
intentkit/core/agent.py
CHANGED
|
@@ -2,21 +2,19 @@ import logging
|
|
|
2
2
|
import time
|
|
3
3
|
from datetime import datetime, timedelta, timezone
|
|
4
4
|
from decimal import Decimal
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import AsyncGenerator, Dict, Optional, Tuple
|
|
6
6
|
|
|
7
7
|
from sqlalchemy import func, select, text, update
|
|
8
8
|
|
|
9
|
-
from intentkit.abstracts.skill import SkillStoreABC
|
|
10
9
|
from intentkit.clients.cdp import get_wallet_provider
|
|
11
10
|
from intentkit.config.config import config
|
|
12
11
|
from intentkit.models.agent import (
|
|
13
12
|
Agent,
|
|
14
|
-
AgentAutonomous,
|
|
15
13
|
AgentCreate,
|
|
16
14
|
AgentTable,
|
|
17
15
|
AgentUpdate,
|
|
18
16
|
)
|
|
19
|
-
from intentkit.models.agent_data import AgentData,
|
|
17
|
+
from intentkit.models.agent_data import AgentData, AgentQuotaTable
|
|
20
18
|
from intentkit.models.credit import (
|
|
21
19
|
CreditAccount,
|
|
22
20
|
CreditEventTable,
|
|
@@ -486,93 +484,6 @@ async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
|
|
|
486
484
|
return result
|
|
487
485
|
|
|
488
486
|
|
|
489
|
-
class AgentStore(SkillStoreABC):
|
|
490
|
-
"""Implementation of skill data storage operations.
|
|
491
|
-
|
|
492
|
-
This class provides concrete implementations for storing and retrieving
|
|
493
|
-
skill-related data for both agents and threads.
|
|
494
|
-
"""
|
|
495
|
-
|
|
496
|
-
@staticmethod
|
|
497
|
-
def get_system_config(key: str) -> Any:
|
|
498
|
-
# TODO: maybe need a whitelist here
|
|
499
|
-
if hasattr(config, key):
|
|
500
|
-
return getattr(config, key)
|
|
501
|
-
return None
|
|
502
|
-
|
|
503
|
-
@staticmethod
|
|
504
|
-
async def get_agent_config(agent_id: str) -> Optional[Agent]:
|
|
505
|
-
return await Agent.get(agent_id)
|
|
506
|
-
|
|
507
|
-
@staticmethod
|
|
508
|
-
async def get_agent_data(agent_id: str) -> AgentData:
|
|
509
|
-
return await AgentData.get(agent_id)
|
|
510
|
-
|
|
511
|
-
@staticmethod
|
|
512
|
-
async def set_agent_data(agent_id: str, data: Dict) -> AgentData:
|
|
513
|
-
return await AgentData.patch(agent_id, data)
|
|
514
|
-
|
|
515
|
-
@staticmethod
|
|
516
|
-
async def get_agent_quota(agent_id: str) -> AgentQuota:
|
|
517
|
-
return await AgentQuota.get(agent_id)
|
|
518
|
-
|
|
519
|
-
@staticmethod
|
|
520
|
-
async def list_autonomous_tasks(agent_id: str) -> List[AgentAutonomous]:
|
|
521
|
-
"""List all autonomous tasks for an agent.
|
|
522
|
-
|
|
523
|
-
Args:
|
|
524
|
-
agent_id: ID of the agent
|
|
525
|
-
|
|
526
|
-
Returns:
|
|
527
|
-
List[AgentAutonomous]: List of autonomous task configurations
|
|
528
|
-
"""
|
|
529
|
-
return await list_autonomous_tasks(agent_id)
|
|
530
|
-
|
|
531
|
-
@staticmethod
|
|
532
|
-
async def add_autonomous_task(
|
|
533
|
-
agent_id: str, task: AgentAutonomous
|
|
534
|
-
) -> AgentAutonomous:
|
|
535
|
-
"""Add a new autonomous task to an agent.
|
|
536
|
-
|
|
537
|
-
Args:
|
|
538
|
-
agent_id: ID of the agent
|
|
539
|
-
task: Autonomous task configuration
|
|
540
|
-
|
|
541
|
-
Returns:
|
|
542
|
-
AgentAutonomous: The created task
|
|
543
|
-
"""
|
|
544
|
-
return await add_autonomous_task(agent_id, task)
|
|
545
|
-
|
|
546
|
-
@staticmethod
|
|
547
|
-
async def delete_autonomous_task(agent_id: str, task_id: str) -> None:
|
|
548
|
-
"""Delete an autonomous task from an agent.
|
|
549
|
-
|
|
550
|
-
Args:
|
|
551
|
-
agent_id: ID of the agent
|
|
552
|
-
task_id: ID of the task to delete
|
|
553
|
-
"""
|
|
554
|
-
await delete_autonomous_task(agent_id, task_id)
|
|
555
|
-
|
|
556
|
-
@staticmethod
|
|
557
|
-
async def update_autonomous_task(
|
|
558
|
-
agent_id: str, task_id: str, task_updates: dict
|
|
559
|
-
) -> AgentAutonomous:
|
|
560
|
-
"""Update an autonomous task for an agent.
|
|
561
|
-
|
|
562
|
-
Args:
|
|
563
|
-
agent_id: ID of the agent
|
|
564
|
-
task_id: ID of the task to update
|
|
565
|
-
task_updates: Dictionary containing fields to update
|
|
566
|
-
|
|
567
|
-
Returns:
|
|
568
|
-
AgentAutonomous: The updated task
|
|
569
|
-
"""
|
|
570
|
-
return await update_autonomous_task(agent_id, task_id, task_updates)
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
agent_store = AgentStore()
|
|
574
|
-
|
|
575
|
-
|
|
576
487
|
async def _iterate_agent_id_batches(
|
|
577
488
|
batch_size: int = 100,
|
|
578
489
|
) -> AsyncGenerator[list[str], None]:
|
|
@@ -828,191 +739,3 @@ async def update_agents_statistics(
|
|
|
828
739
|
total_updated,
|
|
829
740
|
total_time,
|
|
830
741
|
)
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
async def list_autonomous_tasks(agent_id: str) -> List[AgentAutonomous]:
|
|
834
|
-
"""
|
|
835
|
-
List all autonomous tasks for an agent.
|
|
836
|
-
|
|
837
|
-
Args:
|
|
838
|
-
agent_id: ID of the agent
|
|
839
|
-
|
|
840
|
-
Returns:
|
|
841
|
-
List[AgentAutonomous]: List of autonomous task configurations
|
|
842
|
-
|
|
843
|
-
Raises:
|
|
844
|
-
IntentKitAPIError: If agent is not found
|
|
845
|
-
"""
|
|
846
|
-
agent = await Agent.get(agent_id)
|
|
847
|
-
if not agent:
|
|
848
|
-
raise IntentKitAPIError(
|
|
849
|
-
400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
|
|
850
|
-
)
|
|
851
|
-
|
|
852
|
-
if not agent.autonomous:
|
|
853
|
-
return []
|
|
854
|
-
|
|
855
|
-
return agent.autonomous
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
async def add_autonomous_task(agent_id: str, task: AgentAutonomous) -> AgentAutonomous:
|
|
859
|
-
"""
|
|
860
|
-
Add a new autonomous task to an agent.
|
|
861
|
-
|
|
862
|
-
Args:
|
|
863
|
-
agent_id: ID of the agent
|
|
864
|
-
task: Autonomous task configuration (id will be generated if not provided)
|
|
865
|
-
|
|
866
|
-
Returns:
|
|
867
|
-
AgentAutonomous: The created task with generated ID
|
|
868
|
-
|
|
869
|
-
Raises:
|
|
870
|
-
IntentKitAPIError: If agent is not found
|
|
871
|
-
"""
|
|
872
|
-
agent = await Agent.get(agent_id)
|
|
873
|
-
if not agent:
|
|
874
|
-
raise IntentKitAPIError(
|
|
875
|
-
400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
|
|
876
|
-
)
|
|
877
|
-
|
|
878
|
-
# Get current autonomous tasks
|
|
879
|
-
current_tasks = agent.autonomous or []
|
|
880
|
-
if not isinstance(current_tasks, list):
|
|
881
|
-
current_tasks = []
|
|
882
|
-
|
|
883
|
-
# Add the new task
|
|
884
|
-
current_tasks.append(task)
|
|
885
|
-
|
|
886
|
-
# Convert all AgentAutonomous objects to dictionaries for JSON serialization
|
|
887
|
-
serializable_tasks = [task_item.model_dump() for task_item in current_tasks]
|
|
888
|
-
|
|
889
|
-
# Update the agent in the database
|
|
890
|
-
async with get_session() as session:
|
|
891
|
-
update_stmt = (
|
|
892
|
-
update(AgentTable)
|
|
893
|
-
.where(AgentTable.id == agent_id)
|
|
894
|
-
.values(autonomous=serializable_tasks)
|
|
895
|
-
)
|
|
896
|
-
await session.execute(update_stmt)
|
|
897
|
-
await session.commit()
|
|
898
|
-
|
|
899
|
-
logger.info(f"Added autonomous task {task.id} to agent {agent_id}")
|
|
900
|
-
return task
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
async def delete_autonomous_task(agent_id: str, task_id: str) -> None:
|
|
904
|
-
"""
|
|
905
|
-
Delete an autonomous task from an agent.
|
|
906
|
-
|
|
907
|
-
Args:
|
|
908
|
-
agent_id: ID of the agent
|
|
909
|
-
task_id: ID of the task to delete
|
|
910
|
-
|
|
911
|
-
Raises:
|
|
912
|
-
IntentKitAPIError: If agent is not found or task is not found
|
|
913
|
-
"""
|
|
914
|
-
agent = await Agent.get(agent_id)
|
|
915
|
-
if not agent:
|
|
916
|
-
raise IntentKitAPIError(
|
|
917
|
-
400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
|
|
918
|
-
)
|
|
919
|
-
|
|
920
|
-
# Get current autonomous tasks
|
|
921
|
-
current_tasks = agent.autonomous or []
|
|
922
|
-
if not isinstance(current_tasks, list):
|
|
923
|
-
current_tasks = []
|
|
924
|
-
|
|
925
|
-
# Find and remove the task
|
|
926
|
-
task_found = False
|
|
927
|
-
updated_tasks = []
|
|
928
|
-
for task_data in current_tasks:
|
|
929
|
-
if task_data.id == task_id:
|
|
930
|
-
task_found = True
|
|
931
|
-
continue
|
|
932
|
-
updated_tasks.append(task_data)
|
|
933
|
-
|
|
934
|
-
if not task_found:
|
|
935
|
-
raise IntentKitAPIError(
|
|
936
|
-
404, "TaskNotFound", f"Autonomous task with ID {task_id} not found."
|
|
937
|
-
)
|
|
938
|
-
|
|
939
|
-
# Convert remaining AgentAutonomous objects to dictionaries for JSON serialization
|
|
940
|
-
serializable_tasks = [task_item.model_dump() for task_item in updated_tasks]
|
|
941
|
-
|
|
942
|
-
# Update the agent in the database
|
|
943
|
-
async with get_session() as session:
|
|
944
|
-
update_stmt = (
|
|
945
|
-
update(AgentTable)
|
|
946
|
-
.where(AgentTable.id == agent_id)
|
|
947
|
-
.values(autonomous=serializable_tasks)
|
|
948
|
-
)
|
|
949
|
-
await session.execute(update_stmt)
|
|
950
|
-
await session.commit()
|
|
951
|
-
|
|
952
|
-
logger.info(f"Deleted autonomous task {task_id} from agent {agent_id}")
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
async def update_autonomous_task(
|
|
956
|
-
agent_id: str, task_id: str, task_updates: dict
|
|
957
|
-
) -> AgentAutonomous:
|
|
958
|
-
"""
|
|
959
|
-
Update an autonomous task for an agent.
|
|
960
|
-
|
|
961
|
-
Args:
|
|
962
|
-
agent_id: ID of the agent
|
|
963
|
-
task_id: ID of the task to update
|
|
964
|
-
task_updates: Dictionary containing fields to update
|
|
965
|
-
|
|
966
|
-
Returns:
|
|
967
|
-
AgentAutonomous: The updated task
|
|
968
|
-
|
|
969
|
-
Raises:
|
|
970
|
-
IntentKitAPIError: If agent is not found or task is not found
|
|
971
|
-
"""
|
|
972
|
-
agent = await Agent.get(agent_id)
|
|
973
|
-
if not agent:
|
|
974
|
-
raise IntentKitAPIError(
|
|
975
|
-
400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
|
|
976
|
-
)
|
|
977
|
-
|
|
978
|
-
# Get current autonomous tasks
|
|
979
|
-
current_tasks: List[AgentAutonomous] = agent.autonomous or []
|
|
980
|
-
|
|
981
|
-
# Find and update the task
|
|
982
|
-
task_found = False
|
|
983
|
-
updated_tasks: List[AgentAutonomous] = []
|
|
984
|
-
updated_task = None
|
|
985
|
-
|
|
986
|
-
for task_data in current_tasks:
|
|
987
|
-
if task_data.id == task_id:
|
|
988
|
-
task_found = True
|
|
989
|
-
# Create a dictionary with current task data
|
|
990
|
-
task_dict = task_data.model_dump()
|
|
991
|
-
# Update with provided fields
|
|
992
|
-
task_dict.update(task_updates)
|
|
993
|
-
# Create new AgentAutonomous instance
|
|
994
|
-
updated_task = AgentAutonomous.model_validate(task_dict)
|
|
995
|
-
updated_tasks.append(updated_task)
|
|
996
|
-
else:
|
|
997
|
-
updated_tasks.append(task_data)
|
|
998
|
-
|
|
999
|
-
if not task_found:
|
|
1000
|
-
raise IntentKitAPIError(
|
|
1001
|
-
404, "TaskNotFound", f"Autonomous task with ID {task_id} not found."
|
|
1002
|
-
)
|
|
1003
|
-
|
|
1004
|
-
# Convert all AgentAutonomous objects to dictionaries for JSON serialization
|
|
1005
|
-
serializable_tasks = [task_item.model_dump() for task_item in updated_tasks]
|
|
1006
|
-
|
|
1007
|
-
# Update the agent in the database
|
|
1008
|
-
async with get_session() as session:
|
|
1009
|
-
update_stmt = (
|
|
1010
|
-
update(AgentTable)
|
|
1011
|
-
.where(AgentTable.id == agent_id)
|
|
1012
|
-
.values(autonomous=serializable_tasks)
|
|
1013
|
-
)
|
|
1014
|
-
await session.execute(update_stmt)
|
|
1015
|
-
await session.commit()
|
|
1016
|
-
|
|
1017
|
-
logger.info(f"Updated autonomous task {task_id} for agent {agent_id}")
|
|
1018
|
-
return updated_task
|
intentkit/core/asset.py
CHANGED
|
@@ -2,18 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import json
|
|
5
6
|
import logging
|
|
6
7
|
from decimal import Decimal
|
|
7
8
|
from typing import Optional
|
|
8
9
|
|
|
9
10
|
import httpx
|
|
10
11
|
from pydantic import BaseModel, Field
|
|
12
|
+
from sqlalchemy import update
|
|
11
13
|
from web3 import Web3
|
|
12
14
|
|
|
13
15
|
from intentkit.clients.web3 import get_web3_client
|
|
14
16
|
from intentkit.config.config import config
|
|
15
|
-
from intentkit.models.agent import Agent
|
|
17
|
+
from intentkit.models.agent import Agent, AgentTable
|
|
16
18
|
from intentkit.models.agent_data import AgentData
|
|
19
|
+
from intentkit.models.db import get_session
|
|
20
|
+
from intentkit.models.redis import get_redis
|
|
17
21
|
from intentkit.utils.error import IntentKitAPIError
|
|
18
22
|
|
|
19
23
|
logger = logging.getLogger(__name__)
|
|
@@ -171,29 +175,72 @@ async def _build_assets_list(
|
|
|
171
175
|
|
|
172
176
|
async def agent_asset(agent_id: str) -> AgentAssets:
|
|
173
177
|
"""Fetch wallet net worth and token balances for an agent."""
|
|
178
|
+
|
|
179
|
+
cache_key = f"intentkit:agent_assets:{agent_id}"
|
|
180
|
+
redis_client = None
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
redis_client = get_redis()
|
|
184
|
+
except Exception as exc: # pragma: no cover - best effort fallback
|
|
185
|
+
logger.debug("Redis unavailable for agent assets: %s", exc)
|
|
186
|
+
|
|
174
187
|
agent = await Agent.get(agent_id)
|
|
175
188
|
if not agent:
|
|
176
189
|
raise IntentKitAPIError(404, "AgentNotFound", "Agent not found")
|
|
177
190
|
|
|
191
|
+
if redis_client:
|
|
192
|
+
try:
|
|
193
|
+
cached_raw = await redis_client.get(cache_key)
|
|
194
|
+
if cached_raw:
|
|
195
|
+
cached_data = json.loads(cached_raw)
|
|
196
|
+
cached_assets = AgentAssets.model_validate(cached_data)
|
|
197
|
+
return cached_assets
|
|
198
|
+
except Exception as exc: # pragma: no cover - cache read path only
|
|
199
|
+
logger.debug("Failed to read agent asset cache for %s: %s", agent_id, exc)
|
|
200
|
+
|
|
178
201
|
agent_data = await AgentData.get(agent_id)
|
|
179
202
|
if not agent_data or not agent_data.evm_wallet_address:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
203
|
+
assets_result = AgentAssets(net_worth="0", tokens=[])
|
|
204
|
+
elif not agent.network_id:
|
|
205
|
+
assets_result = AgentAssets(net_worth="0", tokens=[])
|
|
206
|
+
else:
|
|
207
|
+
try:
|
|
208
|
+
web3_client = get_web3_client(str(agent.network_id))
|
|
209
|
+
tokens = await _build_assets_list(agent, agent_data, web3_client)
|
|
210
|
+
net_worth = await _get_wallet_net_worth(agent_data.evm_wallet_address)
|
|
211
|
+
assets_result = AgentAssets(net_worth=net_worth, tokens=tokens)
|
|
212
|
+
except IntentKitAPIError:
|
|
213
|
+
raise
|
|
214
|
+
except Exception as exc:
|
|
215
|
+
logger.error("Error getting agent assets for %s: %s", agent_id, exc)
|
|
216
|
+
raise IntentKitAPIError(
|
|
217
|
+
500, "AgentAssetError", "Failed to retrieve agent assets"
|
|
218
|
+
) from exc
|
|
219
|
+
|
|
220
|
+
assets_payload = assets_result.model_dump(mode="json")
|
|
221
|
+
|
|
222
|
+
if redis_client:
|
|
223
|
+
try:
|
|
224
|
+
await redis_client.set(
|
|
225
|
+
cache_key,
|
|
226
|
+
json.dumps(assets_payload),
|
|
227
|
+
ex=3600,
|
|
228
|
+
)
|
|
229
|
+
except Exception as exc: # pragma: no cover - cache write path only
|
|
230
|
+
logger.debug("Failed to write agent asset cache for %s: %s", agent_id, exc)
|
|
184
231
|
|
|
185
232
|
try:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
233
|
+
async with get_session() as session:
|
|
234
|
+
await session.execute(
|
|
235
|
+
update(AgentTable)
|
|
236
|
+
.where(AgentTable.id == agent_id)
|
|
237
|
+
.values(assets=assets_payload)
|
|
238
|
+
)
|
|
239
|
+
await session.commit()
|
|
240
|
+
except Exception as exc: # pragma: no cover - db persistence path only
|
|
241
|
+
logger.error("Error updating agent assets cache for %s: %s", agent_id, exc)
|
|
242
|
+
|
|
243
|
+
return assets_result
|
|
197
244
|
|
|
198
245
|
|
|
199
246
|
__all__ = [
|
intentkit/core/engine.py
CHANGED
|
@@ -21,7 +21,6 @@ from typing import Optional, Tuple
|
|
|
21
21
|
|
|
22
22
|
import sqlalchemy
|
|
23
23
|
from epyxid import XID
|
|
24
|
-
from langchain.agents import create_agent as create_react_agent
|
|
25
24
|
from langchain_core.language_models import BaseChatModel
|
|
26
25
|
from langchain_core.messages import (
|
|
27
26
|
BaseMessage,
|
|
@@ -30,13 +29,13 @@ from langchain_core.messages import (
|
|
|
30
29
|
from langchain_core.tools import BaseTool
|
|
31
30
|
from langgraph.errors import GraphRecursionError
|
|
32
31
|
from langgraph.graph.state import CompiledStateGraph
|
|
32
|
+
from langgraph.prebuilt import create_react_agent
|
|
33
33
|
from langgraph.runtime import Runtime
|
|
34
34
|
from sqlalchemy import func, update
|
|
35
35
|
from sqlalchemy.exc import SQLAlchemyError
|
|
36
36
|
|
|
37
37
|
from intentkit.abstracts.graph import AgentContext, AgentError, AgentState
|
|
38
38
|
from intentkit.config.config import config
|
|
39
|
-
from intentkit.core.agent import agent_store
|
|
40
39
|
from intentkit.core.chat import clear_thread_memory
|
|
41
40
|
from intentkit.core.credit import expense_message, expense_skill
|
|
42
41
|
from intentkit.core.node import PreModelNode, post_model_node
|
|
@@ -56,7 +55,7 @@ from intentkit.models.chat import (
|
|
|
56
55
|
from intentkit.models.credit import CreditAccount, OwnerType
|
|
57
56
|
from intentkit.models.db import get_langgraph_checkpointer, get_session
|
|
58
57
|
from intentkit.models.llm import LLMModelInfo, LLMProvider, create_llm_model
|
|
59
|
-
from intentkit.models.skill import AgentSkillData, ChatSkillData
|
|
58
|
+
from intentkit.models.skill import AgentSkillData, ChatSkillData, Skill
|
|
60
59
|
from intentkit.models.user import User
|
|
61
60
|
from intentkit.utils.error import IntentKitAPIError
|
|
62
61
|
|
|
@@ -115,13 +114,13 @@ async def build_agent(
|
|
|
115
114
|
if hasattr(skill_module, "get_skills"):
|
|
116
115
|
# all
|
|
117
116
|
skill_tools = await skill_module.get_skills(
|
|
118
|
-
v, False,
|
|
117
|
+
v, False, agent_id=agent.id, agent=agent
|
|
119
118
|
)
|
|
120
119
|
if skill_tools and len(skill_tools) > 0:
|
|
121
120
|
tools.extend(skill_tools)
|
|
122
121
|
# private
|
|
123
122
|
skill_private_tools = await skill_module.get_skills(
|
|
124
|
-
v, True,
|
|
123
|
+
v, True, agent_id=agent.id, agent=agent
|
|
125
124
|
)
|
|
126
125
|
if skill_private_tools and len(skill_private_tools) > 0:
|
|
127
126
|
private_tools.extend(skill_private_tools)
|
|
@@ -333,6 +332,8 @@ async def stream_agent_raw(
|
|
|
333
332
|
model = await LLMModelInfo.get(agent.model)
|
|
334
333
|
|
|
335
334
|
payment_enabled = config.payment_enabled
|
|
335
|
+
if user_message.author_type == AuthorType.X402:
|
|
336
|
+
payment_enabled = False
|
|
336
337
|
|
|
337
338
|
# check user balance
|
|
338
339
|
if payment_enabled:
|
|
@@ -703,6 +704,9 @@ async def stream_agent_raw(
|
|
|
703
704
|
for skill_call in skill_calls:
|
|
704
705
|
if not skill_call["success"]:
|
|
705
706
|
continue
|
|
707
|
+
skill = await Skill.get(skill_call["name"])
|
|
708
|
+
if not skill:
|
|
709
|
+
continue
|
|
706
710
|
payment_event = await expense_skill(
|
|
707
711
|
session,
|
|
708
712
|
payer,
|
intentkit/core/scheduler.py
CHANGED
|
@@ -11,7 +11,6 @@ from apscheduler.triggers.cron import CronTrigger
|
|
|
11
11
|
from intentkit.core.agent import (
|
|
12
12
|
update_agent_action_cost,
|
|
13
13
|
update_agents_account_snapshot,
|
|
14
|
-
update_agents_assets,
|
|
15
14
|
update_agents_statistics,
|
|
16
15
|
)
|
|
17
16
|
from intentkit.core.credit import refill_all_free_credits
|
|
@@ -63,13 +62,14 @@ def create_scheduler(
|
|
|
63
62
|
)
|
|
64
63
|
|
|
65
64
|
# Update agent assets daily at UTC midnight
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
73
|
|
|
74
74
|
# Update agent action costs hourly at minute 40
|
|
75
75
|
scheduler.add_job(
|