intentkit 0.6.10.dev7__py3-none-any.whl → 0.6.11__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.

@@ -0,0 +1,213 @@
1
+ from typing import List, Tuple, Type
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+ from intentkit.clients.cdp import get_origin_cdp_client
6
+ from intentkit.models.chat import ChatMessageAttachment, ChatMessageAttachmentType
7
+ from intentkit.skills.xmtp.base import XmtpBaseTool
8
+
9
+
10
+ class SwapInput(BaseModel):
11
+ """Input for XMTP swap skill.
12
+
13
+ This creates an unsigned swap transaction attachment using CDP swap quote
14
+ that a user can review and sign via XMTP wallet_sendCalls.
15
+ """
16
+
17
+ from_address: str = Field(description="The sender address for the swap")
18
+ from_token: str = Field(
19
+ description="The contract address of the token to swap from"
20
+ )
21
+ to_token: str = Field(description="The contract address of the token to swap to")
22
+ from_amount: str = Field(
23
+ description="The input amount in the smallest unit of from_token (as string)"
24
+ )
25
+ slippage_bps: int = Field(
26
+ default=100,
27
+ description="Maximum slippage in basis points (100 = 1%). Defaults to 100.",
28
+ )
29
+
30
+
31
+ class XmtpSwap(XmtpBaseTool):
32
+ """Skill for creating XMTP swap transactions using CDP swap quote.
33
+
34
+ Generates a wallet_sendCalls transaction request to perform a token swap.
35
+ May include an ERC20 approval call followed by the router swap call.
36
+ Supports Base mainnet and Base Sepolia testnet.
37
+ """
38
+
39
+ name: str = "xmtp_swap"
40
+ description: str = (
41
+ "Create an XMTP transaction request for swapping tokens on Base using CDP swap quote. "
42
+ "Returns a wallet_sendCalls payload that can include an optional approval call and the swap call. "
43
+ "Only supports base-mainnet and base-sepolia."
44
+ )
45
+ args_schema: Type[BaseModel] = SwapInput
46
+
47
+ async def _arun(
48
+ self,
49
+ from_address: str,
50
+ from_token: str,
51
+ to_token: str,
52
+ from_amount: str,
53
+ slippage_bps: int = 100,
54
+ ) -> Tuple[str, List[ChatMessageAttachment]]:
55
+ # Input validation
56
+ if (
57
+ not from_address
58
+ or not from_address.startswith("0x")
59
+ or len(from_address) != 42
60
+ ):
61
+ raise ValueError("from_address must be a valid Ethereum address")
62
+
63
+ if not from_token or not from_token.startswith("0x") or len(from_token) != 42:
64
+ raise ValueError("from_token must be a valid token contract address")
65
+
66
+ if not to_token or not to_token.startswith("0x") or len(to_token) != 42:
67
+ raise ValueError("to_token must be a valid token contract address")
68
+
69
+ if from_token.lower() == to_token.lower():
70
+ raise ValueError("from_token and to_token cannot be the same")
71
+
72
+ try:
73
+ amount_int = int(from_amount)
74
+ if amount_int <= 0:
75
+ raise ValueError("from_amount must be a positive integer")
76
+ except ValueError as e:
77
+ raise ValueError(f"from_amount must be a valid positive integer: {e}")
78
+
79
+ if (
80
+ not isinstance(slippage_bps, int)
81
+ or slippage_bps < 0
82
+ or slippage_bps > 10000
83
+ ):
84
+ raise ValueError("slippage_bps must be between 0 and 10000 (0% to 100%)")
85
+
86
+ # Resolve agent context and target network
87
+ context = self.get_context()
88
+ agent = context.agent
89
+
90
+ # ChainId mapping for XMTP wallet_sendCalls
91
+ chain_id_hex_by_network = {
92
+ "base-mainnet": "0x2105", # 8453
93
+ "base-sepolia": "0x14A34", # 84532
94
+ }
95
+
96
+ if agent.network_id not in chain_id_hex_by_network:
97
+ raise ValueError(
98
+ f"XMTP swap only supports base-mainnet or base-sepolia. Current agent network: {agent.network_id}"
99
+ )
100
+
101
+ chain_id_hex = chain_id_hex_by_network[agent.network_id]
102
+
103
+ # CDP network mapping for swap quote API
104
+ # Reference: CDP SDK examples for swap quote and price
105
+ # https://github.com/coinbase/cdp-sdk/blob/main/examples/python/evm/swaps/create_swap_quote.py
106
+ network_for_cdp = {
107
+ "base-mainnet": "base",
108
+ "base-sepolia": "base-sepolia",
109
+ }[agent.network_id]
110
+
111
+ # Get CDP client from global origin helper (server-side credentials)
112
+ cdp_client = get_origin_cdp_client(self.skill_store)
113
+
114
+ # Call CDP to create swap quote and extract call datas
115
+ # Be permissive with response shape across SDK versions
116
+ try:
117
+ # Attempt the canonical method per CDP SDK examples
118
+ # create_swap_quote(from_token, to_token, from_amount, network, taker, slippage_bps, signer_address)
119
+ # Note: Don't use async with context manager as get_origin_cdp_client returns a managed global client
120
+ quote = await cdp_client.evm.create_swap_quote(
121
+ from_token=from_token,
122
+ to_token=to_token,
123
+ from_amount=str(from_amount),
124
+ network=network_for_cdp,
125
+ taker=from_address,
126
+ slippage_bps=slippage_bps,
127
+ signer_address=from_address,
128
+ )
129
+ except Exception as e: # pragma: no cover - defensive
130
+ raise ValueError(f"Failed to create swap quote via CDP: {e!s}")
131
+
132
+ # Extract transaction data from QuoteSwapResult
133
+ # CDP returns a single transaction object with all necessary data
134
+ calls: list[dict] = []
135
+
136
+ # Validate that we have the required fields from CDP
137
+ if not hasattr(quote, "to") or not hasattr(quote, "data"):
138
+ raise ValueError(
139
+ "CDP swap quote missing required transaction fields (to, data)"
140
+ )
141
+
142
+ # Format value field - ensure it's a hex string
143
+ value_hex = "0x0"
144
+ if hasattr(quote, "value") and quote.value:
145
+ if isinstance(quote.value, str) and quote.value.startswith("0x"):
146
+ value_hex = quote.value
147
+ else:
148
+ value_hex = hex(int(quote.value)) if quote.value != "0" else "0x0"
149
+
150
+ # Format data field - ensure it has 0x prefix
151
+ data_hex = quote.data if quote.data.startswith("0x") else f"0x{quote.data}"
152
+
153
+ # Get expected output amount for metadata
154
+ to_amount = getattr(quote, "to_amount", None) or "unknown"
155
+ min_to_amount = getattr(quote, "min_to_amount", None) or "unknown"
156
+
157
+ # Create the swap call following XMTP wallet_sendCalls format
158
+ swap_call = {
159
+ "to": quote.to,
160
+ "value": value_hex,
161
+ "data": data_hex,
162
+ "metadata": {
163
+ "description": f"Swap {from_amount} units of {from_token} for {to_token} (expected: {to_amount}, min: {min_to_amount})",
164
+ "transactionType": "swap",
165
+ "currency": from_token,
166
+ "amount": int(from_amount),
167
+ "toAddress": quote.to,
168
+ "fromToken": from_token,
169
+ "toToken": to_token,
170
+ "expectedOutput": to_amount,
171
+ "minimumOutput": min_to_amount,
172
+ "slippageBps": slippage_bps,
173
+ "network": agent.network_id,
174
+ },
175
+ }
176
+
177
+ calls.append(swap_call)
178
+
179
+ # Note: CDP's create_swap_quote already includes any necessary approvals
180
+ # in the single transaction if needed, or handles them via Permit2 signatures
181
+
182
+ # Build XMTP wallet_sendCalls payload
183
+ wallet_send_calls = {
184
+ "version": "1.0",
185
+ "from": from_address,
186
+ "chainId": chain_id_hex,
187
+ "calls": calls,
188
+ }
189
+
190
+ # Attachment for chat
191
+ attachment: ChatMessageAttachment = {
192
+ "type": ChatMessageAttachmentType.XMTP,
193
+ "url": None,
194
+ "json": wallet_send_calls,
195
+ }
196
+
197
+ # Human-friendly message with more details
198
+ expected_output = getattr(quote, "to_amount", "unknown")
199
+ min_output = getattr(quote, "min_to_amount", "unknown")
200
+
201
+ content_message = (
202
+ f"🔄 Swap transaction ready!\n\n"
203
+ f"**Details:**\n"
204
+ f"• From: {from_amount} units of {from_token}\n"
205
+ f"• To: {to_token}\n"
206
+ f"• Expected output: {expected_output} units\n"
207
+ f"• Minimum output: {min_output} units\n"
208
+ f"• Network: {agent.network_id}\n"
209
+ f"• Slippage: {slippage_bps / 100:.1f}%\n\n"
210
+ f"Please review the transaction details and sign to execute the swap."
211
+ )
212
+
213
+ return content_message, [attachment]
@@ -66,13 +66,20 @@ class XmtpTransfer(XmtpBaseTool):
66
66
  context = self.get_context()
67
67
  agent = context.agent
68
68
 
69
- # Check if agent is on base mainnet
70
- if agent.network_id != "base-mainnet" and agent.network_id != "base-sepolia":
69
+ # ChainId mapping for XMTP wallet_sendCalls
70
+ chain_id_hex_by_network = {
71
+ "base-mainnet": "0x2105", # 8453
72
+ "base-sepolia": "0x14A34", # 84532
73
+ }
74
+
75
+ if agent.network_id not in chain_id_hex_by_network:
71
76
  raise ValueError(
72
77
  f"XMTP transfer only supports base-mainnet or base-sepolia network. "
73
78
  f"Current agent network: {agent.network_id}"
74
79
  )
75
80
 
81
+ chain_id_hex = chain_id_hex_by_network[agent.network_id]
82
+
76
83
  # Calculate amount in smallest unit (wei for ETH, token units for ERC20)
77
84
  amount_int = int(float(amount) * (10**decimals))
78
85
 
@@ -127,7 +134,7 @@ class XmtpTransfer(XmtpBaseTool):
127
134
  wallet_send_calls = {
128
135
  "version": "1.0",
129
136
  "from": from_address,
130
- "chainId": "0x2105", # Base mainnet chain ID (8453 in hex)
137
+ "chainId": chain_id_hex,
131
138
  "calls": [
132
139
  {
133
140
  "to": transaction_to,
@@ -147,8 +154,12 @@ class XmtpTransfer(XmtpBaseTool):
147
154
 
148
155
  # Create user message
149
156
  content_message = (
150
- f"I have created a transaction request for transferring {amount} {currency} "
151
- f"to {to_address} on Base mainnet. "
157
+ f"💸 Transfer transaction ready!\n\n"
158
+ f"**Details:**\n"
159
+ f"• Amount: {amount} {currency}\n"
160
+ f"• To: {to_address}\n"
161
+ f"• Network: {agent.network_id}\n"
162
+ f"• Type: {'ERC20 Token' if token_contract_address else 'Native ETH'}\n\n"
152
163
  f"Please review the transaction details and sign to execute the transfer."
153
164
  )
154
165
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: intentkit
3
- Version: 0.6.10.dev7
3
+ Version: 0.6.11
4
4
  Summary: Intent-based AI Agent Platform - Core Package
5
5
  Project-URL: Homepage, https://github.com/crestal-network/intentkit
6
6
  Project-URL: Repository, https://github.com/crestal-network/intentkit
@@ -58,6 +58,7 @@ Requires-Dist: httpx>=0.28.1
58
58
  Requires-Dist: jsonref>=1.1.0
59
59
  Requires-Dist: langchain-community>=0.3.19
60
60
  Requires-Dist: langchain-core>=0.3.43
61
+ Requires-Dist: langchain-deepseek>=0.1.4
61
62
  Requires-Dist: langchain-mcp-adapters>=0.0.11
62
63
  Requires-Dist: langchain-openai>=0.3.8
63
64
  Requires-Dist: langchain-text-splitters>=0.3.8
@@ -1,4 +1,4 @@
1
- intentkit/__init__.py,sha256=ZmqNv3he6-fU_58ILsPGXGbpawiaKh-MXgNkiaFQA7c,384
1
+ intentkit/__init__.py,sha256=O-g3L_v3CCqDWGpUO9c77rBx7P3t0KVW0X67YBiBdnw,379
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
@@ -8,18 +8,18 @@ intentkit/abstracts/graph.py,sha256=8jkQnm6pnUAyiU7w5dpe2RuSLvpXBN17NGqZGEuc0ys,
8
8
  intentkit/abstracts/skill.py,sha256=cIJ6BkASD31U1IEkE8rdAawq99w_xsg0lt3oalqa1ZA,5071
9
9
  intentkit/abstracts/twitter.py,sha256=cEtP7ygR_b-pHdc9i8kBuyooz1cPoGUGwsBHDpowJyY,1262
10
10
  intentkit/clients/__init__.py,sha256=sQ_6_bRC2MPWLPH-skQ3qsEe8ce-dUGL7i8VJOautHg,298
11
- intentkit/clients/cdp.py,sha256=_CkvnBkzdq7-sFMGct4lz85FpaOoHxOGstWubhClzrA,5921
11
+ intentkit/clients/cdp.py,sha256=VaIFzgfqpq5H4bHbFBe8UPabhkwe8s5pge_P5FssGqU,6453
12
12
  intentkit/clients/twitter.py,sha256=Lfa7srHOFnY96SXcElW0jfg7XKS_WliWnXjPZEe6SQc,18976
13
13
  intentkit/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- intentkit/config/config.py,sha256=npQqWffhc2RZ3ECEOQXHp1DP-15aQqQ-xooIBkxDiM0,7576
14
+ intentkit/config/config.py,sha256=Q3xsxRvn0RxcPpAOHbHcPumTRlJQMcE_pfnPfAl6aXw,8553
15
15
  intentkit/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  intentkit/core/agent.py,sha256=GIKDn1dTenIHWMRxe-ud7hd1cQaHzbTDdypy5IAgPfU,16658
17
17
  intentkit/core/api.py,sha256=3GIMJpwduLUSbVPNW6mQVxZncYHH3OlLwdiqFtYtEAE,1208
18
18
  intentkit/core/client.py,sha256=rIwtJVVm-7piXtFNDbeykt9vWdNTecgjW0aA3N-lHnM,1495
19
- intentkit/core/credit.py,sha256=vLT47NlLrGyvSU1OP8dkVXV5_VHqRNSeAK5t1FqSSYs,61742
20
- intentkit/core/engine.py,sha256=ibaPSez5IuNys5AT3xifBsKUwNElFiJMmsXCjuziRdE,43555
19
+ intentkit/core/credit.py,sha256=Y5cjShFFqGBhz7Uc_ziqejyW-2FP58TYxsSNc4N_6hI,63039
20
+ intentkit/core/engine.py,sha256=aDfaqw8kBWYg_cznIapSWPT4Z8O2pTOMVEIJTgxSut8,38020
21
21
  intentkit/core/node.py,sha256=7h9zgDSd928bzUi3m3EZnKkhbwqlbRAQUr_uz7gKB5Y,8880
22
- intentkit/core/prompt.py,sha256=RfLhlUktkB2kCr3wfldqq6ZP2l8heZIMc8jVp31KIyQ,3631
22
+ intentkit/core/prompt.py,sha256=eaa2FyFptpsWlEGWCL8jVmZMGB6Pl9hBnt-y8Yq37RU,16041
23
23
  intentkit/core/skill.py,sha256=vPK37sDRT9kzkMBymPwqZ5uEdxTTRtb_DfREIeyz-Xw,5788
24
24
  intentkit/models/agent.py,sha256=pKeafRhmFMJwuIEBJkBEIl_oEu_CQ5AkvsBVfNfoxuQ,67168
25
25
  intentkit/models/agent_data.py,sha256=mVsiK8TziYa1W1ujU1KwI9osIVIeSM7XJEogGRL1WVU,28263
@@ -32,7 +32,7 @@ intentkit/models/credit.py,sha256=bcasHyrCwforLGrH8ZWEvN6y6ml7NeAFrGl8cfqvqbI,42
32
32
  intentkit/models/db.py,sha256=nuDX6NEtnfD5YLr2iVpAAXsgHbSpG5diqfLC-PkHsA4,4406
33
33
  intentkit/models/db_mig.py,sha256=vT6Tanm-BHC2T7dTztuB1UG494EFBAlHADKsNzR6xaQ,3577
34
34
  intentkit/models/generator.py,sha256=lyZu9U9rZUGkqd_QT5SAhay9DY358JJY8EhDSpN8I1M,10298
35
- intentkit/models/llm.py,sha256=TTTuea6f9aFxmS1X1SVUuMhvTh5rvIiqMn9A14lFxPY,26911
35
+ intentkit/models/llm.py,sha256=BgmtW6Vq7ZLZN33HG37VWGg_e8YlF8GxrO9WEvKCE-A,26928
36
36
  intentkit/models/redis.py,sha256=UoN8jqLREO1VO9_w6m-JhldpP19iEHj4TiGVCMutQW4,3702
37
37
  intentkit/models/skill.py,sha256=h_2wtKEbYE29TLsMdaSnjfOv6vXY6GwMU_abw-ONX28,16374
38
38
  intentkit/models/user.py,sha256=P7l6LOsZmXZ5tDPTczTbqDtDB_MKc_9_ddZkAB2npPk,9288
@@ -388,10 +388,12 @@ intentkit/skills/web_scraper/scrape_and_index.py,sha256=Xi1BmUd-LgmJXnQOgSz82baq
388
388
  intentkit/skills/web_scraper/utils.py,sha256=feGBTMWqpkoY7RFy2xDHVs5y8c2h8-XZ111jRo6cC3k,23349
389
389
  intentkit/skills/web_scraper/website_indexer.py,sha256=rTqCx-XzJtMlZnyGImPGWRdLpS13_exXc3lQu9EDjQM,17925
390
390
  intentkit/skills/xmtp/README.md,sha256=7y3ny77l5WUI758Q3xip1akFEgBdbibkwZjeJDu5MwE,2963
391
- intentkit/skills/xmtp/__init__.py,sha256=pG56rMjtC85x_R_YadlKyTnWYJe-jgwW4xolilcVCkA,2003
391
+ intentkit/skills/xmtp/__init__.py,sha256=inpuVqA9i98g8VIqqfC28PbfveozSukbEHOLbOMYv14,2538
392
392
  intentkit/skills/xmtp/base.py,sha256=85ZEuNLJmI_NmBPkbvDXQrNvJNG8dp9MbcbQYQQ3QZ8,430
393
- intentkit/skills/xmtp/schema.json,sha256=p8lPnzAzsW4yrPcuEv48Tv6qj3ouSNEFjw7YSxDZ3ok,1558
394
- intentkit/skills/xmtp/transfer.py,sha256=hlkUu2UkTKx1Y7mUrBT4OjkWuzDK8DwfNpxYEwdOFhc,5860
393
+ intentkit/skills/xmtp/price.py,sha256=LqM3tWiW42bYIRqfvsZUvYpG5H5ife3WUhR-pxiS9I8,2648
394
+ intentkit/skills/xmtp/schema.json,sha256=GFJKYPQVAcfiybL1uhAHANYeQUR0JWWxPgPhXW92N0s,3089
395
+ intentkit/skills/xmtp/swap.py,sha256=8YEjfOTS-BtKKuXT1QLedBTM9h4QUF0rVYtLkC7WPG0,8412
396
+ intentkit/skills/xmtp/transfer.py,sha256=qmSIsSrWR-S5JFlBP4YjxudsWlKsCpp-JjDQjYUhdHg,6182
395
397
  intentkit/skills/xmtp/xmtp.png,sha256=vQzT-71zIb8aPodg-GkGSQbBnjGAPczWGm3es2ZkJe8,6681
396
398
  intentkit/utils/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
397
399
  intentkit/utils/chain.py,sha256=3GBHuAbXxQr_HlOvkbB2kruYSkweucfxI5u-swXzY40,15135
@@ -401,7 +403,7 @@ intentkit/utils/random.py,sha256=DymMxu9g0kuQLgJUqalvgksnIeLdS-v0aRk5nQU0mLI,452
401
403
  intentkit/utils/s3.py,sha256=9trQNkKQ5VgxWsewVsV8Y0q_pXzGRvsCYP8xauyUYkg,8549
402
404
  intentkit/utils/slack_alert.py,sha256=s7UpRgyzLW7Pbmt8cKzTJgMA9bm4EP-1rQ5KXayHu6E,2264
403
405
  intentkit/utils/tx.py,sha256=2yLLGuhvfBEY5n_GJ8wmIWLCzn0FsYKv5kRNzw_sLUI,1454
404
- intentkit-0.6.10.dev7.dist-info/METADATA,sha256=7fKyuBYx-P6ONWtY6BCv7SslqGW3IfRqAbQNC9ArH3U,6373
405
- intentkit-0.6.10.dev7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
406
- intentkit-0.6.10.dev7.dist-info/licenses/LICENSE,sha256=Bln6DhK-LtcO4aXy-PBcdZv2f24MlJFm_qn222biJtE,1071
407
- intentkit-0.6.10.dev7.dist-info/RECORD,,
406
+ intentkit-0.6.11.dist-info/METADATA,sha256=vf9PbkXoHaxW1Wac6xw9_xh8hd2yYWYD3D5H79mXl5I,6409
407
+ intentkit-0.6.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
408
+ intentkit-0.6.11.dist-info/licenses/LICENSE,sha256=Bln6DhK-LtcO4aXy-PBcdZv2f24MlJFm_qn222biJtE,1071
409
+ intentkit-0.6.11.dist-info/RECORD,,