intentkit 0.6.9.dev2__py3-none-any.whl → 0.6.10.dev1__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/graph.py +17 -2
- intentkit/core/engine.py +29 -30
- intentkit/core/node.py +10 -20
- intentkit/models/agent.py +3 -0
- intentkit/models/chat.py +9 -1
- intentkit/skills/acolyt/ask.py +2 -5
- intentkit/skills/acolyt/base.py +16 -6
- intentkit/skills/aixbt/__init__.py +3 -7
- intentkit/skills/aixbt/projects.py +12 -36
- intentkit/skills/allora/base.py +16 -6
- intentkit/skills/allora/price.py +2 -4
- intentkit/skills/base.py +8 -1
- intentkit/skills/carv/base.py +12 -10
- intentkit/skills/carv/fetch_news.py +90 -92
- intentkit/skills/carv/onchain_query.py +162 -164
- intentkit/skills/carv/token_info_and_price.py +108 -110
- intentkit/skills/chainlist/chain_lookup.py +1 -2
- intentkit/skills/common/current_time.py +1 -2
- intentkit/skills/cookiefun/base.py +20 -12
- intentkit/skills/cookiefun/get_account_details.py +1 -3
- intentkit/skills/cookiefun/get_account_feed.py +1 -3
- intentkit/skills/cookiefun/get_account_smart_followers.py +1 -3
- intentkit/skills/cookiefun/get_sectors.py +2 -3
- intentkit/skills/cookiefun/search_accounts.py +1 -3
- intentkit/skills/cryptocompare/fetch_news.py +3 -4
- intentkit/skills/cryptocompare/fetch_price.py +3 -4
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +3 -4
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +3 -4
- intentkit/skills/cryptocompare/fetch_top_volume.py +3 -4
- intentkit/skills/cryptocompare/fetch_trading_signals.py +3 -4
- intentkit/skills/cryptopanic/base.py +13 -9
- intentkit/skills/cryptopanic/fetch_crypto_news.py +150 -153
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +133 -136
- intentkit/skills/dapplooker/base.py +16 -6
- intentkit/skills/dapplooker/dapplooker_token_data.py +2 -4
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +2 -3
- intentkit/skills/defillama/coins/fetch_block.py +2 -3
- intentkit/skills/defillama/coins/fetch_current_prices.py +2 -5
- intentkit/skills/defillama/coins/fetch_first_price.py +2 -5
- intentkit/skills/defillama/coins/fetch_historical_prices.py +2 -3
- intentkit/skills/defillama/coins/fetch_price_chart.py +2 -5
- intentkit/skills/defillama/coins/fetch_price_percentage.py +2 -5
- intentkit/skills/defillama/fees/fetch_fees_overview.py +2 -3
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +2 -3
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +2 -3
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +2 -3
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +2 -3
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +2 -5
- intentkit/skills/defillama/tvl/fetch_chains.py +2 -3
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +2 -3
- intentkit/skills/defillama/tvl/fetch_protocol.py +2 -5
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +2 -5
- intentkit/skills/defillama/tvl/fetch_protocols.py +2 -3
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +2 -3
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +2 -5
- intentkit/skills/defillama/volumes/fetch_options_overview.py +2 -3
- intentkit/skills/defillama/yields/fetch_pool_chart.py +2 -5
- intentkit/skills/defillama/yields/fetch_pools.py +2 -3
- intentkit/skills/dune_analytics/base.py +15 -9
- intentkit/skills/dune_analytics/fetch_kol_buys.py +125 -128
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +234 -237
- intentkit/skills/elfa/base.py +16 -6
- intentkit/skills/elfa/mention.py +2 -7
- intentkit/skills/elfa/stats.py +2 -6
- intentkit/skills/elfa/tokens.py +1 -4
- intentkit/skills/enso/base.py +25 -13
- intentkit/skills/enso/best_yield.py +1 -4
- intentkit/skills/enso/networks.py +2 -5
- intentkit/skills/enso/prices.py +1 -5
- intentkit/skills/enso/route.py +2 -5
- intentkit/skills/enso/tokens.py +1 -4
- intentkit/skills/enso/wallet.py +3 -9
- intentkit/skills/firecrawl/base.py +16 -6
- intentkit/skills/firecrawl/clear.py +1 -3
- intentkit/skills/firecrawl/crawl.py +7 -8
- intentkit/skills/firecrawl/query.py +7 -9
- intentkit/skills/firecrawl/scrape.py +7 -8
- intentkit/skills/github/github_search.py +1 -3
- intentkit/skills/heurist/base.py +15 -0
- intentkit/skills/heurist/image_generation_animagine_xl.py +3 -4
- intentkit/skills/heurist/image_generation_arthemy_comics.py +3 -4
- intentkit/skills/heurist/image_generation_arthemy_real.py +3 -4
- intentkit/skills/heurist/image_generation_braindance.py +3 -4
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +3 -4
- intentkit/skills/heurist/image_generation_flux_1_dev.py +3 -4
- intentkit/skills/heurist/image_generation_sdxl.py +3 -4
- intentkit/skills/http/get.py +0 -2
- intentkit/skills/http/post.py +0 -2
- intentkit/skills/http/put.py +0 -2
- intentkit/skills/lifi/token_execute.py +1 -3
- intentkit/skills/lifi/token_quote.py +0 -2
- intentkit/skills/moralis/base.py +15 -1
- intentkit/skills/nation/nft_check.py +2 -5
- intentkit/skills/openai/base.py +14 -5
- intentkit/skills/openai/dalle_image_generation.py +6 -5
- intentkit/skills/openai/gpt_image_generation.py +6 -5
- intentkit/skills/openai/gpt_image_to_image.py +6 -5
- intentkit/skills/openai/image_to_text.py +6 -6
- intentkit/skills/portfolio/base.py +4 -3
- intentkit/skills/portfolio/token_balances.py +2 -4
- intentkit/skills/portfolio/wallet_approvals.py +2 -4
- intentkit/skills/portfolio/wallet_defi_positions.py +3 -4
- intentkit/skills/portfolio/wallet_history.py +2 -4
- intentkit/skills/portfolio/wallet_net_worth.py +2 -4
- intentkit/skills/portfolio/wallet_nfts.py +2 -4
- intentkit/skills/portfolio/wallet_profitability.py +2 -4
- intentkit/skills/portfolio/wallet_profitability_summary.py +2 -4
- intentkit/skills/portfolio/wallet_stats.py +2 -4
- intentkit/skills/portfolio/wallet_swaps.py +2 -4
- intentkit/skills/slack/base.py +18 -0
- intentkit/skills/slack/get_channel.py +3 -4
- intentkit/skills/slack/get_message.py +3 -4
- intentkit/skills/slack/schedule_message.py +3 -4
- intentkit/skills/slack/send_message.py +3 -4
- intentkit/skills/supabase/delete_data.py +3 -6
- intentkit/skills/supabase/fetch_data.py +3 -6
- intentkit/skills/supabase/insert_data.py +3 -6
- intentkit/skills/supabase/invoke_function.py +3 -6
- intentkit/skills/supabase/update_data.py +3 -6
- intentkit/skills/supabase/upsert_data.py +3 -6
- intentkit/skills/system/add_autonomous_task.py +1 -3
- intentkit/skills/system/delete_autonomous_task.py +1 -3
- intentkit/skills/system/edit_autonomous_task.py +1 -3
- intentkit/skills/system/list_autonomous_tasks.py +1 -3
- intentkit/skills/system/read_agent_api_key.py +2 -3
- intentkit/skills/system/regenerate_agent_api_key.py +2 -5
- intentkit/skills/tavily/base.py +14 -5
- intentkit/skills/tavily/tavily_extract.py +7 -8
- intentkit/skills/tavily/tavily_search.py +11 -9
- intentkit/skills/token/base.py +4 -6
- intentkit/skills/token/erc20_transfers.py +2 -4
- intentkit/skills/token/token_analytics.py +2 -4
- intentkit/skills/token/token_price.py +2 -4
- intentkit/skills/token/token_search.py +2 -4
- intentkit/skills/twitter/base.py +41 -0
- intentkit/skills/twitter/follow_user.py +4 -4
- intentkit/skills/twitter/get_mentions.py +4 -4
- intentkit/skills/twitter/get_timeline.py +4 -4
- intentkit/skills/twitter/get_user_by_username.py +4 -4
- intentkit/skills/twitter/get_user_tweets.py +4 -4
- intentkit/skills/twitter/like_tweet.py +4 -4
- intentkit/skills/twitter/post_tweet.py +3 -4
- intentkit/skills/twitter/reply_tweet.py +3 -4
- intentkit/skills/twitter/retweet.py +4 -4
- intentkit/skills/twitter/search_tweets.py +4 -4
- intentkit/skills/unrealspeech/base.py +16 -0
- intentkit/skills/unrealspeech/text_to_speech.py +4 -4
- intentkit/skills/venice_audio/base.py +11 -9
- intentkit/skills/venice_audio/venice_audio.py +238 -240
- intentkit/skills/venice_image/base.py +23 -19
- intentkit/skills/venice_image/image_enhance/image_enhance.py +78 -80
- intentkit/skills/venice_image/image_generation/image_generation_base.py +115 -117
- intentkit/skills/venice_image/image_upscale/image_upscale.py +88 -90
- intentkit/skills/venice_image/image_vision/image_vision.py +98 -100
- intentkit/skills/web_scraper/document_indexer.py +3 -5
- intentkit/skills/web_scraper/scrape_and_index.py +14 -17
- intentkit/skills/web_scraper/website_indexer.py +8 -10
- intentkit/skills/xmtp/README.md +110 -0
- intentkit/skills/xmtp/__init__.py +82 -0
- intentkit/skills/xmtp/base.py +13 -0
- intentkit/skills/xmtp/schema.json +41 -0
- intentkit/skills/xmtp/transfer.py +170 -0
- intentkit/skills/xmtp/xmtp.svg +26 -0
- {intentkit-0.6.9.dev2.dist-info → intentkit-0.6.10.dev1.dist-info}/METADATA +3 -3
- {intentkit-0.6.9.dev2.dist-info → intentkit-0.6.10.dev1.dist-info}/RECORD +168 -162
- {intentkit-0.6.9.dev2.dist-info → intentkit-0.6.10.dev1.dist-info}/WHEEL +0 -0
- {intentkit-0.6.9.dev2.dist-info → intentkit-0.6.10.dev1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,100 +1,98 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from typing import Any, Type
|
|
3
|
-
|
|
4
|
-
from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
from intentkit.skills.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
await
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
"error": f"An unexpected error occurred: {str(e)}",
|
|
100
|
-
}
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any, Type
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, HttpUrl
|
|
5
|
+
|
|
6
|
+
from intentkit.skills.base import ToolException
|
|
7
|
+
from intentkit.skills.venice_image.image_vision.image_vision_base import (
|
|
8
|
+
VeniceImageVisionBaseTool,
|
|
9
|
+
)
|
|
10
|
+
from intentkit.skills.venice_image.image_vision.image_vision_input import (
|
|
11
|
+
VeniceImageVision,
|
|
12
|
+
)
|
|
13
|
+
from intentkit.skills.venice_image.utils import fetch_image_as_base64
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ImageVision(VeniceImageVisionBaseTool):
|
|
19
|
+
"""
|
|
20
|
+
Describes an image provided via URL using the Venice AI API.
|
|
21
|
+
Ideal for understanding the content of an existing image.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
name: str = "venice_image_vision"
|
|
25
|
+
description: str = (
|
|
26
|
+
"Describes an image from a URL using Venice AI.\n"
|
|
27
|
+
"Provide the public URL of the image to describe.\n"
|
|
28
|
+
"Returns a descriptive text of the image."
|
|
29
|
+
)
|
|
30
|
+
args_schema: Type[BaseModel] = VeniceImageVision
|
|
31
|
+
# No model_id needed for the generic vision endpoint currently
|
|
32
|
+
|
|
33
|
+
async def _arun(
|
|
34
|
+
self,
|
|
35
|
+
image_url: HttpUrl,
|
|
36
|
+
**kwargs,
|
|
37
|
+
) -> dict[str, Any]:
|
|
38
|
+
try:
|
|
39
|
+
context = self.get_context()
|
|
40
|
+
|
|
41
|
+
await self.apply_venice_rate_limit(context)
|
|
42
|
+
|
|
43
|
+
image_base64 = await fetch_image_as_base64(image_url)
|
|
44
|
+
if not image_base64:
|
|
45
|
+
error_msg = f"Failed to fetch or validate image from URL: {image_url}"
|
|
46
|
+
logger.error(error_msg)
|
|
47
|
+
return {"success": False, "error": error_msg, "result": None}
|
|
48
|
+
|
|
49
|
+
payload = {
|
|
50
|
+
"model": "qwen-2.5-vl",
|
|
51
|
+
"messages": [
|
|
52
|
+
{
|
|
53
|
+
"role": "system",
|
|
54
|
+
"content": [
|
|
55
|
+
{
|
|
56
|
+
"type": "text",
|
|
57
|
+
"text": (
|
|
58
|
+
"You are an AI model that provides detailed descriptions of images. "
|
|
59
|
+
"When given an image, you must respond with a description that is as comprehensive and detailed as possible. "
|
|
60
|
+
"Focus on identifying all objects, colors, textures, and any other relevant features present in the image. "
|
|
61
|
+
"Provide a thorough and exhaustive account of what is visible in the image."
|
|
62
|
+
),
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"role": "user",
|
|
68
|
+
"content": [
|
|
69
|
+
{
|
|
70
|
+
"type": "text",
|
|
71
|
+
"text": (
|
|
72
|
+
"Provide an extremely detailed description of the image, focusing on every discernible aspect. "
|
|
73
|
+
"Include information about objects, colors, textures, lighting conditions, artistic style (if applicable), "
|
|
74
|
+
"composition, and any other relevant details that would allow someone to accurately understand and potentially "
|
|
75
|
+
"recreate the image. Be as thorough and comprehensive as possible."
|
|
76
|
+
),
|
|
77
|
+
},
|
|
78
|
+
{"type": "image_url", "image_url": {"url": str(image_url)}},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
result, error = await self.post("api/v1/chat/completions", payload, context)
|
|
85
|
+
if error:
|
|
86
|
+
raise ToolException(f"Venice Image Vision API error: {error}")
|
|
87
|
+
return result
|
|
88
|
+
except ToolException as e:
|
|
89
|
+
return {
|
|
90
|
+
"success": False,
|
|
91
|
+
"error": f"An unexpected error occurred: {str(e)}",
|
|
92
|
+
}
|
|
93
|
+
except Exception as e:
|
|
94
|
+
logger.error(f"Error in {self.name}: {str(e)}")
|
|
95
|
+
return {
|
|
96
|
+
"success": False,
|
|
97
|
+
"error": f"An unexpected error occurred: {str(e)}",
|
|
98
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from typing import Type
|
|
3
3
|
|
|
4
|
-
from langchain_core.runnables import RunnableConfig
|
|
5
4
|
from pydantic import BaseModel, Field
|
|
6
5
|
|
|
7
6
|
from intentkit.skills.web_scraper.base import WebScraperBaseTool
|
|
@@ -76,15 +75,14 @@ class DocumentIndexer(WebScraperBaseTool):
|
|
|
76
75
|
chunk_size: int = 1000,
|
|
77
76
|
chunk_overlap: int = 200,
|
|
78
77
|
tags: str = "",
|
|
79
|
-
config: RunnableConfig = None,
|
|
80
78
|
**kwargs,
|
|
81
79
|
) -> str:
|
|
82
80
|
"""Add text content to the vector database."""
|
|
83
81
|
# Get agent context - throw error if not available
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
# Configuration is always available in new runtime
|
|
83
|
+
pass
|
|
86
84
|
|
|
87
|
-
context = self.
|
|
85
|
+
context = self.get_context()
|
|
88
86
|
if not context or not context.agent_id:
|
|
89
87
|
raise ValueError("Agent ID is required but not found in configuration")
|
|
90
88
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from typing import List, Type
|
|
3
3
|
|
|
4
|
-
from langchain_core.runnables import RunnableConfig
|
|
5
4
|
from pydantic import BaseModel, Field
|
|
6
5
|
|
|
7
6
|
from intentkit.skills.web_scraper.base import WebScraperBaseTool
|
|
@@ -75,16 +74,15 @@ class ScrapeAndIndex(WebScraperBaseTool):
|
|
|
75
74
|
urls: List[str],
|
|
76
75
|
chunk_size: int = DEFAULT_CHUNK_SIZE,
|
|
77
76
|
chunk_overlap: int = DEFAULT_CHUNK_OVERLAP,
|
|
78
|
-
config: RunnableConfig = None,
|
|
79
77
|
**kwargs,
|
|
80
78
|
) -> str:
|
|
81
79
|
"""Scrape URLs and index content into vector store."""
|
|
82
80
|
try:
|
|
83
81
|
# Get agent context - throw error if not available
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
# Configuration is always available in new runtime
|
|
83
|
+
pass
|
|
86
84
|
|
|
87
|
-
context = self.
|
|
85
|
+
context = self.get_context()
|
|
88
86
|
if not context or not context.agent_id:
|
|
89
87
|
raise ValueError("Agent ID is required but not found in configuration")
|
|
90
88
|
|
|
@@ -147,10 +145,10 @@ class ScrapeAndIndex(WebScraperBaseTool):
|
|
|
147
145
|
# Extract agent_id for error logging if possible
|
|
148
146
|
agent_id = "UNKNOWN"
|
|
149
147
|
try:
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
148
|
+
# TODO: Fix config reference
|
|
149
|
+
context = self.get_context()
|
|
150
|
+
if context and context.agent_id:
|
|
151
|
+
agent_id = context.agent_id
|
|
154
152
|
except Exception:
|
|
155
153
|
pass
|
|
156
154
|
|
|
@@ -177,16 +175,15 @@ class QueryIndexedContent(WebScraperBaseTool):
|
|
|
177
175
|
self,
|
|
178
176
|
query: str,
|
|
179
177
|
max_results: int = 4,
|
|
180
|
-
config: RunnableConfig = None,
|
|
181
178
|
**kwargs,
|
|
182
179
|
) -> str:
|
|
183
180
|
"""Query the indexed content."""
|
|
184
181
|
try:
|
|
185
182
|
# Get agent context - throw error if not available
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
# Configuration is always available in new runtime
|
|
184
|
+
pass
|
|
188
185
|
|
|
189
|
-
context = self.
|
|
186
|
+
context = self.get_context()
|
|
190
187
|
if not context or not context.agent_id:
|
|
191
188
|
raise ValueError("Agent ID is required but not found in configuration")
|
|
192
189
|
|
|
@@ -249,10 +246,10 @@ class QueryIndexedContent(WebScraperBaseTool):
|
|
|
249
246
|
# Extract agent_id for error logging if possible
|
|
250
247
|
agent_id = "UNKNOWN"
|
|
251
248
|
try:
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
249
|
+
# TODO: Fix config reference
|
|
250
|
+
context = self.get_context()
|
|
251
|
+
if context and context.agent_id:
|
|
252
|
+
agent_id = context.agent_id
|
|
256
253
|
except Exception:
|
|
257
254
|
pass
|
|
258
255
|
|
|
@@ -4,7 +4,6 @@ from urllib.parse import urljoin, urlparse
|
|
|
4
4
|
|
|
5
5
|
import httpx
|
|
6
6
|
import openai
|
|
7
|
-
from langchain_core.runnables import RunnableConfig
|
|
8
7
|
from pydantic import BaseModel, Field
|
|
9
8
|
|
|
10
9
|
from intentkit.skills.web_scraper.base import WebScraperBaseTool
|
|
@@ -254,7 +253,7 @@ Extract the URLs now:"""
|
|
|
254
253
|
from intentkit.skills.openai.base import OpenAIBaseTool
|
|
255
254
|
|
|
256
255
|
temp_tool = OpenAIBaseTool(skill_store=self.skill_store)
|
|
257
|
-
api_key = temp_tool.get_api_key(
|
|
256
|
+
api_key = temp_tool.get_api_key()
|
|
258
257
|
|
|
259
258
|
# Initialize OpenAI client
|
|
260
259
|
client = openai.AsyncOpenAI(api_key=api_key)
|
|
@@ -287,7 +286,6 @@ Extract the URLs now:"""
|
|
|
287
286
|
chunk_overlap: int = DEFAULT_CHUNK_OVERLAP,
|
|
288
287
|
include_patterns: List[str] = None,
|
|
289
288
|
exclude_patterns: List[str] = None,
|
|
290
|
-
config: RunnableConfig = None,
|
|
291
289
|
**kwargs,
|
|
292
290
|
) -> str:
|
|
293
291
|
"""Discover website sitemaps, extract URLs with AI, and delegate to scrape_and_index."""
|
|
@@ -302,11 +300,11 @@ Extract the URLs now:"""
|
|
|
302
300
|
if not parsed_url.netloc:
|
|
303
301
|
return "Error: Invalid base URL provided. Please provide a valid URL (e.g., https://example.com)"
|
|
304
302
|
|
|
305
|
-
|
|
306
|
-
|
|
303
|
+
# Get agent context - throw error if not available
|
|
304
|
+
# TODO: Fix config reference
|
|
307
305
|
raise ValueError("Configuration is required but not provided")
|
|
308
306
|
|
|
309
|
-
context = self.
|
|
307
|
+
context = self.get_context()
|
|
310
308
|
if not context or not context.agent_id:
|
|
311
309
|
raise ValueError("Agent ID is required but not found in configuration")
|
|
312
310
|
|
|
@@ -445,10 +443,10 @@ Extract the URLs now:"""
|
|
|
445
443
|
# Extract agent_id for error logging if possible
|
|
446
444
|
agent_id = "UNKNOWN"
|
|
447
445
|
try:
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
446
|
+
# TODO: Fix config reference
|
|
447
|
+
context = self.get_context()
|
|
448
|
+
if context and context.agent_id:
|
|
449
|
+
agent_id = context.agent_id
|
|
452
450
|
except Exception:
|
|
453
451
|
pass
|
|
454
452
|
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# XMTP Skills
|
|
2
|
+
|
|
3
|
+
This skill category provides capabilities for creating XMTP protocol transaction requests that can be sent to users for signing.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **xmtp_transfer**: Create ETH or ERC20 token transfer transactions on Base mainnet using XMTP protocol
|
|
8
|
+
|
|
9
|
+
## Key Innovations
|
|
10
|
+
|
|
11
|
+
This skill category uses a new response format mechanism:
|
|
12
|
+
|
|
13
|
+
- `response_format = "content_and_artifact"` in the base class
|
|
14
|
+
- Skills return a tuple `(content_message, List[ChatMessageAttachment])` instead of just a string
|
|
15
|
+
- The `content_message` is sent to the user as conversational text
|
|
16
|
+
- The `ChatMessageAttachment` list contains XMTP transaction data with type "xmtp"
|
|
17
|
+
|
|
18
|
+
## Requirements
|
|
19
|
+
|
|
20
|
+
- Agent must be configured for Base mainnet (`network_id: "base-mainnet"`)
|
|
21
|
+
- Agent must have an EVM wallet address configured
|
|
22
|
+
- Only supports Base mainnet (Chain ID: 8453)
|
|
23
|
+
|
|
24
|
+
## Supported Transfer Types
|
|
25
|
+
|
|
26
|
+
### ETH Transfers
|
|
27
|
+
- Direct ETH transfers using transaction value
|
|
28
|
+
- No token contract address required
|
|
29
|
+
|
|
30
|
+
### ERC20 Token Transfers
|
|
31
|
+
- Supports any ERC20 token on Base mainnet
|
|
32
|
+
- Uses `transfer(address,uint256)` function call
|
|
33
|
+
- Requires token contract address
|
|
34
|
+
- Automatically encodes function call data
|
|
35
|
+
|
|
36
|
+
## Transaction Format
|
|
37
|
+
|
|
38
|
+
### ETH Transfer Example
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"version": "1.0",
|
|
42
|
+
"from": "0x...",
|
|
43
|
+
"chainId": "0x2105",
|
|
44
|
+
"calls": [{
|
|
45
|
+
"to": "0x...",
|
|
46
|
+
"value": "0x16345785d8a0000",
|
|
47
|
+
"data": "0x",
|
|
48
|
+
"metadata": {
|
|
49
|
+
"description": "Send 0.1 ETH to address",
|
|
50
|
+
"transactionType": "transfer",
|
|
51
|
+
"currency": "ETH",
|
|
52
|
+
"amount": 100000000000000000,
|
|
53
|
+
"decimals": 18,
|
|
54
|
+
"toAddress": "0x..."
|
|
55
|
+
}
|
|
56
|
+
}]
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### ERC20 Transfer Example
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"version": "1.0",
|
|
64
|
+
"from": "0x...",
|
|
65
|
+
"chainId": "0x2105",
|
|
66
|
+
"calls": [{
|
|
67
|
+
"to": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
68
|
+
"value": "0x0",
|
|
69
|
+
"data": "0xa9059cbb000000000000000000000000...",
|
|
70
|
+
"metadata": {
|
|
71
|
+
"description": "Send 100 USDC to address",
|
|
72
|
+
"transactionType": "erc20_transfer",
|
|
73
|
+
"currency": "USDC",
|
|
74
|
+
"amount": 100000000,
|
|
75
|
+
"decimals": 6,
|
|
76
|
+
"toAddress": "0x...",
|
|
77
|
+
"tokenContract": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
78
|
+
}
|
|
79
|
+
}]
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Parameters
|
|
84
|
+
|
|
85
|
+
- `from_address`: Sender's wallet address (must match agent's EVM wallet)
|
|
86
|
+
- `to_address`: Recipient's wallet address
|
|
87
|
+
- `amount`: Amount to transfer (in human-readable format, e.g., "1.5" for 1.5 tokens)
|
|
88
|
+
- `decimals`: Token decimals (18 for ETH, 6 for USDC, etc.)
|
|
89
|
+
- `currency`: Currency symbol ("ETH", "USDC", "DAI", etc.)
|
|
90
|
+
- `token_contract_address`: Token contract address (optional, leave empty for ETH)
|
|
91
|
+
|
|
92
|
+
## Usage
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
# ETH Transfer:
|
|
96
|
+
# from_address: agent's EVM wallet
|
|
97
|
+
# to_address: recipient address
|
|
98
|
+
# amount: "0.1"
|
|
99
|
+
# decimals: 18
|
|
100
|
+
# currency: "ETH"
|
|
101
|
+
# token_contract_address: None
|
|
102
|
+
|
|
103
|
+
# USDC Transfer:
|
|
104
|
+
# from_address: agent's EVM wallet
|
|
105
|
+
# to_address: recipient address
|
|
106
|
+
# amount: "100"
|
|
107
|
+
# decimals: 6
|
|
108
|
+
# currency: "USDC"
|
|
109
|
+
# token_contract_address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
110
|
+
```
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""XMTP skills."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from typing import TypedDict
|
|
5
|
+
|
|
6
|
+
from intentkit.abstracts.skill import SkillStoreABC
|
|
7
|
+
from intentkit.skills.base import SkillConfig, SkillOwnerState
|
|
8
|
+
from intentkit.skills.xmtp.base import XmtpBaseTool
|
|
9
|
+
from intentkit.skills.xmtp.transfer import XmtpTransfer
|
|
10
|
+
|
|
11
|
+
# Cache skills at the module level, because they are stateless
|
|
12
|
+
_cache: dict[str, XmtpBaseTool] = {}
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SkillStates(TypedDict):
|
|
18
|
+
xmtp_transfer: SkillOwnerState
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Config(SkillConfig):
|
|
22
|
+
"""Configuration for XMTP skills."""
|
|
23
|
+
|
|
24
|
+
states: SkillStates
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
async def get_skills(
|
|
28
|
+
config: "Config",
|
|
29
|
+
is_private: bool,
|
|
30
|
+
store: SkillStoreABC,
|
|
31
|
+
**_,
|
|
32
|
+
) -> list[XmtpBaseTool]:
|
|
33
|
+
"""Get all XMTP skills.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
config: The configuration for XMTP skills.
|
|
37
|
+
is_private: Whether to include private skills.
|
|
38
|
+
store: The skill store for persisting data.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
A list of XMTP skills.
|
|
42
|
+
"""
|
|
43
|
+
available_skills = []
|
|
44
|
+
|
|
45
|
+
# Include skills based on their state
|
|
46
|
+
for skill_name, state in config["states"].items():
|
|
47
|
+
if state == "disabled":
|
|
48
|
+
continue
|
|
49
|
+
elif state == "public" or (state == "private" and is_private):
|
|
50
|
+
available_skills.append(skill_name)
|
|
51
|
+
|
|
52
|
+
# Get each skill using the cached getter
|
|
53
|
+
result = []
|
|
54
|
+
for name in available_skills:
|
|
55
|
+
skill = get_xmtp_skill(name, store)
|
|
56
|
+
if skill:
|
|
57
|
+
result.append(skill)
|
|
58
|
+
return result
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def get_xmtp_skill(
|
|
62
|
+
name: str,
|
|
63
|
+
store: SkillStoreABC,
|
|
64
|
+
) -> XmtpBaseTool:
|
|
65
|
+
"""Get an XMTP skill by name.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
name: The name of the skill to get
|
|
69
|
+
store: The skill store for persisting data
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
The requested XMTP skill
|
|
73
|
+
"""
|
|
74
|
+
if name == "xmtp_transfer":
|
|
75
|
+
if name not in _cache:
|
|
76
|
+
_cache[name] = XmtpTransfer(
|
|
77
|
+
skill_store=store,
|
|
78
|
+
)
|
|
79
|
+
return _cache[name]
|
|
80
|
+
else:
|
|
81
|
+
logger.warning(f"Unknown XMTP skill: {name}")
|
|
82
|
+
return None
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from intentkit.skills.base import IntentKitSkill
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class XmtpBaseTool(IntentKitSkill):
|
|
5
|
+
"""Base class for XMTP-related skills."""
|
|
6
|
+
|
|
7
|
+
# Set response format to content_and_artifact for returning tuple
|
|
8
|
+
response_format = "content_and_artifact"
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def category(self) -> str:
|
|
12
|
+
"""Return the skill category."""
|
|
13
|
+
return "xmtp"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"title": "XMTP",
|
|
5
|
+
"description": "XMTP protocol skills for creating blockchain transaction requests that can be sent to users for signing",
|
|
6
|
+
"x-icon": "https://ai.service.crestal.dev/skills/xmtp/xmtp.svg",
|
|
7
|
+
"x-tags": [
|
|
8
|
+
"XMTP",
|
|
9
|
+
"Blockchain",
|
|
10
|
+
"Transactions",
|
|
11
|
+
"Web3",
|
|
12
|
+
"Base"
|
|
13
|
+
],
|
|
14
|
+
"properties": {
|
|
15
|
+
"enabled": {
|
|
16
|
+
"type": "boolean",
|
|
17
|
+
"title": "Enabled",
|
|
18
|
+
"description": "Whether this skill is enabled",
|
|
19
|
+
"default": false
|
|
20
|
+
},
|
|
21
|
+
"states": {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"properties": {
|
|
24
|
+
"xmtp_transfer": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"title": "XMTP Transfer",
|
|
27
|
+
"enum": [
|
|
28
|
+
"disabled",
|
|
29
|
+
"private"
|
|
30
|
+
],
|
|
31
|
+
"x-enum-title": [
|
|
32
|
+
"Disabled",
|
|
33
|
+
"Agent Owner Only"
|
|
34
|
+
],
|
|
35
|
+
"description": "Create XMTP transaction requests for transferring ETH or ERC20 tokens on Base mainnet. Supports both native ETH transfers and ERC20 token transfers. Generates wallet_sendCalls transaction data that users can sign.",
|
|
36
|
+
"default": "disabled"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|