intentkit 0.7.4rc1__py3-none-any.whl → 0.7.4rc2__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.
- intentkit/__init__.py +1 -1
- intentkit/clients/cdp.py +1 -1
- intentkit/core/agent.py +465 -3
- intentkit/core/engine.py +7 -26
- intentkit/core/prompt.py +1 -1
- intentkit/models/agent.py +194 -235
- intentkit/models/agent_schema.json +0 -39
- intentkit/models/db.py +1 -1
- intentkit/models/user.py +12 -5
- intentkit/utils/chain.py +3 -3
- {intentkit-0.7.4rc1.dist-info → intentkit-0.7.4rc2.dist-info}/METADATA +1 -1
- {intentkit-0.7.4rc1.dist-info → intentkit-0.7.4rc2.dist-info}/RECORD +14 -15
- intentkit/core/skill.py +0 -200
- {intentkit-0.7.4rc1.dist-info → intentkit-0.7.4rc2.dist-info}/WHEEL +0 -0
- {intentkit-0.7.4rc1.dist-info → intentkit-0.7.4rc2.dist-info}/licenses/LICENSE +0 -0
intentkit/__init__.py
CHANGED
intentkit/clients/cdp.py
CHANGED
|
@@ -87,7 +87,7 @@ class CdpClient:
|
|
|
87
87
|
return self._wallet_provider
|
|
88
88
|
agent: Agent = await self._skill_store.get_agent_config(self._agent_id)
|
|
89
89
|
agent_data: AgentData = await self._skill_store.get_agent_data(self._agent_id)
|
|
90
|
-
network_id = agent.network_id
|
|
90
|
+
network_id = agent.network_id
|
|
91
91
|
|
|
92
92
|
# Get credentials from skill store system config
|
|
93
93
|
api_key_id = self._skill_store.get_system_config("cdp_api_key_id")
|
intentkit/core/agent.py
CHANGED
|
@@ -2,19 +2,305 @@ import logging
|
|
|
2
2
|
import time
|
|
3
3
|
from datetime import datetime, timedelta, timezone
|
|
4
4
|
from decimal import Decimal
|
|
5
|
-
from typing import Dict, List
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
6
6
|
|
|
7
|
+
from aiogram import Bot
|
|
8
|
+
from aiogram.exceptions import TelegramConflictError, TelegramUnauthorizedError
|
|
9
|
+
from aiogram.utils.token import TokenValidationError
|
|
7
10
|
from sqlalchemy import func, select, text, update
|
|
8
11
|
|
|
9
|
-
from intentkit.
|
|
10
|
-
from intentkit.
|
|
12
|
+
from intentkit.abstracts.skill import SkillStoreABC
|
|
13
|
+
from intentkit.clients.cdp import get_cdp_client
|
|
14
|
+
from intentkit.config.config import config
|
|
15
|
+
from intentkit.models.agent import (
|
|
16
|
+
Agent,
|
|
17
|
+
AgentAutonomous,
|
|
18
|
+
AgentCreate,
|
|
19
|
+
AgentResponse,
|
|
20
|
+
AgentTable,
|
|
21
|
+
AgentUpdate,
|
|
22
|
+
)
|
|
23
|
+
from intentkit.models.agent_data import AgentData, AgentQuota, AgentQuotaTable
|
|
11
24
|
from intentkit.models.credit import CreditEventTable, EventType, UpstreamType
|
|
12
25
|
from intentkit.models.db import get_session
|
|
26
|
+
from intentkit.models.skill import (
|
|
27
|
+
AgentSkillData,
|
|
28
|
+
AgentSkillDataCreate,
|
|
29
|
+
ThreadSkillData,
|
|
30
|
+
ThreadSkillDataCreate,
|
|
31
|
+
)
|
|
13
32
|
from intentkit.utils.error import IntentKitAPIError
|
|
33
|
+
from intentkit.utils.slack_alert import send_slack_message
|
|
14
34
|
|
|
15
35
|
logger = logging.getLogger(__name__)
|
|
16
36
|
|
|
17
37
|
|
|
38
|
+
async def _process_agent_post_actions(
|
|
39
|
+
agent: Agent, is_new: bool = True, slack_message: str | None = None
|
|
40
|
+
) -> AgentData:
|
|
41
|
+
"""Process common actions after agent creation or update.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
agent: The agent that was created or updated
|
|
45
|
+
is_new: Whether the agent is newly created
|
|
46
|
+
slack_message: Optional custom message for Slack notification
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
AgentData: The processed agent data
|
|
50
|
+
"""
|
|
51
|
+
if config.cdp_api_key_id and agent.wallet_provider == "cdp":
|
|
52
|
+
cdp_client = await get_cdp_client(agent.id, agent_store)
|
|
53
|
+
await cdp_client.get_wallet_provider()
|
|
54
|
+
|
|
55
|
+
# Get new agent data
|
|
56
|
+
# FIXME: refuse to change wallet provider
|
|
57
|
+
if agent.wallet_provider == "readonly":
|
|
58
|
+
agent_data = await AgentData.patch(
|
|
59
|
+
agent.id,
|
|
60
|
+
{
|
|
61
|
+
"evm_wallet_address": agent.readonly_wallet_address,
|
|
62
|
+
},
|
|
63
|
+
)
|
|
64
|
+
else:
|
|
65
|
+
agent_data = await AgentData.get(agent.id)
|
|
66
|
+
|
|
67
|
+
# Send Slack notification
|
|
68
|
+
slack_message = slack_message or ("Agent Created" if is_new else "Agent Updated")
|
|
69
|
+
try:
|
|
70
|
+
_send_agent_notification(agent, agent_data, slack_message)
|
|
71
|
+
except Exception as e:
|
|
72
|
+
logger.error("Failed to send Slack notification: %s", e)
|
|
73
|
+
|
|
74
|
+
return agent_data
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async def _process_telegram_config(
|
|
78
|
+
agent: AgentUpdate, existing_agent: Optional[Agent], agent_data: AgentData
|
|
79
|
+
) -> AgentData:
|
|
80
|
+
"""Process telegram configuration for an agent.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
agent: The agent with telegram configuration
|
|
84
|
+
existing_agent: The existing agent (if updating)
|
|
85
|
+
agent_data: The agent data to update
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
AgentData: The updated agent data
|
|
89
|
+
"""
|
|
90
|
+
changes = agent.model_dump(exclude_unset=True)
|
|
91
|
+
if not changes.get("telegram_entrypoint_enabled"):
|
|
92
|
+
return agent_data
|
|
93
|
+
|
|
94
|
+
if not changes.get("telegram_config") or not changes.get("telegram_config").get(
|
|
95
|
+
"token"
|
|
96
|
+
):
|
|
97
|
+
return agent_data
|
|
98
|
+
|
|
99
|
+
tg_bot_token = changes.get("telegram_config").get("token")
|
|
100
|
+
|
|
101
|
+
if existing_agent and existing_agent.telegram_config.get("token") == tg_bot_token:
|
|
102
|
+
return agent_data
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
bot = Bot(token=tg_bot_token)
|
|
106
|
+
bot_info = await bot.get_me()
|
|
107
|
+
agent_data.telegram_id = str(bot_info.id)
|
|
108
|
+
agent_data.telegram_username = bot_info.username
|
|
109
|
+
agent_data.telegram_name = bot_info.first_name
|
|
110
|
+
if bot_info.last_name:
|
|
111
|
+
agent_data.telegram_name = f"{bot_info.first_name} {bot_info.last_name}"
|
|
112
|
+
await agent_data.save()
|
|
113
|
+
try:
|
|
114
|
+
await bot.close()
|
|
115
|
+
except Exception:
|
|
116
|
+
pass
|
|
117
|
+
return agent_data
|
|
118
|
+
except (
|
|
119
|
+
TelegramUnauthorizedError,
|
|
120
|
+
TelegramConflictError,
|
|
121
|
+
TokenValidationError,
|
|
122
|
+
) as req_err:
|
|
123
|
+
logger.error(
|
|
124
|
+
f"Unauthorized err getting telegram bot username with token {tg_bot_token}: {req_err}",
|
|
125
|
+
)
|
|
126
|
+
return agent_data
|
|
127
|
+
except Exception as e:
|
|
128
|
+
logger.error(
|
|
129
|
+
f"Error getting telegram bot username with token {tg_bot_token}: {e}",
|
|
130
|
+
)
|
|
131
|
+
return agent_data
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _send_agent_notification(agent: Agent, agent_data: AgentData, message: str) -> None:
|
|
135
|
+
"""Send a notification about agent creation or update.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
agent: The agent that was created or updated
|
|
139
|
+
agent_data: The agent data to update
|
|
140
|
+
message: The notification message
|
|
141
|
+
"""
|
|
142
|
+
# Format autonomous configurations - show only enabled ones with their id, name, and schedule
|
|
143
|
+
autonomous_formatted = ""
|
|
144
|
+
if agent.autonomous:
|
|
145
|
+
enabled_autonomous = [auto for auto in agent.autonomous if auto.enabled]
|
|
146
|
+
if enabled_autonomous:
|
|
147
|
+
autonomous_items = []
|
|
148
|
+
for auto in enabled_autonomous:
|
|
149
|
+
schedule = (
|
|
150
|
+
f"cron: {auto.cron}" if auto.cron else f"minutes: {auto.minutes}"
|
|
151
|
+
)
|
|
152
|
+
autonomous_items.append(
|
|
153
|
+
f"• {auto.id}: {auto.name or 'Unnamed'} ({schedule})"
|
|
154
|
+
)
|
|
155
|
+
autonomous_formatted = "\n".join(autonomous_items)
|
|
156
|
+
else:
|
|
157
|
+
autonomous_formatted = "No enabled autonomous configurations"
|
|
158
|
+
else:
|
|
159
|
+
autonomous_formatted = "None"
|
|
160
|
+
|
|
161
|
+
# Format skills - find categories with enabled: true and list skills in public/private states
|
|
162
|
+
skills_formatted = ""
|
|
163
|
+
if agent.skills:
|
|
164
|
+
enabled_categories = []
|
|
165
|
+
for category, skill_config in agent.skills.items():
|
|
166
|
+
if skill_config and skill_config.get("enabled") is True:
|
|
167
|
+
skills_list = []
|
|
168
|
+
states = skill_config.get("states", {})
|
|
169
|
+
public_skills = [
|
|
170
|
+
skill for skill, state in states.items() if state == "public"
|
|
171
|
+
]
|
|
172
|
+
private_skills = [
|
|
173
|
+
skill for skill, state in states.items() if state == "private"
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
if public_skills:
|
|
177
|
+
skills_list.append(f" Public: {', '.join(public_skills)}")
|
|
178
|
+
if private_skills:
|
|
179
|
+
skills_list.append(f" Private: {', '.join(private_skills)}")
|
|
180
|
+
|
|
181
|
+
if skills_list:
|
|
182
|
+
enabled_categories.append(
|
|
183
|
+
f"• {category}:\n{chr(10).join(skills_list)}"
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
if enabled_categories:
|
|
187
|
+
skills_formatted = "\n".join(enabled_categories)
|
|
188
|
+
else:
|
|
189
|
+
skills_formatted = "No enabled skills"
|
|
190
|
+
else:
|
|
191
|
+
skills_formatted = "None"
|
|
192
|
+
|
|
193
|
+
send_slack_message(
|
|
194
|
+
message,
|
|
195
|
+
attachments=[
|
|
196
|
+
{
|
|
197
|
+
"color": "good",
|
|
198
|
+
"fields": [
|
|
199
|
+
{"title": "ID", "short": True, "value": agent.id},
|
|
200
|
+
{"title": "Name", "short": True, "value": agent.name},
|
|
201
|
+
{"title": "Model", "short": True, "value": agent.model},
|
|
202
|
+
{
|
|
203
|
+
"title": "Network",
|
|
204
|
+
"short": True,
|
|
205
|
+
"value": agent.network_id or "Default",
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"title": "X Username",
|
|
209
|
+
"short": True,
|
|
210
|
+
"value": agent_data.twitter_username,
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"title": "Telegram Enabled",
|
|
214
|
+
"short": True,
|
|
215
|
+
"value": str(agent.telegram_entrypoint_enabled),
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"title": "Telegram Username",
|
|
219
|
+
"short": True,
|
|
220
|
+
"value": agent_data.telegram_username,
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"title": "Wallet Address",
|
|
224
|
+
"value": agent_data.evm_wallet_address,
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"title": "Autonomous",
|
|
228
|
+
"value": autonomous_formatted,
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"title": "Skills",
|
|
232
|
+
"value": skills_formatted,
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
}
|
|
236
|
+
],
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
async def deploy_agent(
|
|
241
|
+
agent_id: str, agent: AgentUpdate, owner: Optional[str] = None
|
|
242
|
+
) -> AgentResponse:
|
|
243
|
+
"""Override an existing agent.
|
|
244
|
+
|
|
245
|
+
Use input to override agent configuration. If some fields are not provided, they will be reset to default values.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
agent_id: ID of the agent to update
|
|
249
|
+
agent: Agent update configuration
|
|
250
|
+
owner: Optional owner for the agent
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
AgentResponse: Updated agent configuration with additional processed data
|
|
254
|
+
|
|
255
|
+
Raises:
|
|
256
|
+
HTTPException:
|
|
257
|
+
- 400: Invalid agent ID format
|
|
258
|
+
- 404: Agent not found
|
|
259
|
+
- 403: Permission denied (if owner mismatch)
|
|
260
|
+
- 500: Database error
|
|
261
|
+
"""
|
|
262
|
+
existing_agent = await Agent.get(agent_id)
|
|
263
|
+
if not existing_agent:
|
|
264
|
+
agent = AgentCreate.model_validate(input)
|
|
265
|
+
agent.id = agent_id
|
|
266
|
+
if owner:
|
|
267
|
+
agent.owner = owner
|
|
268
|
+
else:
|
|
269
|
+
agent.owner = "system"
|
|
270
|
+
# Check for existing agent by upstream_id, forward compatibility, raise error after 3.0
|
|
271
|
+
existing = await agent.get_by_upstream_id()
|
|
272
|
+
if existing:
|
|
273
|
+
agent_data = await AgentData.get(existing.id)
|
|
274
|
+
agent_response = await AgentResponse.from_agent(existing, agent_data)
|
|
275
|
+
return agent_response
|
|
276
|
+
|
|
277
|
+
# Create new agent
|
|
278
|
+
latest_agent = await agent.create()
|
|
279
|
+
# Process common post-creation actions
|
|
280
|
+
agent_data = await _process_agent_post_actions(
|
|
281
|
+
latest_agent, True, "Agent Created"
|
|
282
|
+
)
|
|
283
|
+
agent_data = await _process_telegram_config(input, None, agent_data)
|
|
284
|
+
agent_response = await AgentResponse.from_agent(latest_agent, agent_data)
|
|
285
|
+
|
|
286
|
+
return agent_response
|
|
287
|
+
|
|
288
|
+
if owner and owner != existing_agent.owner:
|
|
289
|
+
raise IntentKitAPIError(403, "forbidden", "forbidden")
|
|
290
|
+
|
|
291
|
+
# Update agent
|
|
292
|
+
latest_agent = await agent.override(agent_id)
|
|
293
|
+
|
|
294
|
+
# Process common post-update actions
|
|
295
|
+
agent_data = await _process_agent_post_actions(
|
|
296
|
+
latest_agent, False, "Agent Overridden"
|
|
297
|
+
)
|
|
298
|
+
agent_data = await _process_telegram_config(agent, existing_agent, agent_data)
|
|
299
|
+
agent_response = await AgentResponse.from_agent(latest_agent, agent_data)
|
|
300
|
+
|
|
301
|
+
return agent_response
|
|
302
|
+
|
|
303
|
+
|
|
18
304
|
async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
|
|
19
305
|
"""
|
|
20
306
|
Calculate various action cost metrics for an agent based on past three days of credit events.
|
|
@@ -192,6 +478,182 @@ async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
|
|
|
192
478
|
return result
|
|
193
479
|
|
|
194
480
|
|
|
481
|
+
class AgentStore(SkillStoreABC):
|
|
482
|
+
"""Implementation of skill data storage operations.
|
|
483
|
+
|
|
484
|
+
This class provides concrete implementations for storing and retrieving
|
|
485
|
+
skill-related data for both agents and threads.
|
|
486
|
+
"""
|
|
487
|
+
|
|
488
|
+
@staticmethod
|
|
489
|
+
def get_system_config(key: str) -> Any:
|
|
490
|
+
# TODO: maybe need a whitelist here
|
|
491
|
+
if hasattr(config, key):
|
|
492
|
+
return getattr(config, key)
|
|
493
|
+
return None
|
|
494
|
+
|
|
495
|
+
@staticmethod
|
|
496
|
+
async def get_agent_config(agent_id: str) -> Optional[Agent]:
|
|
497
|
+
return await Agent.get(agent_id)
|
|
498
|
+
|
|
499
|
+
@staticmethod
|
|
500
|
+
async def get_agent_data(agent_id: str) -> AgentData:
|
|
501
|
+
return await AgentData.get(agent_id)
|
|
502
|
+
|
|
503
|
+
@staticmethod
|
|
504
|
+
async def set_agent_data(agent_id: str, data: Dict) -> AgentData:
|
|
505
|
+
return await AgentData.patch(agent_id, data)
|
|
506
|
+
|
|
507
|
+
@staticmethod
|
|
508
|
+
async def get_agent_quota(agent_id: str) -> AgentQuota:
|
|
509
|
+
return await AgentQuota.get(agent_id)
|
|
510
|
+
|
|
511
|
+
@staticmethod
|
|
512
|
+
async def get_agent_skill_data(
|
|
513
|
+
agent_id: str, skill: str, key: str
|
|
514
|
+
) -> Optional[Dict[str, Any]]:
|
|
515
|
+
"""Get skill data for an agent.
|
|
516
|
+
|
|
517
|
+
Args:
|
|
518
|
+
agent_id: ID of the agent
|
|
519
|
+
skill: Name of the skill
|
|
520
|
+
key: Data key
|
|
521
|
+
|
|
522
|
+
Returns:
|
|
523
|
+
Dictionary containing the skill data if found, None otherwise
|
|
524
|
+
"""
|
|
525
|
+
return await AgentSkillData.get(agent_id, skill, key)
|
|
526
|
+
|
|
527
|
+
@staticmethod
|
|
528
|
+
async def save_agent_skill_data(
|
|
529
|
+
agent_id: str, skill: str, key: str, data: Dict[str, Any]
|
|
530
|
+
) -> None:
|
|
531
|
+
"""Save or update skill data for an agent.
|
|
532
|
+
|
|
533
|
+
Args:
|
|
534
|
+
agent_id: ID of the agent
|
|
535
|
+
skill: Name of the skill
|
|
536
|
+
key: Data key
|
|
537
|
+
data: JSON data to store
|
|
538
|
+
"""
|
|
539
|
+
skill_data = AgentSkillDataCreate(
|
|
540
|
+
agent_id=agent_id,
|
|
541
|
+
skill=skill,
|
|
542
|
+
key=key,
|
|
543
|
+
data=data,
|
|
544
|
+
)
|
|
545
|
+
await skill_data.save()
|
|
546
|
+
|
|
547
|
+
@staticmethod
|
|
548
|
+
async def delete_agent_skill_data(agent_id: str, skill: str, key: str) -> None:
|
|
549
|
+
"""Delete skill data for an agent.
|
|
550
|
+
|
|
551
|
+
Args:
|
|
552
|
+
agent_id: ID of the agent
|
|
553
|
+
skill: Name of the skill
|
|
554
|
+
key: Data key
|
|
555
|
+
"""
|
|
556
|
+
await AgentSkillData.delete(agent_id, skill, key)
|
|
557
|
+
|
|
558
|
+
@staticmethod
|
|
559
|
+
async def get_thread_skill_data(
|
|
560
|
+
thread_id: str, skill: str, key: str
|
|
561
|
+
) -> Optional[Dict[str, Any]]:
|
|
562
|
+
"""Get skill data for a thread.
|
|
563
|
+
|
|
564
|
+
Args:
|
|
565
|
+
thread_id: ID of the thread
|
|
566
|
+
skill: Name of the skill
|
|
567
|
+
key: Data key
|
|
568
|
+
|
|
569
|
+
Returns:
|
|
570
|
+
Dictionary containing the skill data if found, None otherwise
|
|
571
|
+
"""
|
|
572
|
+
return await ThreadSkillData.get(thread_id, skill, key)
|
|
573
|
+
|
|
574
|
+
@staticmethod
|
|
575
|
+
async def save_thread_skill_data(
|
|
576
|
+
thread_id: str,
|
|
577
|
+
agent_id: str,
|
|
578
|
+
skill: str,
|
|
579
|
+
key: str,
|
|
580
|
+
data: Dict[str, Any],
|
|
581
|
+
) -> None:
|
|
582
|
+
"""Save or update skill data for a thread.
|
|
583
|
+
|
|
584
|
+
Args:
|
|
585
|
+
thread_id: ID of the thread
|
|
586
|
+
agent_id: ID of the agent that owns this thread
|
|
587
|
+
skill: Name of the skill
|
|
588
|
+
key: Data key
|
|
589
|
+
data: JSON data to store
|
|
590
|
+
"""
|
|
591
|
+
skill_data = ThreadSkillDataCreate(
|
|
592
|
+
thread_id=thread_id,
|
|
593
|
+
agent_id=agent_id,
|
|
594
|
+
skill=skill,
|
|
595
|
+
key=key,
|
|
596
|
+
data=data,
|
|
597
|
+
)
|
|
598
|
+
await skill_data.save()
|
|
599
|
+
|
|
600
|
+
@staticmethod
|
|
601
|
+
async def list_autonomous_tasks(agent_id: str) -> List[AgentAutonomous]:
|
|
602
|
+
"""List all autonomous tasks for an agent.
|
|
603
|
+
|
|
604
|
+
Args:
|
|
605
|
+
agent_id: ID of the agent
|
|
606
|
+
|
|
607
|
+
Returns:
|
|
608
|
+
List[AgentAutonomous]: List of autonomous task configurations
|
|
609
|
+
"""
|
|
610
|
+
return await list_autonomous_tasks(agent_id)
|
|
611
|
+
|
|
612
|
+
@staticmethod
|
|
613
|
+
async def add_autonomous_task(
|
|
614
|
+
agent_id: str, task: AgentAutonomous
|
|
615
|
+
) -> AgentAutonomous:
|
|
616
|
+
"""Add a new autonomous task to an agent.
|
|
617
|
+
|
|
618
|
+
Args:
|
|
619
|
+
agent_id: ID of the agent
|
|
620
|
+
task: Autonomous task configuration
|
|
621
|
+
|
|
622
|
+
Returns:
|
|
623
|
+
AgentAutonomous: The created task
|
|
624
|
+
"""
|
|
625
|
+
return await add_autonomous_task(agent_id, task)
|
|
626
|
+
|
|
627
|
+
@staticmethod
|
|
628
|
+
async def delete_autonomous_task(agent_id: str, task_id: str) -> None:
|
|
629
|
+
"""Delete an autonomous task from an agent.
|
|
630
|
+
|
|
631
|
+
Args:
|
|
632
|
+
agent_id: ID of the agent
|
|
633
|
+
task_id: ID of the task to delete
|
|
634
|
+
"""
|
|
635
|
+
await delete_autonomous_task(agent_id, task_id)
|
|
636
|
+
|
|
637
|
+
@staticmethod
|
|
638
|
+
async def update_autonomous_task(
|
|
639
|
+
agent_id: str, task_id: str, task_updates: dict
|
|
640
|
+
) -> AgentAutonomous:
|
|
641
|
+
"""Update an autonomous task for an agent.
|
|
642
|
+
|
|
643
|
+
Args:
|
|
644
|
+
agent_id: ID of the agent
|
|
645
|
+
task_id: ID of the task to update
|
|
646
|
+
task_updates: Dictionary containing fields to update
|
|
647
|
+
|
|
648
|
+
Returns:
|
|
649
|
+
AgentAutonomous: The updated task
|
|
650
|
+
"""
|
|
651
|
+
return await update_autonomous_task(agent_id, task_id, task_updates)
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
agent_store = AgentStore()
|
|
655
|
+
|
|
656
|
+
|
|
195
657
|
async def update_agent_action_cost():
|
|
196
658
|
"""
|
|
197
659
|
Update action costs for all agents.
|
intentkit/core/engine.py
CHANGED
|
@@ -35,6 +35,7 @@ from sqlalchemy.exc import SQLAlchemyError
|
|
|
35
35
|
|
|
36
36
|
from intentkit.abstracts.graph import AgentContext, AgentError, AgentState
|
|
37
37
|
from intentkit.config.config import config
|
|
38
|
+
from intentkit.core.agent import agent_store
|
|
38
39
|
from intentkit.core.chat import clear_thread_memory
|
|
39
40
|
from intentkit.core.credit import expense_message, expense_skill
|
|
40
41
|
from intentkit.core.node import PreModelNode, post_model_node
|
|
@@ -42,7 +43,6 @@ from intentkit.core.prompt import (
|
|
|
42
43
|
create_formatted_prompt_function,
|
|
43
44
|
explain_prompt,
|
|
44
45
|
)
|
|
45
|
-
from intentkit.core.skill import skill_store
|
|
46
46
|
from intentkit.models.agent import Agent, AgentTable
|
|
47
47
|
from intentkit.models.agent_data import AgentData, AgentQuota
|
|
48
48
|
from intentkit.models.app_setting import AppSetting, SystemMessageType
|
|
@@ -54,7 +54,7 @@ from intentkit.models.chat import (
|
|
|
54
54
|
)
|
|
55
55
|
from intentkit.models.credit import CreditAccount, OwnerType
|
|
56
56
|
from intentkit.models.db import get_langgraph_checkpointer, get_session
|
|
57
|
-
from intentkit.models.llm import LLMModelInfo, LLMProvider
|
|
57
|
+
from intentkit.models.llm import LLMModelInfo, LLMProvider, create_llm_model
|
|
58
58
|
from intentkit.models.skill import AgentSkillData, ThreadSkillData
|
|
59
59
|
from intentkit.models.user import User
|
|
60
60
|
from intentkit.utils.error import IntentKitAPIError
|
|
@@ -71,9 +71,7 @@ _agents_updated: dict[str, datetime] = {}
|
|
|
71
71
|
_private_agents_updated: dict[str, datetime] = {}
|
|
72
72
|
|
|
73
73
|
|
|
74
|
-
async def create_agent(
|
|
75
|
-
agent: Agent, is_private: bool = False, has_search: bool = False
|
|
76
|
-
) -> CompiledStateGraph:
|
|
74
|
+
async def create_agent(agent: Agent, is_private: bool = False) -> CompiledStateGraph:
|
|
77
75
|
"""Create an AI agent with specified configuration and tools.
|
|
78
76
|
|
|
79
77
|
This function:
|
|
@@ -92,9 +90,6 @@ async def create_agent(
|
|
|
92
90
|
"""
|
|
93
91
|
agent_data = await AgentData.get(agent.id)
|
|
94
92
|
|
|
95
|
-
# ==== Initialize LLM using the LLM abstraction.
|
|
96
|
-
from intentkit.models.llm import create_llm_model
|
|
97
|
-
|
|
98
93
|
# Create the LLM model instance
|
|
99
94
|
llm_model = await create_llm_model(
|
|
100
95
|
model_name=agent.model,
|
|
@@ -123,7 +118,7 @@ async def create_agent(
|
|
|
123
118
|
skill_module = importlib.import_module(f"intentkit.skills.{k}")
|
|
124
119
|
if hasattr(skill_module, "get_skills"):
|
|
125
120
|
skill_tools = await skill_module.get_skills(
|
|
126
|
-
v, is_private,
|
|
121
|
+
v, is_private, agent_store, agent_id=agent.id
|
|
127
122
|
)
|
|
128
123
|
if skill_tools and len(skill_tools) > 0:
|
|
129
124
|
tools.extend(skill_tools)
|
|
@@ -137,8 +132,7 @@ async def create_agent(
|
|
|
137
132
|
|
|
138
133
|
# Add search tools if requested
|
|
139
134
|
if (
|
|
140
|
-
|
|
141
|
-
and llm_model.info.provider == LLMProvider.OPENAI
|
|
135
|
+
llm_model.info.provider == LLMProvider.OPENAI
|
|
142
136
|
and llm_model.info.supports_search
|
|
143
137
|
and not agent.model.startswith(
|
|
144
138
|
"gpt-5"
|
|
@@ -159,7 +153,7 @@ async def create_agent(
|
|
|
159
153
|
model=llm,
|
|
160
154
|
short_term_memory_strategy=agent.short_term_memory_strategy,
|
|
161
155
|
max_tokens=input_token_limit // 2,
|
|
162
|
-
max_summary_tokens=2048,
|
|
156
|
+
max_summary_tokens=2048,
|
|
163
157
|
)
|
|
164
158
|
|
|
165
159
|
# Create ReAct Agent using the LLM and CDP Agentkit tools.
|
|
@@ -202,21 +196,8 @@ async def initialize_agent(aid, is_private=False):
|
|
|
202
196
|
if not agent:
|
|
203
197
|
raise HTTPException(status_code=404, detail="Agent not found")
|
|
204
198
|
|
|
205
|
-
# Determine if search should be enabled based on model capabilities
|
|
206
|
-
from intentkit.models.llm import create_llm_model
|
|
207
|
-
|
|
208
|
-
llm_model = await create_llm_model(
|
|
209
|
-
model_name=agent.model,
|
|
210
|
-
temperature=agent.temperature,
|
|
211
|
-
frequency_penalty=agent.frequency_penalty,
|
|
212
|
-
presence_penalty=agent.presence_penalty,
|
|
213
|
-
)
|
|
214
|
-
has_search = (
|
|
215
|
-
llm_model.info.provider == LLMProvider.OPENAI and llm_model.info.supports_search
|
|
216
|
-
)
|
|
217
|
-
|
|
218
199
|
# Create the agent using the new create_agent function
|
|
219
|
-
executor = await create_agent(agent, is_private
|
|
200
|
+
executor = await create_agent(agent, is_private)
|
|
220
201
|
|
|
221
202
|
# Cache the agent executor
|
|
222
203
|
if is_private:
|
intentkit/core/prompt.py
CHANGED
|
@@ -106,7 +106,7 @@ def _build_wallet_section(agent: Agent, agent_data: AgentData) -> str:
|
|
|
106
106
|
return ""
|
|
107
107
|
|
|
108
108
|
wallet_parts = []
|
|
109
|
-
network_id = agent.network_id
|
|
109
|
+
network_id = agent.network_id
|
|
110
110
|
|
|
111
111
|
if agent_data.evm_wallet_address and network_id != "solana":
|
|
112
112
|
wallet_parts.append(
|