intentkit 0.6.0.dev13__py3-none-any.whl → 0.6.0.dev14__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.

Files changed (61) hide show
  1. intentkit/__init__.py +1 -1
  2. intentkit/core/engine.py +2 -1
  3. intentkit/core/node.py +3 -1
  4. intentkit/skills/base.py +37 -17
  5. intentkit/skills/cryptocompare/fetch_news.py +2 -2
  6. intentkit/skills/cryptocompare/fetch_price.py +2 -2
  7. intentkit/skills/cryptocompare/fetch_top_exchanges.py +2 -2
  8. intentkit/skills/cryptocompare/fetch_top_market_cap.py +2 -2
  9. intentkit/skills/cryptocompare/fetch_top_volume.py +2 -2
  10. intentkit/skills/cryptocompare/fetch_trading_signals.py +2 -2
  11. intentkit/skills/defillama/base.py +3 -3
  12. intentkit/skills/enso/base.py +2 -2
  13. intentkit/skills/enso/networks.py +1 -1
  14. intentkit/skills/enso/route.py +1 -1
  15. intentkit/skills/enso/tokens.py +1 -1
  16. intentkit/skills/firecrawl/clear.py +1 -1
  17. intentkit/skills/firecrawl/crawl.py +2 -10
  18. intentkit/skills/firecrawl/query.py +4 -4
  19. intentkit/skills/firecrawl/scrape.py +2 -8
  20. intentkit/skills/heurist/image_generation_animagine_xl.py +1 -1
  21. intentkit/skills/heurist/image_generation_arthemy_comics.py +1 -1
  22. intentkit/skills/heurist/image_generation_arthemy_real.py +1 -1
  23. intentkit/skills/heurist/image_generation_braindance.py +1 -1
  24. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +1 -1
  25. intentkit/skills/heurist/image_generation_flux_1_dev.py +1 -1
  26. intentkit/skills/heurist/image_generation_sdxl.py +1 -1
  27. intentkit/skills/lifi/token_execute.py +1 -1
  28. intentkit/skills/openai/dalle_image_generation.py +1 -1
  29. intentkit/skills/openai/gpt_image_generation.py +1 -1
  30. intentkit/skills/openai/gpt_image_to_image.py +1 -1
  31. intentkit/skills/supabase/__init__.py +116 -0
  32. intentkit/skills/supabase/base.py +72 -0
  33. intentkit/skills/supabase/delete_data.py +102 -0
  34. intentkit/skills/supabase/fetch_data.py +120 -0
  35. intentkit/skills/supabase/insert_data.py +70 -0
  36. intentkit/skills/supabase/invoke_function.py +74 -0
  37. intentkit/skills/supabase/schema.json +168 -0
  38. intentkit/skills/supabase/supabase.svg +15 -0
  39. intentkit/skills/supabase/update_data.py +105 -0
  40. intentkit/skills/supabase/upsert_data.py +77 -0
  41. intentkit/skills/system/read_agent_api_key.py +1 -1
  42. intentkit/skills/system/regenerate_agent_api_key.py +1 -1
  43. intentkit/skills/token/base.py +1 -39
  44. intentkit/skills/twitter/follow_user.py +3 -3
  45. intentkit/skills/twitter/get_mentions.py +6 -6
  46. intentkit/skills/twitter/get_timeline.py +5 -5
  47. intentkit/skills/twitter/get_user_by_username.py +3 -3
  48. intentkit/skills/twitter/get_user_tweets.py +5 -5
  49. intentkit/skills/twitter/like_tweet.py +3 -3
  50. intentkit/skills/twitter/post_tweet.py +4 -4
  51. intentkit/skills/twitter/reply_tweet.py +4 -4
  52. intentkit/skills/twitter/retweet.py +3 -3
  53. intentkit/skills/twitter/search_tweets.py +5 -5
  54. intentkit/skills/unrealspeech/text_to_speech.py +1 -1
  55. intentkit/skills/web_scraper/document_indexer.py +2 -2
  56. intentkit/skills/web_scraper/scrape_and_index.py +8 -8
  57. intentkit/skills/web_scraper/website_indexer.py +4 -4
  58. {intentkit-0.6.0.dev13.dist-info → intentkit-0.6.0.dev14.dist-info}/METADATA +1 -1
  59. {intentkit-0.6.0.dev13.dist-info → intentkit-0.6.0.dev14.dist-info}/RECORD +61 -51
  60. {intentkit-0.6.0.dev13.dist-info → intentkit-0.6.0.dev14.dist-info}/WHEEL +0 -0
  61. {intentkit-0.6.0.dev13.dist-info → intentkit-0.6.0.dev14.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,105 @@
1
+ import logging
2
+ from typing import Any, Dict, Type
3
+
4
+ from langchain_core.runnables import RunnableConfig
5
+ from langchain_core.tools import ToolException
6
+ from pydantic import BaseModel, Field
7
+ from supabase import Client, create_client
8
+
9
+ from intentkit.skills.supabase.base import SupabaseBaseTool
10
+
11
+ NAME = "supabase_update_data"
12
+ PROMPT = "Update existing data in a Supabase table with filtering conditions."
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class SupabaseUpdateDataInput(BaseModel):
18
+ """Input for SupabaseUpdateData tool."""
19
+
20
+ table: str = Field(description="The name of the table to update data in")
21
+ data: Dict[str, Any] = Field(
22
+ description="The data to update (key-value pairs of columns and new values)"
23
+ )
24
+ filters: Dict[str, Any] = Field(
25
+ description="Dictionary of filters to identify which records to update (e.g., {'id': 123})"
26
+ )
27
+ returning: str = Field(
28
+ default="*", description="Columns to return after update (default: '*' for all)"
29
+ )
30
+
31
+
32
+ class SupabaseUpdateData(SupabaseBaseTool):
33
+ """Tool for updating data in Supabase tables.
34
+
35
+ This tool allows updating records in Supabase tables based on filter conditions.
36
+ """
37
+
38
+ name: str = NAME
39
+ description: str = PROMPT
40
+ args_schema: Type[BaseModel] = SupabaseUpdateDataInput
41
+
42
+ async def _arun(
43
+ self,
44
+ table: str,
45
+ data: Dict[str, Any],
46
+ filters: Dict[str, Any],
47
+ returning: str = "*",
48
+ config: RunnableConfig = None,
49
+ **kwargs,
50
+ ):
51
+ try:
52
+ context = self.context_from_config(config)
53
+
54
+ # Validate table access for public mode
55
+ self.validate_table_access(table, context)
56
+
57
+ supabase_url, supabase_key = self.get_supabase_config(context.config)
58
+
59
+ # Create Supabase client
60
+ supabase: Client = create_client(supabase_url, supabase_key)
61
+
62
+ # Start building the update query
63
+ query = supabase.table(table).update(data)
64
+
65
+ # Apply filters to identify which records to update
66
+ for column, value in filters.items():
67
+ if isinstance(value, dict):
68
+ # Handle complex filters like {'gte': 18}
69
+ for operator, filter_value in value.items():
70
+ if operator == "eq":
71
+ query = query.eq(column, filter_value)
72
+ elif operator == "neq":
73
+ query = query.neq(column, filter_value)
74
+ elif operator == "gt":
75
+ query = query.gt(column, filter_value)
76
+ elif operator == "gte":
77
+ query = query.gte(column, filter_value)
78
+ elif operator == "lt":
79
+ query = query.lt(column, filter_value)
80
+ elif operator == "lte":
81
+ query = query.lte(column, filter_value)
82
+ elif operator == "like":
83
+ query = query.like(column, filter_value)
84
+ elif operator == "ilike":
85
+ query = query.ilike(column, filter_value)
86
+ elif operator == "in":
87
+ query = query.in_(column, filter_value)
88
+ else:
89
+ logger.warning(f"Unknown filter operator: {operator}")
90
+ else:
91
+ # Simple equality filter
92
+ query = query.eq(column, value)
93
+
94
+ # Execute the update
95
+ response = query.execute()
96
+
97
+ return {
98
+ "success": True,
99
+ "data": response.data,
100
+ "count": len(response.data) if response.data else 0,
101
+ }
102
+
103
+ except Exception as e:
104
+ logger.error(f"Error updating data in Supabase: {str(e)}")
105
+ raise ToolException(f"Failed to update data in table '{table}': {str(e)}")
@@ -0,0 +1,77 @@
1
+ import logging
2
+ from typing import Any, Dict, List, Type, Union
3
+
4
+ from langchain_core.runnables import RunnableConfig
5
+ from langchain_core.tools import ToolException
6
+ from pydantic import BaseModel, Field
7
+ from supabase import Client, create_client
8
+
9
+ from intentkit.skills.supabase.base import SupabaseBaseTool
10
+
11
+ NAME = "supabase_upsert_data"
12
+ PROMPT = (
13
+ "Upsert (insert or update) data in a Supabase table based on conflict resolution."
14
+ )
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class SupabaseUpsertDataInput(BaseModel):
20
+ """Input for SupabaseUpsertData tool."""
21
+
22
+ table: str = Field(description="The name of the table to upsert data into")
23
+ data: Union[Dict[str, Any], List[Dict[str, Any]]] = Field(
24
+ description="The data to upsert. Can be a single object or a list of objects"
25
+ )
26
+ on_conflict: str = Field(
27
+ description="The column(s) to use for conflict resolution (e.g., 'id' or 'email,username')"
28
+ )
29
+ returning: str = Field(
30
+ default="*", description="Columns to return after upsert (default: '*' for all)"
31
+ )
32
+
33
+
34
+ class SupabaseUpsertData(SupabaseBaseTool):
35
+ """Tool for upserting data in Supabase tables.
36
+
37
+ This tool allows inserting new records or updating existing ones based on conflict resolution.
38
+ """
39
+
40
+ name: str = NAME
41
+ description: str = PROMPT
42
+ args_schema: Type[BaseModel] = SupabaseUpsertDataInput
43
+
44
+ async def _arun(
45
+ self,
46
+ table: str,
47
+ data: Union[Dict[str, Any], List[Dict[str, Any]]],
48
+ on_conflict: str,
49
+ returning: str = "*",
50
+ config: RunnableConfig = None,
51
+ **kwargs,
52
+ ):
53
+ try:
54
+ context = self.context_from_config(config)
55
+
56
+ # Validate table access for public mode
57
+ self.validate_table_access(table, context)
58
+
59
+ supabase_url, supabase_key = self.get_supabase_config(context.config)
60
+
61
+ # Create Supabase client
62
+ supabase: Client = create_client(supabase_url, supabase_key)
63
+
64
+ # Upsert data
65
+ response = (
66
+ supabase.table(table).upsert(data, on_conflict=on_conflict).execute()
67
+ )
68
+
69
+ return {
70
+ "success": True,
71
+ "data": response.data,
72
+ "count": len(response.data) if response.data else 0,
73
+ }
74
+
75
+ except Exception as e:
76
+ logger.error(f"Error upserting data in Supabase: {str(e)}")
77
+ raise ToolException(f"Failed to upsert data in table '{table}': {str(e)}")
@@ -40,7 +40,7 @@ class ReadAgentApiKey(SystemBaseTool):
40
40
  """Retrieve or generate an API key for the agent."""
41
41
  # Get context from runnable config to access agent.id
42
42
  context = self.context_from_config(config)
43
- agent_id = context.agent.id
43
+ agent_id = context.agent_id
44
44
 
45
45
  # Get agent data from skill store
46
46
  agent_data = await self.skill_store.get_agent_data(agent_id)
@@ -44,7 +44,7 @@ class RegenerateAgentApiKey(SystemBaseTool):
44
44
  """Generate and set a new API key for the agent."""
45
45
  # Get context from runnable config to access agent.id
46
46
  context = self.context_from_config(config)
47
- agent_id = context.agent.id
47
+ agent_id = context.agent_id
48
48
 
49
49
  # Get agent data from skill store
50
50
  agent_data = await self.skill_store.get_agent_data(agent_id)
@@ -1,10 +1,9 @@
1
1
  """Base class for token-related skills."""
2
2
 
3
3
  import logging
4
- from typing import Any, Dict, Optional
4
+ from typing import Any, Dict
5
5
 
6
6
  import aiohttp
7
- from langchain_core.runnables import RunnableConfig
8
7
 
9
8
  from intentkit.abstracts.skill import SkillStoreABC
10
9
  from intentkit.skills.base import IntentKitSkill, SkillContext
@@ -42,43 +41,6 @@ class TokenBaseTool(IntentKitSkill):
42
41
  return skill_config.get("api_key")
43
42
  return self.skill_store.get_system_config("moralis_api_key")
44
43
 
45
- def context_from_config(self, config: Optional[RunnableConfig] = None) -> Any:
46
- """Extract context from the runnable config."""
47
- if not config:
48
- logger.error("No config provided to context_from_config")
49
- return None
50
-
51
- if "configurable" not in config:
52
- logger.error("'configurable' not in config")
53
- return None
54
-
55
- if "agent" not in config["configurable"]:
56
- logger.error("'agent' not in config['configurable']")
57
- return None
58
-
59
- agent = config["configurable"].get("agent")
60
- category_config = None
61
-
62
- if agent.skills:
63
- category_config = agent.skills.get(self.category)
64
-
65
- if not category_config:
66
- category_config = getattr(agent, self.category + "_config", {})
67
-
68
- if not category_config:
69
- category_config = {}
70
-
71
- from intentkit.skills.base import SkillContext
72
-
73
- context = SkillContext(
74
- agent=agent,
75
- config=category_config,
76
- user_id=config["configurable"].get("user_id"),
77
- entrypoint=config["configurable"].get("entrypoint"),
78
- )
79
-
80
- return context
81
-
82
44
  def _prepare_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
83
45
  """Convert boolean values to lowercase strings for API compatibility.
84
46
 
@@ -41,7 +41,7 @@ class TwitterFollowUser(TwitterBaseTool):
41
41
  try:
42
42
  context = self.context_from_config(config)
43
43
  twitter = get_twitter_client(
44
- agent_id=context.agent.id,
44
+ agent_id=context.agent_id,
45
45
  skill_store=self.skill_store,
46
46
  config=context.config,
47
47
  )
@@ -50,7 +50,7 @@ class TwitterFollowUser(TwitterBaseTool):
50
50
  # Check rate limit only when not using OAuth
51
51
  if not twitter.use_key:
52
52
  await self.check_rate_limit(
53
- context.agent.id, max_requests=5, interval=15
53
+ context.agent_id, max_requests=5, interval=15
54
54
  )
55
55
 
56
56
  # Follow the user using tweepy client
@@ -66,4 +66,4 @@ class TwitterFollowUser(TwitterBaseTool):
66
66
 
67
67
  except Exception as e:
68
68
  logger.error("Error following user: %s", str(e))
69
- raise type(e)(f"[agent:{context.agent.id}]: {e}") from e
69
+ raise type(e)(f"[agent:{context.agent_id}]: {e}") from e
@@ -45,7 +45,7 @@ class TwitterGetMentions(TwitterBaseTool):
45
45
  try:
46
46
  context = self.context_from_config(config)
47
47
  twitter = get_twitter_client(
48
- agent_id=context.agent.id,
48
+ agent_id=context.agent_id,
49
49
  skill_store=self.skill_store,
50
50
  config=context.config,
51
51
  )
@@ -56,14 +56,14 @@ class TwitterGetMentions(TwitterBaseTool):
56
56
  # Check rate limit only when not using OAuth
57
57
  if not twitter.use_key:
58
58
  await self.check_rate_limit(
59
- context.agent.id,
59
+ context.agent_id,
60
60
  max_requests=1,
61
61
  interval=59, # TODO: tmp to 59, back to 240 later
62
62
  )
63
63
 
64
64
  # get since id from store
65
65
  last = await self.skill_store.get_agent_skill_data(
66
- context.agent.id, self.name, "last"
66
+ context.agent_id, self.name, "last"
67
67
  )
68
68
  last = last or {}
69
69
  max_results = 10
@@ -114,11 +114,11 @@ class TwitterGetMentions(TwitterBaseTool):
114
114
  if mentions.get("meta") and mentions["meta"].get("newest_id"):
115
115
  last["since_id"] = mentions["meta"].get("newest_id")
116
116
  await self.skill_store.save_agent_skill_data(
117
- context.agent.id, self.name, "last", last
117
+ context.agent_id, self.name, "last", last
118
118
  )
119
119
 
120
120
  return mentions
121
121
 
122
122
  except Exception as e:
123
- logger.error(f"[agent:{context.agent.id}]: {e}")
124
- raise type(e)(f"[agent:{context.agent.id}]: {e}") from e
123
+ logger.error(f"[agent:{context.agent_id}]: {e}")
124
+ raise type(e)(f"[agent:{context.agent_id}]: {e}") from e
@@ -44,7 +44,7 @@ class TwitterGetTimeline(TwitterBaseTool):
44
44
 
45
45
  context = self.context_from_config(config)
46
46
  twitter = get_twitter_client(
47
- agent_id=context.agent.id,
47
+ agent_id=context.agent_id,
48
48
  skill_store=self.skill_store,
49
49
  config=context.config,
50
50
  )
@@ -53,12 +53,12 @@ class TwitterGetTimeline(TwitterBaseTool):
53
53
  # Check rate limit only when not using OAuth
54
54
  if not twitter.use_key:
55
55
  await self.check_rate_limit(
56
- context.agent.id, max_requests=3, interval=60 * 24
56
+ context.agent_id, max_requests=3, interval=60 * 24
57
57
  )
58
58
 
59
59
  # get since id from store
60
60
  last = await self.skill_store.get_agent_skill_data(
61
- context.agent.id, self.name, "last"
61
+ context.agent_id, self.name, "last"
62
62
  )
63
63
  last = last or {}
64
64
  since_id = last.get("since_id")
@@ -101,11 +101,11 @@ class TwitterGetTimeline(TwitterBaseTool):
101
101
  if timeline.get("meta") and timeline["meta"].get("newest_id"):
102
102
  last["since_id"] = timeline["meta"]["newest_id"]
103
103
  await self.skill_store.save_agent_skill_data(
104
- context.agent.id, self.name, "last", last
104
+ context.agent_id, self.name, "last", last
105
105
  )
106
106
 
107
107
  return timeline
108
108
 
109
109
  except Exception as e:
110
110
  logger.error("Error getting timeline: %s", str(e))
111
- raise type(e)(f"[agent:{context.agent.id}]: {e}") from e
111
+ raise type(e)(f"[agent:{context.agent_id}]: {e}") from e
@@ -42,7 +42,7 @@ class TwitterGetUserByUsername(TwitterBaseTool):
42
42
  try:
43
43
  context = self.context_from_config(config)
44
44
  twitter = get_twitter_client(
45
- agent_id=context.agent.id,
45
+ agent_id=context.agent_id,
46
46
  skill_store=self.skill_store,
47
47
  config=context.config,
48
48
  )
@@ -51,7 +51,7 @@ class TwitterGetUserByUsername(TwitterBaseTool):
51
51
  # Check rate limit only when not using OAuth
52
52
  if not twitter.use_key:
53
53
  await self.check_rate_limit(
54
- context.agent.id, max_requests=3, interval=60 * 24
54
+ context.agent_id, max_requests=3, interval=60 * 24
55
55
  )
56
56
 
57
57
  user_data = await client.get_user(
@@ -81,4 +81,4 @@ class TwitterGetUserByUsername(TwitterBaseTool):
81
81
 
82
82
  except Exception as e:
83
83
  logger.error(f"Error getting user by username: {str(e)}")
84
- raise type(e)(f"[agent:{context.agent.id}]: {e}") from e
84
+ raise type(e)(f"[agent:{context.agent_id}]: {e}") from e
@@ -58,7 +58,7 @@ class TwitterGetUserTweets(TwitterBaseTool):
58
58
 
59
59
  context = self.context_from_config(config)
60
60
  twitter = get_twitter_client(
61
- agent_id=context.agent.id,
61
+ agent_id=context.agent_id,
62
62
  skill_store=self.skill_store,
63
63
  config=context.config,
64
64
  )
@@ -67,12 +67,12 @@ class TwitterGetUserTweets(TwitterBaseTool):
67
67
  # Check rate limit only when not using OAuth
68
68
  if not twitter.use_key:
69
69
  await self.check_rate_limit(
70
- context.agent.id, max_requests=3, interval=60 * 24
70
+ context.agent_id, max_requests=3, interval=60 * 24
71
71
  )
72
72
 
73
73
  # get since id from store
74
74
  last = await self.skill_store.get_agent_skill_data(
75
- context.agent.id, self.name, user_id
75
+ context.agent_id, self.name, user_id
76
76
  )
77
77
  last = last or {}
78
78
  since_id = last.get("since_id")
@@ -113,11 +113,11 @@ class TwitterGetUserTweets(TwitterBaseTool):
113
113
  if tweets.get("meta") and tweets["meta"].get("newest_id"):
114
114
  last["since_id"] = tweets["meta"]["newest_id"]
115
115
  await self.skill_store.save_agent_skill_data(
116
- context.agent.id, self.name, user_id, last
116
+ context.agent_id, self.name, user_id, last
117
117
  )
118
118
 
119
119
  return tweets
120
120
 
121
121
  except Exception as e:
122
122
  logger.error("Error getting user tweets: %s", str(e))
123
- raise type(e)(f"[agent:{context.agent.id}]: {e}") from e
123
+ raise type(e)(f"[agent:{context.agent_id}]: {e}") from e
@@ -39,7 +39,7 @@ class TwitterLikeTweet(TwitterBaseTool):
39
39
  try:
40
40
  context = self.context_from_config(config)
41
41
  twitter = get_twitter_client(
42
- agent_id=context.agent.id,
42
+ agent_id=context.agent_id,
43
43
  skill_store=self.skill_store,
44
44
  config=context.config,
45
45
  )
@@ -48,7 +48,7 @@ class TwitterLikeTweet(TwitterBaseTool):
48
48
  # Check rate limit only when not using OAuth
49
49
  if not twitter.use_key:
50
50
  await self.check_rate_limit(
51
- context.agent.id, max_requests=100, interval=1440
51
+ context.agent_id, max_requests=100, interval=1440
52
52
  )
53
53
 
54
54
  # Like the tweet using tweepy client
@@ -62,4 +62,4 @@ class TwitterLikeTweet(TwitterBaseTool):
62
62
 
63
63
  except Exception as e:
64
64
  logger.error(f"Error liking tweet: {str(e)}")
65
- raise type(e)(f"[agent:{context.agent.id}]: {e}") from e
65
+ raise type(e)(f"[agent:{context.agent_id}]: {e}") from e
@@ -54,7 +54,7 @@ class TwitterPostTweet(TwitterBaseTool):
54
54
  try:
55
55
  context = self.context_from_config(config)
56
56
  twitter = get_twitter_client(
57
- agent_id=context.agent.id,
57
+ agent_id=context.agent_id,
58
58
  skill_store=self.skill_store,
59
59
  config=context.config,
60
60
  )
@@ -63,7 +63,7 @@ class TwitterPostTweet(TwitterBaseTool):
63
63
  # Check rate limit only when not using OAuth
64
64
  if not twitter.use_key:
65
65
  await self.check_rate_limit(
66
- context.agent.id, max_requests=24, interval=1440
66
+ context.agent_id, max_requests=24, interval=1440
67
67
  )
68
68
 
69
69
  media_ids = []
@@ -71,7 +71,7 @@ class TwitterPostTweet(TwitterBaseTool):
71
71
  # Handle image upload if provided
72
72
  if image:
73
73
  # Use the TwitterClient method to upload the image
74
- media_ids = await twitter.upload_media(context.agent.id, image)
74
+ media_ids = await twitter.upload_media(context.agent_id, image)
75
75
 
76
76
  # Post tweet using tweepy client
77
77
  tweet_params = {"text": text, "user_auth": twitter.use_key}
@@ -87,4 +87,4 @@ class TwitterPostTweet(TwitterBaseTool):
87
87
 
88
88
  except Exception as e:
89
89
  logger.error(f"Error posting tweet: {str(e)}")
90
- raise type(e)(f"[agent:{context.agent.id}]: {e}") from e
90
+ raise type(e)(f"[agent:{context.agent_id}]: {e}") from e
@@ -56,7 +56,7 @@ class TwitterReplyTweet(TwitterBaseTool):
56
56
  try:
57
57
  context = self.context_from_config(config)
58
58
  twitter = get_twitter_client(
59
- agent_id=context.agent.id,
59
+ agent_id=context.agent_id,
60
60
  skill_store=self.skill_store,
61
61
  config=context.config,
62
62
  )
@@ -65,7 +65,7 @@ class TwitterReplyTweet(TwitterBaseTool):
65
65
  # Check rate limit only when not using OAuth
66
66
  if not twitter.use_key:
67
67
  await self.check_rate_limit(
68
- context.agent.id, max_requests=48, interval=1440
68
+ context.agent_id, max_requests=48, interval=1440
69
69
  )
70
70
 
71
71
  media_ids = []
@@ -73,7 +73,7 @@ class TwitterReplyTweet(TwitterBaseTool):
73
73
  # Handle image upload if provided
74
74
  if image:
75
75
  # Use the TwitterClient method to upload the image
76
- media_ids = await twitter.upload_media(context.agent.id, image)
76
+ media_ids = await twitter.upload_media(context.agent_id, image)
77
77
 
78
78
  # Post reply tweet using tweepy client
79
79
  tweet_params = {
@@ -95,4 +95,4 @@ class TwitterReplyTweet(TwitterBaseTool):
95
95
 
96
96
  except Exception as e:
97
97
  logger.error(f"Error replying to tweet: {str(e)}")
98
- raise type(e)(f"[agent:{context.agent.id}]: {e}") from e
98
+ raise type(e)(f"[agent:{context.agent_id}]: {e}") from e
@@ -39,7 +39,7 @@ class TwitterRetweet(TwitterBaseTool):
39
39
  try:
40
40
  context = self.context_from_config(config)
41
41
  twitter = get_twitter_client(
42
- agent_id=context.agent.id,
42
+ agent_id=context.agent_id,
43
43
  skill_store=self.skill_store,
44
44
  config=context.config,
45
45
  )
@@ -48,7 +48,7 @@ class TwitterRetweet(TwitterBaseTool):
48
48
  # Check rate limit only when not using OAuth
49
49
  if not twitter.use_key:
50
50
  await self.check_rate_limit(
51
- context.agent.id, max_requests=5, interval=15
51
+ context.agent_id, max_requests=5, interval=15
52
52
  )
53
53
 
54
54
  # Get authenticated user's ID
@@ -73,4 +73,4 @@ class TwitterRetweet(TwitterBaseTool):
73
73
 
74
74
  except Exception as e:
75
75
  logger.error(f"Error retweeting: {str(e)}")
76
- raise type(e)(f"[agent:{context.agent.id}]: {e}") from e
76
+ raise type(e)(f"[agent:{context.agent_id}]: {e}") from e
@@ -41,7 +41,7 @@ class TwitterSearchTweets(TwitterBaseTool):
41
41
  try:
42
42
  context = self.context_from_config(config)
43
43
  twitter = get_twitter_client(
44
- agent_id=context.agent.id,
44
+ agent_id=context.agent_id,
45
45
  skill_store=self.skill_store,
46
46
  config=context.config,
47
47
  )
@@ -50,12 +50,12 @@ class TwitterSearchTweets(TwitterBaseTool):
50
50
  # Check rate limit only when not using OAuth
51
51
  if not twitter.use_key:
52
52
  await self.check_rate_limit(
53
- context.agent.id, max_requests=3, interval=60 * 24
53
+ context.agent_id, max_requests=3, interval=60 * 24
54
54
  )
55
55
 
56
56
  # Get since_id from store to avoid duplicate results
57
57
  last = await self.skill_store.get_agent_skill_data(
58
- context.agent.id, self.name, query
58
+ context.agent_id, self.name, query
59
59
  )
60
60
  last = last or {}
61
61
  since_id = last.get("since_id")
@@ -105,11 +105,11 @@ class TwitterSearchTweets(TwitterBaseTool):
105
105
  last["since_id"] = tweets["meta"]["newest_id"]
106
106
  last["timestamp"] = datetime.datetime.now().isoformat()
107
107
  await self.skill_store.save_agent_skill_data(
108
- context.agent.id, self.name, query, last
108
+ context.agent_id, self.name, query, last
109
109
  )
110
110
 
111
111
  return tweets
112
112
 
113
113
  except Exception as e:
114
114
  logger.error(f"Error searching tweets: {str(e)}")
115
- raise type(e)(f"[agent:{context.agent.id}]: {e}") from e
115
+ raise type(e)(f"[agent:{context.agent_id}]: {e}") from e
@@ -81,7 +81,7 @@ class TextToSpeech(UnrealSpeechBaseTool):
81
81
  # If no API key in config, try to get it from skill store
82
82
  if not api_key:
83
83
  try:
84
- agent_id = context.agent.id if context and context.agent else "default"
84
+ agent_id = context.agent_id
85
85
  api_key_data = await self.skill_store.get_agent_data(
86
86
  agent_id, "unrealspeech_api_key"
87
87
  )
@@ -85,10 +85,10 @@ class DocumentIndexer(WebScraperBaseTool):
85
85
  raise ValueError("Configuration is required but not provided")
86
86
 
87
87
  context = self.context_from_config(config)
88
- if not context or not context.agent or not context.agent.id:
88
+ if not context or not context.agent_id:
89
89
  raise ValueError("Agent ID is required but not found in configuration")
90
90
 
91
- agent_id = context.agent.id
91
+ agent_id = context.agent_id
92
92
 
93
93
  logger.info(f"[{agent_id}] Starting document indexing for title: '{title}'")
94
94
 
@@ -85,10 +85,10 @@ class ScrapeAndIndex(WebScraperBaseTool):
85
85
  raise ValueError("Configuration is required but not provided")
86
86
 
87
87
  context = self.context_from_config(config)
88
- if not context or not context.agent or not context.agent.id:
88
+ if not context or not context.agent_id:
89
89
  raise ValueError("Agent ID is required but not found in configuration")
90
90
 
91
- agent_id = context.agent.id
91
+ agent_id = context.agent_id
92
92
 
93
93
  logger.info(
94
94
  f"[{agent_id}] Starting scrape and index operation with {len(urls)} URLs"
@@ -149,8 +149,8 @@ class ScrapeAndIndex(WebScraperBaseTool):
149
149
  try:
150
150
  if config:
151
151
  context = self.context_from_config(config)
152
- if context and context.agent and context.agent.id:
153
- agent_id = context.agent.id
152
+ if context and context.agent_id:
153
+ agent_id = context.agent_id
154
154
  except Exception:
155
155
  pass
156
156
 
@@ -187,10 +187,10 @@ class QueryIndexedContent(WebScraperBaseTool):
187
187
  raise ValueError("Configuration is required but not provided")
188
188
 
189
189
  context = self.context_from_config(config)
190
- if not context or not context.agent or not context.agent.id:
190
+ if not context or not context.agent_id:
191
191
  raise ValueError("Agent ID is required but not found in configuration")
192
192
 
193
- agent_id = context.agent.id
193
+ agent_id = context.agent_id
194
194
 
195
195
  logger.info(f"[{agent_id}] Starting query operation: '{query}'")
196
196
 
@@ -251,8 +251,8 @@ class QueryIndexedContent(WebScraperBaseTool):
251
251
  try:
252
252
  if config:
253
253
  context = self.context_from_config(config)
254
- if context and context.agent and context.agent.id:
255
- agent_id = context.agent.id
254
+ if context and context.agent_id:
255
+ agent_id = context.agent_id
256
256
  except Exception:
257
257
  pass
258
258