intentkit 0.8.16.dev1__py3-none-any.whl → 0.8.17.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 CHANGED
@@ -3,7 +3,7 @@
3
3
  A powerful platform for building AI agents with blockchain and cryptocurrency capabilities.
4
4
  """
5
5
 
6
- __version__ = "0.8.16-dev1"
6
+ __version__ = "0.8.17-dev1"
7
7
  __author__ = "hyacinthus"
8
8
  __email__ = "hyacinthus@gmail.com"
9
9
 
@@ -2,29 +2,29 @@ category,config_name,name,enabled,price_level,price,price_self_key,rate_limit_co
2
2
  acolyt,ask_gpt,acolyt_ask_gpt,FALSE,1,1,1,,,0x2Bd32A312280bF5A01140e68ca630fB76cE8A3De
3
3
  aixbt,aixbt_projects,aixbt_projects,TRUE,3,100,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
4
4
  allora,get_price_prediction,allora_get_price_prediction,TRUE,4,230,5,,,0x2Bd32A312280bF5A01140e68ca630fB76cE8A3De
5
- basename,BasenameActionProvider_register_basename,BasenameActionProvider_register_basename,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
6
- cdp,CdpApiActionProvider_request_faucet_funds,CdpApiActionProvider_request_faucet_funds,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
7
- cdp,CdpEvmWalletActionProvider_get_swap_price,CdpEvmWalletActionProvider_get_swap_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
8
- cdp,CdpEvmWalletActionProvider_swap,CdpEvmWalletActionProvider_swap,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
9
- cdp,WalletActionProvider_get_balance,WalletActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
10
- cdp,WalletActionProvider_get_wallet_details,WalletActionProvider_get_wallet_details,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
11
- cdp,WalletActionProvider_native_transfer,WalletActionProvider_native_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
12
- erc20,ERC20ActionProvider_get_balance,ERC20ActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
13
- erc20,ERC20ActionProvider_transfer,ERC20ActionProvider_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
14
- erc721,Erc721ActionProvider_get_balance,Erc721ActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
15
- erc721,Erc721ActionProvider_mint,Erc721ActionProvider_mint,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
16
- erc721,Erc721ActionProvider_transfer,Erc721ActionProvider_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
17
- morpho,MorphoActionProvider_deposit,MorphoActionProvider_deposit,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
18
- morpho,MorphoActionProvider_withdraw,MorphoActionProvider_withdraw,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
19
- pyth,PythActionProvider_fetch_price,PythActionProvider_fetch_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
20
- pyth,PythActionProvider_fetch_price_feed,PythActionProvider_fetch_price_feed,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
21
- superfluid,SuperfluidActionProvider_create_flow,SuperfluidActionProvider_create_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
22
- superfluid,SuperfluidActionProvider_delete_flow,SuperfluidActionProvider_delete_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
23
- superfluid,SuperfluidActionProvider_update_flow,SuperfluidActionProvider_update_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
24
- weth,WethActionProvider_wrap_eth,WethActionProvider_wrap_eth,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
25
- wow,WowActionProvider_buy_token,WowActionProvider_buy_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
26
- wow,WowActionProvider_create_token,WowActionProvider_create_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
27
- wow,WowActionProvider_sell_token,WowActionProvider_sell_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
5
+ basename,BasenameActionProvider_register_basename,BasenameActionProvider_register_basename,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
6
+ cdp,CdpApiActionProvider_request_faucet_funds,CdpApiActionProvider_request_faucet_funds,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
7
+ cdp,CdpEvmWalletActionProvider_get_swap_price,CdpEvmWalletActionProvider_get_swap_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
8
+ cdp,CdpEvmWalletActionProvider_swap,CdpEvmWalletActionProvider_swap,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
9
+ cdp,WalletActionProvider_get_balance,WalletActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
10
+ cdp,WalletActionProvider_get_wallet_details,WalletActionProvider_get_wallet_details,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
11
+ cdp,WalletActionProvider_native_transfer,WalletActionProvider_native_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
12
+ erc20,ERC20ActionProvider_get_balance,ERC20ActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
13
+ erc20,ERC20ActionProvider_transfer,ERC20ActionProvider_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
14
+ erc721,Erc721ActionProvider_get_balance,Erc721ActionProvider_get_balance,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
15
+ erc721,Erc721ActionProvider_mint,Erc721ActionProvider_mint,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
16
+ erc721,Erc721ActionProvider_transfer,Erc721ActionProvider_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
17
+ morpho,MorphoActionProvider_deposit,MorphoActionProvider_deposit,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
18
+ morpho,MorphoActionProvider_withdraw,MorphoActionProvider_withdraw,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
19
+ pyth,PythActionProvider_fetch_price,PythActionProvider_fetch_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
20
+ pyth,PythActionProvider_fetch_price_feed,PythActionProvider_fetch_price_feed,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
21
+ superfluid,SuperfluidActionProvider_create_flow,SuperfluidActionProvider_create_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
22
+ superfluid,SuperfluidActionProvider_delete_flow,SuperfluidActionProvider_delete_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
23
+ superfluid,SuperfluidActionProvider_update_flow,SuperfluidActionProvider_update_flow,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
24
+ weth,WethActionProvider_wrap_eth,WethActionProvider_wrap_eth,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
25
+ wow,WowActionProvider_buy_token,WowActionProvider_buy_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
26
+ wow,WowActionProvider_create_token,WowActionProvider_create_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
27
+ wow,WowActionProvider_sell_token,WowActionProvider_sell_token,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
28
28
  chainlist,chain_lookup,chain-lookup,TRUE,1,5,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
29
29
  common,current_time,common_current_time,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
30
30
  cookiefun,get_account_details,cookiefun_get_account_details,TRUE,2,70,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
@@ -162,10 +162,11 @@ firecrawl,firecrawl_scrape,firecrawl_scrape,TRUE,3,100,5,,,0x3cdd051eeC909f94965
162
162
  firecrawl,firecrawl_crawl,firecrawl_crawl,TRUE,3,100,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
163
163
  firecrawl,firecrawl_query_indexed_content,firecrawl_query_indexed_content,TRUE,1,5,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
164
164
  firecrawl,firecrawl_clear_indexed_content,firecrawl_clear_indexed_content,TRUE,1,5,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
165
- xmtp,xmtp_transfer,xmtp_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
166
- xmtp,xmtp_swap,xmtp_swap,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
167
- xmtp,xmtp_get_swap_price,xmtp_get_swap_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
168
- x402,x402_ask_agent,x402_ask_agent,TRUE,1,1,1,,,0x445750026A4a1906b61302442E085f9cbAfe206a
169
- casino,deck_shuffle,casino_deck_shuffle,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
165
+ xmtp,xmtp_transfer,xmtp_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
166
+ xmtp,xmtp_swap,xmtp_swap,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
167
+ xmtp,xmtp_get_swap_price,xmtp_get_swap_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
168
+ x402,x402_ask_agent,x402_ask_agent,TRUE,1,1,1,,,0x445750026A4a1906b61302442E085f9cbAfe206a
169
+ x402,x402_http_request,x402_http_request,TRUE,1,1,1,,,0x445750026A4a1906b61302442E085f9cbAfe206a
170
+ casino,deck_shuffle,casino_deck_shuffle,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
170
171
  casino,deck_draw,casino_deck_draw,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
171
172
  casino,dice_roll,casino_dice_roll,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
@@ -1,11 +1,12 @@
1
1
  """x402 skill category."""
2
2
 
3
3
  import logging
4
- from typing import TypedDict
4
+ from typing import Type, TypedDict
5
5
 
6
6
  from intentkit.skills.base import SkillConfig, SkillState
7
7
  from intentkit.skills.x402.ask_agent import X402AskAgent
8
8
  from intentkit.skills.x402.base import X402BaseSkill
9
+ from intentkit.skills.x402.http_request import X402HttpRequest
9
10
 
10
11
  logger = logging.getLogger(__name__)
11
12
 
@@ -14,6 +15,7 @@ _cache: dict[str, X402BaseSkill] = {}
14
15
 
15
16
  class SkillStates(TypedDict):
16
17
  x402_ask_agent: SkillState
18
+ x402_http_request: SkillState
17
19
 
18
20
 
19
21
  class Config(SkillConfig):
@@ -22,6 +24,12 @@ class Config(SkillConfig):
22
24
  states: SkillStates
23
25
 
24
26
 
27
+ _SKILL_BUILDERS: dict[str, Type[X402BaseSkill]] = {
28
+ "x402_ask_agent": X402AskAgent,
29
+ "x402_http_request": X402HttpRequest,
30
+ }
31
+
32
+
25
33
  async def get_skills(
26
34
  config: "Config",
27
35
  is_private: bool,
@@ -44,10 +52,10 @@ async def get_skills(
44
52
 
45
53
 
46
54
  def _get_skill(name: str) -> X402BaseSkill | None:
47
- if name == "x402_ask_agent":
55
+ builder = _SKILL_BUILDERS.get(name)
56
+ if builder:
48
57
  if name not in _cache:
49
- _cache[name] = X402AskAgent()
58
+ _cache[name] = builder()
50
59
  return _cache[name]
51
-
52
60
  logger.warning("Unknown x402 skill requested: %s", name)
53
61
  return None
@@ -1,15 +1,9 @@
1
1
  import logging
2
- import threading
3
2
  from typing import Any, Dict, Optional, Type
4
3
 
5
- from coinbase_agentkit.wallet_providers.evm_wallet_provider import (
6
- EvmWalletSigner as CoinbaseEvmWalletSigner,
7
- )
8
4
  from langchain_core.tools import ToolException
9
5
  from pydantic import BaseModel, Field
10
- from x402.clients.httpx import x402HttpxClient
11
6
 
12
- from intentkit.clients import get_wallet_provider
13
7
  from intentkit.config.config import config
14
8
  from intentkit.models.chat import AuthorType
15
9
  from intentkit.skills.x402.base import X402BaseSkill
@@ -47,15 +41,11 @@ class X402AskAgent(X402BaseSkill):
47
41
  super_mode: Optional[bool] = None,
48
42
  ) -> str:
49
43
  try:
44
+ # Use wallet provider signer to satisfy eth_account.BaseAccount interface requirements
50
45
  base_url = (config.open_api_base_url or "").rstrip("/")
51
46
  if not base_url:
52
- raise ValueError("X402 API base URL is not configured.")
53
-
54
- # Use wallet provider signer to satisfy eth_account.BaseAccount interface requirements
55
- context = self.get_context()
56
- wallet_provider = await get_wallet_provider(context.agent)
57
- account = ThreadSafeEvmWalletSigner(wallet_provider)
58
-
47
+ raise ToolException("X402 API base URL is not configured.")
48
+ target_url = f"{base_url}/x402"
59
49
  payload: Dict[str, Any] = {
60
50
  "agent_id": agent_id,
61
51
  "message": message,
@@ -66,12 +56,8 @@ class X402AskAgent(X402BaseSkill):
66
56
  if super_mode is not None:
67
57
  payload["super_mode"] = super_mode
68
58
 
69
- async with x402HttpxClient(
70
- account=account,
71
- base_url=base_url,
72
- timeout=20.0,
73
- ) as client:
74
- response = await client.post("/x402", json=payload)
59
+ async with self.http_client(timeout=20.0) as client:
60
+ response = await client.post(target_url, json=payload)
75
61
  try:
76
62
  response.raise_for_status()
77
63
  except Exception as e:
@@ -110,55 +96,3 @@ class X402AskAgent(X402BaseSkill):
110
96
  except Exception as e:
111
97
  logger.error(f"Unexpected error in x402_ask_agent: {str(e)}")
112
98
  raise ToolException(f"Unexpected error occurred: {str(e)}") from e
113
-
114
-
115
- class ThreadSafeEvmWalletSigner(CoinbaseEvmWalletSigner):
116
- """EVM wallet signer that avoids nested event loop errors.
117
-
118
- Coinbase's signer runs async wallet calls in the current thread. When invoked
119
- inside an active asyncio loop (as happens in async skills), it trips over the
120
- loop already running. We hop work to a background thread so the provider can
121
- spin up its own loop safely.
122
- """
123
-
124
- def _run_in_thread(self, func: Any, *args: Any, **kwargs: Any) -> Any:
125
- result: list[Any] = []
126
- error: list[BaseException] = []
127
-
128
- def _target() -> None:
129
- try:
130
- result.append(func(*args, **kwargs))
131
- except BaseException as exc: # pragma: no cover - bubble up original error
132
- error.append(exc)
133
-
134
- thread = threading.Thread(target=_target, daemon=True)
135
- thread.start()
136
- thread.join()
137
-
138
- if error:
139
- raise error[0]
140
- return result[0] if result else None
141
-
142
- def unsafe_sign_hash(self, message_hash: Any) -> Any:
143
- return self._run_in_thread(super().unsafe_sign_hash, message_hash)
144
-
145
- def sign_message(self, signable_message: Any) -> Any:
146
- return self._run_in_thread(super().sign_message, signable_message)
147
-
148
- def sign_transaction(self, transaction_dict: Any) -> Any:
149
- return self._run_in_thread(super().sign_transaction, transaction_dict)
150
-
151
- def sign_typed_data(
152
- self,
153
- domain_data: Optional[Dict[str, Any]] = None,
154
- message_types: Optional[Dict[str, Any]] = None,
155
- message_data: Optional[Dict[str, Any]] = None,
156
- full_message: Optional[Dict[str, Any]] = None,
157
- ) -> Any:
158
- return self._run_in_thread(
159
- super().sign_typed_data,
160
- domain_data=domain_data,
161
- message_types=message_types,
162
- message_data=message_data,
163
- full_message=full_message,
164
- )
@@ -1,5 +1,18 @@
1
+ import logging
2
+ import threading
3
+ from contextlib import asynccontextmanager
4
+ from typing import Any, AsyncIterator
5
+
6
+ from coinbase_agentkit.wallet_providers.evm_wallet_provider import (
7
+ EvmWalletSigner as CoinbaseEvmWalletSigner,
8
+ )
9
+ from x402.clients.httpx import x402HttpxClient
10
+
11
+ from intentkit.clients import get_wallet_provider
1
12
  from intentkit.skills.onchain import IntentKitOnChainSkill
2
13
 
14
+ logger = logging.getLogger(__name__)
15
+
3
16
 
4
17
  class X402BaseSkill(IntentKitOnChainSkill):
5
18
  """Base class for x402 skills."""
@@ -7,3 +20,79 @@ class X402BaseSkill(IntentKitOnChainSkill):
7
20
  @property
8
21
  def category(self) -> str:
9
22
  return "x402"
23
+
24
+ async def _get_signer(self) -> "ThreadSafeEvmWalletSigner":
25
+ context = self.get_context()
26
+ wallet_provider = await get_wallet_provider(context.agent)
27
+ return ThreadSafeEvmWalletSigner(wallet_provider)
28
+
29
+ @asynccontextmanager
30
+ async def http_client(
31
+ self,
32
+ timeout: float = 30.0,
33
+ ) -> AsyncIterator[x402HttpxClient]:
34
+ account = await self._get_signer()
35
+ try:
36
+ async with x402HttpxClient(
37
+ account=account,
38
+ timeout=timeout,
39
+ ) as client:
40
+ yield client
41
+ except Exception:
42
+ logger.exception("Failed to create x402 HTTP client")
43
+ raise
44
+
45
+
46
+ class ThreadSafeEvmWalletSigner(CoinbaseEvmWalletSigner):
47
+ """EVM wallet signer that avoids nested event loop errors.
48
+
49
+ Coinbase's signer runs async wallet calls in the current thread. When invoked
50
+ inside an active asyncio loop (as happens in async skills), it trips over the
51
+ loop already running. We hop work to a background thread so the provider can
52
+ spin up its own loop safely.
53
+ """
54
+
55
+ def __init__(self, wallet_provider: Any):
56
+ super().__init__(wallet_provider=wallet_provider)
57
+
58
+ def _run_in_thread(self, func: Any, *args: Any, **kwargs: Any) -> Any:
59
+ result: list[Any] = []
60
+ error: list[BaseException] = []
61
+
62
+ def _target() -> None:
63
+ try:
64
+ result.append(func(*args, **kwargs))
65
+ except BaseException as exc: # pragma: no cover - bubble up original error
66
+ error.append(exc)
67
+
68
+ thread = threading.Thread(target=_target, daemon=True)
69
+ thread.start()
70
+ thread.join()
71
+
72
+ if error:
73
+ raise error[0]
74
+ return result[0] if result else None
75
+
76
+ def unsafe_sign_hash(self, message_hash: Any) -> Any:
77
+ return self._run_in_thread(super().unsafe_sign_hash, message_hash)
78
+
79
+ def sign_message(self, signable_message: Any) -> Any:
80
+ return self._run_in_thread(super().sign_message, signable_message)
81
+
82
+ def sign_transaction(self, transaction_dict: Any) -> Any:
83
+ return self._run_in_thread(super().sign_transaction, transaction_dict)
84
+
85
+ def sign_typed_data(
86
+ self,
87
+ domain_data: Any | None = None,
88
+ message_types: Any | None = None,
89
+ message_data: Any | None = None,
90
+ full_message: Any | None = None,
91
+ ) -> Any:
92
+ return self._run_in_thread(
93
+ super().sign_typed_data,
94
+ domain_data=domain_data,
95
+ message_types=message_types,
96
+ message_data=message_data,
97
+ full_message=full_message,
98
+ )
@@ -0,0 +1,117 @@
1
+ import logging
2
+ from typing import Any, Dict, Optional, Type, Union
3
+ from urllib.parse import urlparse
4
+
5
+ import httpx
6
+ from langchain_core.tools import ToolException
7
+ from pydantic import BaseModel, Field
8
+
9
+ from intentkit.skills.x402.base import X402BaseSkill
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class X402HttpRequestInput(BaseModel):
15
+ """Arguments for a generic x402 HTTP request."""
16
+
17
+ method: str = Field(description="HTTP method to use. Supported values: GET, POST.")
18
+ url: str = Field(
19
+ description="Absolute URL for the request (must include scheme and host)."
20
+ )
21
+ headers: Optional[Dict[str, str]] = Field(
22
+ default=None,
23
+ description="Optional headers to include in the request.",
24
+ )
25
+ params: Optional[Dict[str, Any]] = Field(
26
+ default=None,
27
+ description="Optional query parameters to include in the request.",
28
+ )
29
+ data: Optional[Union[Dict[str, Any], str]] = Field(
30
+ default=None,
31
+ description=(
32
+ "Optional request body. Dictionaries are sent as JSON; strings are sent as raw data. "
33
+ "Only supported for POST requests."
34
+ ),
35
+ )
36
+ timeout: Optional[float] = Field(
37
+ default=30.0,
38
+ description="Request timeout in seconds.",
39
+ )
40
+
41
+
42
+ class X402HttpRequest(X402BaseSkill):
43
+ """Skill that performs signed HTTP requests via the x402 client."""
44
+
45
+ name: str = "x402_http_request"
46
+ description: str = (
47
+ "Send an HTTP GET or POST request using the x402 payment protocol. "
48
+ "Provide the method, absolute URL, optional headers, query parameters, and request body. "
49
+ "Returns the response status and body text."
50
+ )
51
+ args_schema: Type[BaseModel] = X402HttpRequestInput
52
+
53
+ async def _arun(
54
+ self,
55
+ method: str,
56
+ url: str,
57
+ headers: Optional[Dict[str, str]] = None,
58
+ params: Optional[Dict[str, Any]] = None,
59
+ data: Optional[Union[Dict[str, Any], str]] = None,
60
+ timeout: float = 30.0,
61
+ **_: Any,
62
+ ) -> str:
63
+ method_upper = method.upper()
64
+ if method_upper not in {"GET", "POST"}:
65
+ raise ToolException(
66
+ f"Unsupported HTTP method '{method}'. Only GET and POST are allowed."
67
+ )
68
+
69
+ parsed = urlparse(url)
70
+ if not (parsed.scheme and parsed.netloc):
71
+ raise ToolException("URL must include scheme and host (absolute URL).")
72
+
73
+ request_headers = dict(headers or {})
74
+ request_kwargs: Dict[str, Any] = {
75
+ "url": url,
76
+ "headers": request_headers or None,
77
+ "params": params,
78
+ "timeout": timeout,
79
+ }
80
+
81
+ if method_upper == "POST":
82
+ if isinstance(data, dict):
83
+ header_keys = {key.lower() for key in request_headers}
84
+ if "content-type" not in header_keys:
85
+ request_headers["Content-Type"] = "application/json"
86
+ request_kwargs["json"] = data
87
+ elif isinstance(data, str):
88
+ request_kwargs["content"] = data
89
+ elif data is not None:
90
+ raise ToolException(
91
+ "POST body must be either a JSON-serializable object or a string."
92
+ )
93
+ elif data is not None:
94
+ raise ToolException("Request body is only supported for POST requests.")
95
+
96
+ try:
97
+ async with self.http_client(timeout=timeout) as client:
98
+ response = await client.request(method_upper, **request_kwargs)
99
+ response.raise_for_status()
100
+ return f"Status: {response.status_code}\nContent: {response.text}"
101
+ except ValueError as exc:
102
+ raise ToolException(str(exc)) from exc
103
+ except httpx.TimeoutException as exc:
104
+ raise ToolException(
105
+ f"Request to {url} timed out after {timeout} seconds"
106
+ ) from exc
107
+ except httpx.HTTPStatusError as exc:
108
+ raise ToolException(
109
+ f"HTTP {exc.response.status_code} - {exc.response.text}"
110
+ ) from exc
111
+ except httpx.RequestError as exc:
112
+ raise ToolException(f"Failed to connect to {url} - {str(exc)}") from exc
113
+ except ToolException:
114
+ raise
115
+ except Exception as exc:
116
+ logger.error("Unexpected error in x402_http_request", exc_info=exc)
117
+ raise ToolException(f"Unexpected error occurred - {str(exc)}") from exc
@@ -4,10 +4,7 @@
4
4
  "title": "x402",
5
5
  "description": "Interact with other IntentKit agents through the x402 payment protocol.",
6
6
  "x-icon": "https://ai.service.crestal.dev/skills/x402/x402.webp",
7
- "x-tags": [
8
- "Communication",
9
- "Infrastructure"
10
- ],
7
+ "x-tags": ["Communication", "Infrastructure"],
11
8
  "properties": {
12
9
  "enabled": {
13
10
  "type": "boolean",
@@ -21,11 +18,7 @@
21
18
  "x402_ask_agent": {
22
19
  "type": "string",
23
20
  "title": "Ask Agent",
24
- "enum": [
25
- "disabled",
26
- "public",
27
- "private"
28
- ],
21
+ "enum": ["disabled", "public", "private"],
29
22
  "x-enum-title": [
30
23
  "Disabled",
31
24
  "Agent Owner + All Users",
@@ -33,8 +26,20 @@
33
26
  ],
34
27
  "description": "Send a message to another IntentKit agent via the x402 API and return the final agent response.",
35
28
  "default": "disabled"
29
+ },
30
+ "x402_http_request": {
31
+ "type": "string",
32
+ "title": "HTTP Request",
33
+ "enum": ["disabled", "public", "private"],
34
+ "x-enum-title": [
35
+ "Disabled",
36
+ "Agent Owner + All Users",
37
+ "Agent Owner Only"
38
+ ],
39
+ "description": "Perform a signed HTTP GET or POST request via the x402 payment protocol.",
40
+ "default": "disabled"
36
41
  }
37
42
  }
38
43
  }
39
44
  }
40
- }
45
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: intentkit
3
- Version: 0.8.16.dev1
3
+ Version: 0.8.17.dev1
4
4
  Summary: Intent-based AI Agent Platform - Core Package
5
5
  Project-URL: Homepage, https://github.com/crestalnetwork/intentkit
6
6
  Project-URL: Repository, https://github.com/crestalnetwork/intentkit
@@ -1,4 +1,4 @@
1
- intentkit/__init__.py,sha256=lh1TCO4tMMNIcmEgDwm2bup2xBVghTRwIUdD0L9JbiI,384
1
+ intentkit/__init__.py,sha256=CJkMPT5aGywNlVkgqWvYf6tIdhG9yij7FiiQ5BBHEzQ,384
2
2
  intentkit/abstracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  intentkit/abstracts/agent.py,sha256=108gb5W8Q1Sy4G55F2_ZFv2-_CnY76qrBtpIr0Oxxqk,1489
4
4
  intentkit/abstracts/api.py,sha256=ZUc24vaQvQVbbjznx7bV0lbbQxdQPfEV8ZxM2R6wZWo,166
@@ -40,7 +40,7 @@ intentkit/models/llm.csv,sha256=0NIGyo-6E9sKkPy-iCw4xl3KK8dFO5t45le1gwfg7Vs,3801
40
40
  intentkit/models/llm.py,sha256=_t4dCyKo4l3dlETKt1SCEKAn-RZ2LRs1bhJfTESarpI,22313
41
41
  intentkit/models/redis.py,sha256=Vqb9pjeMQ85Az5GvUbqCsQ5stBpFg3n85p94TB40xEw,3727
42
42
  intentkit/models/skill.py,sha256=vGJgKpUmjGsThFznEwMLipuZIlqtto_ovVELp1_AjB8,20709
43
- intentkit/models/skills.csv,sha256=4Ni3OlVLLVEv8ipBtFzBJ23pysi59HbJ4CRCMHAMDYQ,19219
43
+ intentkit/models/skills.csv,sha256=p2zH50X0Mh-n9obWs6f-W97GirNxv7Ea6GXvZDw08nk,19345
44
44
  intentkit/models/user.py,sha256=M79XT1dF1Ju5HKdE49RALeV_XXen7mIvmP9Lhsx9NFw,11485
45
45
  intentkit/skills/__init__.py,sha256=WkjmKB4xvy36zyXMroPMf_DTPgQloNS3L73nVnBmuQI,303
46
46
  intentkit/skills/base.py,sha256=WpCrCHJkvg9hi7wbvwMqBdWfPUGQ2NSOHkGziQuoJfc,12297
@@ -436,10 +436,11 @@ intentkit/skills/wow/__init__.py,sha256=m7kbAlh4kQWEixxiEeyVf3v4wUDdzOuFZ79NVsVj
436
436
  intentkit/skills/wow/base.py,sha256=nFt8sJtQQsu2_ZlRasXhyG148fSJYRL-20kEt380PaE,226
437
437
  intentkit/skills/wow/schema.json,sha256=jGpugebVupGTlOUYNu7fN99p-zL-cfaoOYSX7KW8VQc,2292
438
438
  intentkit/skills/wow/wow.svg,sha256=PO0-m6TZjJCql9r1oWohlRV5PyqGc5kIDUEnpP2-5SU,427
439
- intentkit/skills/x402/__init__.py,sha256=tAO80tBlMluExByWiQ_r2GZlaAYTMsaWxCXDREaqqAg,1315
440
- intentkit/skills/x402/ask_agent.py,sha256=fvsUftFXygGhK_BiFTN1mSSYTWrIhxGRBgTLCy0_USE,6138
441
- intentkit/skills/x402/base.py,sha256=KhC9CWFEgdfQjWH1QCRJiNSWCnmgypVIe1ap1hb3X5E,211
442
- intentkit/skills/x402/schema.json,sha256=drzDQYukjZisupVS-_A73F5GtT7MDHxKcTzDIr-aYTs,1069
439
+ intentkit/skills/x402/__init__.py,sha256=Q-Y19tDeTynU9cxDeAfgabJOvDbWp7CV0VNoxyOiU54,1569
440
+ intentkit/skills/x402/ask_agent.py,sha256=FaHncKPYYmvhfQTNfuKyAJbUuLPjW8XTF_Twzr3aOMs,3774
441
+ intentkit/skills/x402/base.py,sha256=oxVDLCTUj-YR3Of-NptJ_qJX5mLW5SIWFdzUiSQ2zdo,3225
442
+ intentkit/skills/x402/http_request.py,sha256=mvvEn6AMYH7uUaoVPV9lFOtot32smwZjB_2cnCqpP_U,4432
443
+ intentkit/skills/x402/schema.json,sha256=a5cbynk70X-p2szGD1RHvHpNYb2ficYDnVulMLZR44Y,1436
443
444
  intentkit/skills/x402/x402.webp,sha256=uFUnkwm9lwCwJgmNqa9ZgF6PjzCcAdQ8b_CKAFh8g-Y,4490
444
445
  intentkit/skills/xmtp/README.md,sha256=7y3ny77l5WUI758Q3xip1akFEgBdbibkwZjeJDu5MwE,2963
445
446
  intentkit/skills/xmtp/__init__.py,sha256=2x3roc8BaHT_Mfd7IXPw0UgUdca8TDB8NBFvMRibhD0,2180
@@ -458,7 +459,7 @@ intentkit/utils/s3.py,sha256=A8Nsx5QJyLsxhj9g7oHNy2-m24tjQUhC9URm8Qb1jFw,10057
458
459
  intentkit/utils/schema.py,sha256=ATeTskEO2Y-MLFcOJEm5BoFJvxqc_zqQwiRS3rO4XDQ,3428
459
460
  intentkit/utils/slack_alert.py,sha256=s7UpRgyzLW7Pbmt8cKzTJgMA9bm4EP-1rQ5KXayHu6E,2264
460
461
  intentkit/utils/tx.py,sha256=2yLLGuhvfBEY5n_GJ8wmIWLCzn0FsYKv5kRNzw_sLUI,1454
461
- intentkit-0.8.16.dev1.dist-info/METADATA,sha256=3qPPnfhVMbIUe-qbFD5jo5iKYcMcS-fOjzfqk8OKky0,6316
462
- intentkit-0.8.16.dev1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
463
- intentkit-0.8.16.dev1.dist-info/licenses/LICENSE,sha256=Bln6DhK-LtcO4aXy-PBcdZv2f24MlJFm_qn222biJtE,1071
464
- intentkit-0.8.16.dev1.dist-info/RECORD,,
462
+ intentkit-0.8.17.dev1.dist-info/METADATA,sha256=jFVtmwMSbRWdscgou3SsZ-0hZgPZr7Z-rC6QbnVYHKU,6316
463
+ intentkit-0.8.17.dev1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
464
+ intentkit-0.8.17.dev1.dist-info/licenses/LICENSE,sha256=Bln6DhK-LtcO4aXy-PBcdZv2f24MlJFm_qn222biJtE,1071
465
+ intentkit-0.8.17.dev1.dist-info/RECORD,,