intentkit 0.6.5.dev8__py3-none-any.whl → 0.6.7__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/skill.py +59 -2
- intentkit/core/agent.py +276 -3
- intentkit/core/engine.py +39 -12
- intentkit/core/skill.py +67 -2
- intentkit/models/agent.py +10 -0
- intentkit/models/agent_data.py +30 -0
- intentkit/models/app_setting.py +25 -1
- intentkit/models/credit.py +15 -5
- intentkit/skills/system/__init__.py +32 -0
- intentkit/skills/system/add_autonomous_task.py +93 -0
- intentkit/skills/system/delete_autonomous_task.py +56 -0
- intentkit/skills/system/edit_autonomous_task.py +116 -0
- intentkit/skills/system/list_autonomous_tasks.py +52 -0
- intentkit/skills/system/schema.json +58 -2
- {intentkit-0.6.5.dev8.dist-info → intentkit-0.6.7.dist-info}/METADATA +1 -1
- {intentkit-0.6.5.dev8.dist-info → intentkit-0.6.7.dist-info}/RECORD +19 -15
- {intentkit-0.6.5.dev8.dist-info → intentkit-0.6.7.dist-info}/WHEEL +0 -0
- {intentkit-0.6.5.dev8.dist-info → intentkit-0.6.7.dist-info}/licenses/LICENSE +0 -0
intentkit/__init__.py
CHANGED
intentkit/abstracts/skill.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Any, Dict, Optional
|
|
2
|
+
from typing import Any, Dict, List, Optional
|
|
3
3
|
|
|
4
|
-
from intentkit.models.agent import Agent
|
|
4
|
+
from intentkit.models.agent import Agent, AgentAutonomous
|
|
5
5
|
from intentkit.models.agent_data import AgentData, AgentQuota
|
|
6
6
|
|
|
7
7
|
|
|
@@ -139,3 +139,60 @@ class SkillStoreABC(ABC):
|
|
|
139
139
|
data: JSON data to store
|
|
140
140
|
"""
|
|
141
141
|
pass
|
|
142
|
+
|
|
143
|
+
@staticmethod
|
|
144
|
+
@abstractmethod
|
|
145
|
+
async def list_autonomous_tasks(agent_id: str) -> List[AgentAutonomous]:
|
|
146
|
+
"""List all autonomous tasks for an agent.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
agent_id: ID of the agent
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
List[AgentAutonomous]: List of autonomous task configurations
|
|
153
|
+
"""
|
|
154
|
+
pass
|
|
155
|
+
|
|
156
|
+
@staticmethod
|
|
157
|
+
@abstractmethod
|
|
158
|
+
async def add_autonomous_task(
|
|
159
|
+
agent_id: str, task: AgentAutonomous
|
|
160
|
+
) -> AgentAutonomous:
|
|
161
|
+
"""Add a new autonomous task to an agent.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
agent_id: ID of the agent
|
|
165
|
+
task: Autonomous task configuration
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
AgentAutonomous: The created task
|
|
169
|
+
"""
|
|
170
|
+
pass
|
|
171
|
+
|
|
172
|
+
@staticmethod
|
|
173
|
+
@abstractmethod
|
|
174
|
+
async def delete_autonomous_task(agent_id: str, task_id: str) -> None:
|
|
175
|
+
"""Delete an autonomous task from an agent.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
agent_id: ID of the agent
|
|
179
|
+
task_id: ID of the task to delete
|
|
180
|
+
"""
|
|
181
|
+
pass
|
|
182
|
+
|
|
183
|
+
@staticmethod
|
|
184
|
+
@abstractmethod
|
|
185
|
+
async def update_autonomous_task(
|
|
186
|
+
agent_id: str, task_id: str, task_updates: dict
|
|
187
|
+
) -> AgentAutonomous:
|
|
188
|
+
"""Update an autonomous task for an agent.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
agent_id: ID of the agent
|
|
192
|
+
task_id: ID of the task to update
|
|
193
|
+
task_updates: Dictionary containing fields to update
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
AgentAutonomous: The updated task
|
|
197
|
+
"""
|
|
198
|
+
pass
|
intentkit/core/agent.py
CHANGED
|
@@ -2,11 +2,12 @@ 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
|
|
5
|
+
from typing import Dict, List
|
|
6
6
|
|
|
7
|
-
from sqlalchemy import func, select, text
|
|
7
|
+
from sqlalchemy import func, select, text, update
|
|
8
8
|
|
|
9
|
-
from intentkit.models.agent import Agent
|
|
9
|
+
from intentkit.models.agent import Agent, AgentAutonomous, AgentTable
|
|
10
|
+
from intentkit.models.agent_data import AgentQuotaTable
|
|
10
11
|
from intentkit.models.credit import CreditEventTable, EventType, UpstreamType
|
|
11
12
|
from intentkit.models.db import get_session
|
|
12
13
|
from intentkit.utils.error import IntentKitAPIError
|
|
@@ -189,3 +190,275 @@ async def agent_action_cost(agent_id: str) -> Dict[str, Decimal]:
|
|
|
189
190
|
)
|
|
190
191
|
|
|
191
192
|
return result
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
async def update_agent_action_cost():
|
|
196
|
+
"""
|
|
197
|
+
Update action costs for all agents.
|
|
198
|
+
|
|
199
|
+
This function processes agents in batches of 100 to avoid memory issues.
|
|
200
|
+
For each agent, it calculates various action cost metrics:
|
|
201
|
+
- avg_action_cost: average cost per action
|
|
202
|
+
- min_action_cost: minimum cost per action
|
|
203
|
+
- max_action_cost: maximum cost per action
|
|
204
|
+
- low_action_cost: average cost of the lowest 20% of actions
|
|
205
|
+
- medium_action_cost: average cost of the middle 60% of actions
|
|
206
|
+
- high_action_cost: average cost of the highest 20% of actions
|
|
207
|
+
|
|
208
|
+
It then updates the corresponding record in the agent_quotas table.
|
|
209
|
+
"""
|
|
210
|
+
logger.info("Starting update of agent average action costs")
|
|
211
|
+
start_time = time.time()
|
|
212
|
+
batch_size = 100
|
|
213
|
+
last_id = None
|
|
214
|
+
total_updated = 0
|
|
215
|
+
|
|
216
|
+
while True:
|
|
217
|
+
# Get a batch of agent IDs ordered by ID
|
|
218
|
+
async with get_session() as session:
|
|
219
|
+
query = select(AgentTable.id).order_by(AgentTable.id)
|
|
220
|
+
|
|
221
|
+
# Apply pagination if we have a last_id from previous batch
|
|
222
|
+
if last_id:
|
|
223
|
+
query = query.where(AgentTable.id > last_id)
|
|
224
|
+
|
|
225
|
+
query = query.limit(batch_size)
|
|
226
|
+
result = await session.execute(query)
|
|
227
|
+
agent_ids = [row[0] for row in result]
|
|
228
|
+
|
|
229
|
+
# If no more agents, we're done
|
|
230
|
+
if not agent_ids:
|
|
231
|
+
break
|
|
232
|
+
|
|
233
|
+
# Update last_id for next batch
|
|
234
|
+
last_id = agent_ids[-1]
|
|
235
|
+
|
|
236
|
+
# Process this batch of agents
|
|
237
|
+
logger.info(
|
|
238
|
+
f"Processing batch of {len(agent_ids)} agents starting with ID {agent_ids[0]}"
|
|
239
|
+
)
|
|
240
|
+
batch_start_time = time.time()
|
|
241
|
+
|
|
242
|
+
for agent_id in agent_ids:
|
|
243
|
+
try:
|
|
244
|
+
# Calculate action costs for this agent
|
|
245
|
+
costs = await agent_action_cost(agent_id)
|
|
246
|
+
|
|
247
|
+
# Update the agent's quota record
|
|
248
|
+
async with get_session() as session:
|
|
249
|
+
update_stmt = (
|
|
250
|
+
update(AgentQuotaTable)
|
|
251
|
+
.where(AgentQuotaTable.id == agent_id)
|
|
252
|
+
.values(
|
|
253
|
+
avg_action_cost=costs["avg_action_cost"],
|
|
254
|
+
min_action_cost=costs["min_action_cost"],
|
|
255
|
+
max_action_cost=costs["max_action_cost"],
|
|
256
|
+
low_action_cost=costs["low_action_cost"],
|
|
257
|
+
medium_action_cost=costs["medium_action_cost"],
|
|
258
|
+
high_action_cost=costs["high_action_cost"],
|
|
259
|
+
)
|
|
260
|
+
)
|
|
261
|
+
await session.execute(update_stmt)
|
|
262
|
+
await session.commit()
|
|
263
|
+
|
|
264
|
+
total_updated += 1
|
|
265
|
+
except Exception as e:
|
|
266
|
+
logger.error(
|
|
267
|
+
f"Error updating action costs for agent {agent_id}: {str(e)}"
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
batch_time = time.time() - batch_start_time
|
|
271
|
+
logger.info(f"Completed batch in {batch_time:.3f}s")
|
|
272
|
+
|
|
273
|
+
total_time = time.time() - start_time
|
|
274
|
+
logger.info(
|
|
275
|
+
f"Finished updating action costs for {total_updated} agents in {total_time:.3f}s"
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
async def list_autonomous_tasks(agent_id: str) -> List[AgentAutonomous]:
|
|
280
|
+
"""
|
|
281
|
+
List all autonomous tasks for an agent.
|
|
282
|
+
|
|
283
|
+
Args:
|
|
284
|
+
agent_id: ID of the agent
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
List[AgentAutonomous]: List of autonomous task configurations
|
|
288
|
+
|
|
289
|
+
Raises:
|
|
290
|
+
IntentKitAPIError: If agent is not found
|
|
291
|
+
"""
|
|
292
|
+
agent = await Agent.get(agent_id)
|
|
293
|
+
if not agent:
|
|
294
|
+
raise IntentKitAPIError(
|
|
295
|
+
400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
if not agent.autonomous:
|
|
299
|
+
return []
|
|
300
|
+
|
|
301
|
+
return agent.autonomous
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
async def add_autonomous_task(agent_id: str, task: AgentAutonomous) -> AgentAutonomous:
|
|
305
|
+
"""
|
|
306
|
+
Add a new autonomous task to an agent.
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
agent_id: ID of the agent
|
|
310
|
+
task: Autonomous task configuration (id will be generated if not provided)
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
AgentAutonomous: The created task with generated ID
|
|
314
|
+
|
|
315
|
+
Raises:
|
|
316
|
+
IntentKitAPIError: If agent is not found
|
|
317
|
+
"""
|
|
318
|
+
agent = await Agent.get(agent_id)
|
|
319
|
+
if not agent:
|
|
320
|
+
raise IntentKitAPIError(
|
|
321
|
+
400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
# Get current autonomous tasks
|
|
325
|
+
current_tasks = agent.autonomous or []
|
|
326
|
+
if not isinstance(current_tasks, list):
|
|
327
|
+
current_tasks = []
|
|
328
|
+
|
|
329
|
+
# Add the new task
|
|
330
|
+
current_tasks.append(task)
|
|
331
|
+
|
|
332
|
+
# Convert all AgentAutonomous objects to dictionaries for JSON serialization
|
|
333
|
+
serializable_tasks = [task_item.model_dump() for task_item in current_tasks]
|
|
334
|
+
|
|
335
|
+
# Update the agent in the database
|
|
336
|
+
async with get_session() as session:
|
|
337
|
+
update_stmt = (
|
|
338
|
+
update(AgentTable)
|
|
339
|
+
.where(AgentTable.id == agent_id)
|
|
340
|
+
.values(autonomous=serializable_tasks)
|
|
341
|
+
)
|
|
342
|
+
await session.execute(update_stmt)
|
|
343
|
+
await session.commit()
|
|
344
|
+
|
|
345
|
+
logger.info(f"Added autonomous task {task.id} to agent {agent_id}")
|
|
346
|
+
return task
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
async def delete_autonomous_task(agent_id: str, task_id: str) -> None:
|
|
350
|
+
"""
|
|
351
|
+
Delete an autonomous task from an agent.
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
agent_id: ID of the agent
|
|
355
|
+
task_id: ID of the task to delete
|
|
356
|
+
|
|
357
|
+
Raises:
|
|
358
|
+
IntentKitAPIError: If agent is not found or task is not found
|
|
359
|
+
"""
|
|
360
|
+
agent = await Agent.get(agent_id)
|
|
361
|
+
if not agent:
|
|
362
|
+
raise IntentKitAPIError(
|
|
363
|
+
400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
# Get current autonomous tasks
|
|
367
|
+
current_tasks = agent.autonomous or []
|
|
368
|
+
if not isinstance(current_tasks, list):
|
|
369
|
+
current_tasks = []
|
|
370
|
+
|
|
371
|
+
# Find and remove the task
|
|
372
|
+
task_found = False
|
|
373
|
+
updated_tasks = []
|
|
374
|
+
for task_data in current_tasks:
|
|
375
|
+
if task_data.id == task_id:
|
|
376
|
+
task_found = True
|
|
377
|
+
continue
|
|
378
|
+
updated_tasks.append(task_data)
|
|
379
|
+
|
|
380
|
+
if not task_found:
|
|
381
|
+
raise IntentKitAPIError(
|
|
382
|
+
404, "TaskNotFound", f"Autonomous task with ID {task_id} not found."
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
# Convert remaining AgentAutonomous objects to dictionaries for JSON serialization
|
|
386
|
+
serializable_tasks = [task_item.model_dump() for task_item in updated_tasks]
|
|
387
|
+
|
|
388
|
+
# Update the agent in the database
|
|
389
|
+
async with get_session() as session:
|
|
390
|
+
update_stmt = (
|
|
391
|
+
update(AgentTable)
|
|
392
|
+
.where(AgentTable.id == agent_id)
|
|
393
|
+
.values(autonomous=serializable_tasks)
|
|
394
|
+
)
|
|
395
|
+
await session.execute(update_stmt)
|
|
396
|
+
await session.commit()
|
|
397
|
+
|
|
398
|
+
logger.info(f"Deleted autonomous task {task_id} from agent {agent_id}")
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
async def update_autonomous_task(
|
|
402
|
+
agent_id: str, task_id: str, task_updates: dict
|
|
403
|
+
) -> AgentAutonomous:
|
|
404
|
+
"""
|
|
405
|
+
Update an autonomous task for an agent.
|
|
406
|
+
|
|
407
|
+
Args:
|
|
408
|
+
agent_id: ID of the agent
|
|
409
|
+
task_id: ID of the task to update
|
|
410
|
+
task_updates: Dictionary containing fields to update
|
|
411
|
+
|
|
412
|
+
Returns:
|
|
413
|
+
AgentAutonomous: The updated task
|
|
414
|
+
|
|
415
|
+
Raises:
|
|
416
|
+
IntentKitAPIError: If agent is not found or task is not found
|
|
417
|
+
"""
|
|
418
|
+
agent = await Agent.get(agent_id)
|
|
419
|
+
if not agent:
|
|
420
|
+
raise IntentKitAPIError(
|
|
421
|
+
400, "AgentNotFound", f"Agent with ID {agent_id} does not exist."
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
# Get current autonomous tasks
|
|
425
|
+
current_tasks: List[AgentAutonomous] = agent.autonomous or []
|
|
426
|
+
|
|
427
|
+
# Find and update the task
|
|
428
|
+
task_found = False
|
|
429
|
+
updated_tasks: List[AgentAutonomous] = []
|
|
430
|
+
updated_task = None
|
|
431
|
+
|
|
432
|
+
for task_data in current_tasks:
|
|
433
|
+
if task_data.id == task_id:
|
|
434
|
+
task_found = True
|
|
435
|
+
# Create a dictionary with current task data
|
|
436
|
+
task_dict = task_data.model_dump()
|
|
437
|
+
# Update with provided fields
|
|
438
|
+
task_dict.update(task_updates)
|
|
439
|
+
# Create new AgentAutonomous instance
|
|
440
|
+
updated_task = AgentAutonomous.model_validate(task_dict)
|
|
441
|
+
updated_tasks.append(updated_task)
|
|
442
|
+
else:
|
|
443
|
+
updated_tasks.append(task_data)
|
|
444
|
+
|
|
445
|
+
if not task_found:
|
|
446
|
+
raise IntentKitAPIError(
|
|
447
|
+
404, "TaskNotFound", f"Autonomous task with ID {task_id} not found."
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
# Convert all AgentAutonomous objects to dictionaries for JSON serialization
|
|
451
|
+
serializable_tasks = [task_item.model_dump() for task_item in updated_tasks]
|
|
452
|
+
|
|
453
|
+
# Update the agent in the database
|
|
454
|
+
async with get_session() as session:
|
|
455
|
+
update_stmt = (
|
|
456
|
+
update(AgentTable)
|
|
457
|
+
.where(AgentTable.id == agent_id)
|
|
458
|
+
.values(autonomous=serializable_tasks)
|
|
459
|
+
)
|
|
460
|
+
await session.execute(update_stmt)
|
|
461
|
+
await session.commit()
|
|
462
|
+
|
|
463
|
+
logger.info(f"Updated autonomous task {task_id} for agent {agent_id}")
|
|
464
|
+
return updated_task
|
intentkit/core/engine.py
CHANGED
|
@@ -221,6 +221,45 @@ async def create_agent(
|
|
|
221
221
|
):
|
|
222
222
|
entrypoint_prompt = agent.telegram_entrypoint_prompt
|
|
223
223
|
logger.debug("telegram entrypoint prompt added")
|
|
224
|
+
elif entrypoint == AuthorType.TRIGGER.value:
|
|
225
|
+
task_id = (
|
|
226
|
+
config["configurable"]
|
|
227
|
+
.get("chat_id", "")
|
|
228
|
+
.removeprefix("autonomous-")
|
|
229
|
+
)
|
|
230
|
+
# Find the autonomous task by task_id
|
|
231
|
+
autonomous_task = None
|
|
232
|
+
if agent.autonomous:
|
|
233
|
+
for task in agent.autonomous:
|
|
234
|
+
if task.id == task_id:
|
|
235
|
+
autonomous_task = task
|
|
236
|
+
break
|
|
237
|
+
|
|
238
|
+
if autonomous_task:
|
|
239
|
+
# Build detailed task info - always include task_id
|
|
240
|
+
if autonomous_task.name:
|
|
241
|
+
task_info = f"You are running an autonomous task '{autonomous_task.name}' (ID: {task_id})"
|
|
242
|
+
else:
|
|
243
|
+
task_info = (
|
|
244
|
+
f"You are running an autonomous task (ID: {task_id})"
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
# Add description if available
|
|
248
|
+
if autonomous_task.description:
|
|
249
|
+
task_info += f": {autonomous_task.description}"
|
|
250
|
+
|
|
251
|
+
# Add cycle info
|
|
252
|
+
if autonomous_task.minutes:
|
|
253
|
+
task_info += f". This task runs every {autonomous_task.minutes} minute(s)"
|
|
254
|
+
elif autonomous_task.cron:
|
|
255
|
+
task_info += (
|
|
256
|
+
f". This task runs on schedule: {autonomous_task.cron}"
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
entrypoint_prompt = f"{task_info}. "
|
|
260
|
+
else:
|
|
261
|
+
# Fallback if task not found
|
|
262
|
+
entrypoint_prompt = f"You are running an autonomous task. The task id is {task_id}. "
|
|
224
263
|
if entrypoint_prompt:
|
|
225
264
|
entrypoint_prompt = await explain_prompt(entrypoint_prompt)
|
|
226
265
|
final_system_prompt = f"{final_system_prompt}## Entrypoint rules\n\n{entrypoint_prompt}\n\n"
|
|
@@ -1012,15 +1051,3 @@ async def thread_stats(agent_id: str, chat_id: str) -> list[BaseMessage]:
|
|
|
1012
1051
|
return snap.values["messages"]
|
|
1013
1052
|
else:
|
|
1014
1053
|
return []
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
async def is_payment_required(input: ChatMessageCreate, agent: Agent) -> bool:
|
|
1018
|
-
if not config.payment_enabled:
|
|
1019
|
-
return False
|
|
1020
|
-
payment_settings = await AppSetting.payment()
|
|
1021
|
-
if payment_settings.agent_whitelist_enabled:
|
|
1022
|
-
if agent.id not in payment_settings.agent_whitelist:
|
|
1023
|
-
return False
|
|
1024
|
-
if input.user_id and agent.owner:
|
|
1025
|
-
return True
|
|
1026
|
-
return False
|
intentkit/core/skill.py
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
from typing import Any, Dict, Optional
|
|
1
|
+
from typing import Any, Dict, List, Optional
|
|
2
2
|
|
|
3
3
|
from intentkit.abstracts.skill import SkillStoreABC
|
|
4
4
|
from intentkit.config.config import config
|
|
5
|
-
from intentkit.
|
|
5
|
+
from intentkit.core.agent import (
|
|
6
|
+
add_autonomous_task as _add_autonomous_task,
|
|
7
|
+
)
|
|
8
|
+
from intentkit.core.agent import (
|
|
9
|
+
delete_autonomous_task as _delete_autonomous_task,
|
|
10
|
+
)
|
|
11
|
+
from intentkit.core.agent import (
|
|
12
|
+
list_autonomous_tasks as _list_autonomous_tasks,
|
|
13
|
+
)
|
|
14
|
+
from intentkit.core.agent import (
|
|
15
|
+
update_autonomous_task as _update_autonomous_task,
|
|
16
|
+
)
|
|
17
|
+
from intentkit.models.agent import Agent, AgentAutonomous
|
|
6
18
|
from intentkit.models.agent_data import AgentData, AgentQuota
|
|
7
19
|
from intentkit.models.skill import (
|
|
8
20
|
AgentSkillData,
|
|
@@ -131,5 +143,58 @@ class SkillStore(SkillStoreABC):
|
|
|
131
143
|
)
|
|
132
144
|
await skill_data.save()
|
|
133
145
|
|
|
146
|
+
@staticmethod
|
|
147
|
+
async def list_autonomous_tasks(agent_id: str) -> List[AgentAutonomous]:
|
|
148
|
+
"""List all autonomous tasks for an agent.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
agent_id: ID of the agent
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
List[AgentAutonomous]: List of autonomous task configurations
|
|
155
|
+
"""
|
|
156
|
+
return await _list_autonomous_tasks(agent_id)
|
|
157
|
+
|
|
158
|
+
@staticmethod
|
|
159
|
+
async def add_autonomous_task(
|
|
160
|
+
agent_id: str, task: AgentAutonomous
|
|
161
|
+
) -> AgentAutonomous:
|
|
162
|
+
"""Add a new autonomous task to an agent.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
agent_id: ID of the agent
|
|
166
|
+
task: Autonomous task configuration
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
AgentAutonomous: The created task
|
|
170
|
+
"""
|
|
171
|
+
return await _add_autonomous_task(agent_id, task)
|
|
172
|
+
|
|
173
|
+
@staticmethod
|
|
174
|
+
async def delete_autonomous_task(agent_id: str, task_id: str) -> None:
|
|
175
|
+
"""Delete an autonomous task from an agent.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
agent_id: ID of the agent
|
|
179
|
+
task_id: ID of the task to delete
|
|
180
|
+
"""
|
|
181
|
+
await _delete_autonomous_task(agent_id, task_id)
|
|
182
|
+
|
|
183
|
+
@staticmethod
|
|
184
|
+
async def update_autonomous_task(
|
|
185
|
+
agent_id: str, task_id: str, task_updates: dict
|
|
186
|
+
) -> AgentAutonomous:
|
|
187
|
+
"""Update an autonomous task for an agent.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
agent_id: ID of the agent
|
|
191
|
+
task_id: ID of the task to update
|
|
192
|
+
task_updates: Dictionary containing fields to update
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
AgentAutonomous: The updated task
|
|
196
|
+
"""
|
|
197
|
+
return await _update_autonomous_task(agent_id, task_id, task_updates)
|
|
198
|
+
|
|
134
199
|
|
|
135
200
|
skill_store = SkillStore()
|
intentkit/models/agent.py
CHANGED
|
@@ -1487,6 +1487,12 @@ class AgentResponse(BaseModel):
|
|
|
1487
1487
|
cdp_wallet_address: Annotated[
|
|
1488
1488
|
Optional[str], PydanticField(description="CDP wallet address for the agent")
|
|
1489
1489
|
]
|
|
1490
|
+
evm_wallet_address: Annotated[
|
|
1491
|
+
Optional[str], PydanticField(description="EVM wallet address for the agent")
|
|
1492
|
+
]
|
|
1493
|
+
solana_wallet_address: Annotated[
|
|
1494
|
+
Optional[str], PydanticField(description="Solana wallet address for the agent")
|
|
1495
|
+
]
|
|
1490
1496
|
has_twitter_linked: Annotated[
|
|
1491
1497
|
bool,
|
|
1492
1498
|
PydanticField(description="Whether the agent has linked their Twitter account"),
|
|
@@ -1602,6 +1608,8 @@ class AgentResponse(BaseModel):
|
|
|
1602
1608
|
|
|
1603
1609
|
# Process CDP wallet address
|
|
1604
1610
|
cdp_wallet_address = agent_data.evm_wallet_address if agent_data else None
|
|
1611
|
+
evm_wallet_address = agent_data.evm_wallet_address if agent_data else None
|
|
1612
|
+
solana_wallet_address = agent_data.solana_wallet_address if agent_data else None
|
|
1605
1613
|
|
|
1606
1614
|
# Process Twitter linked status
|
|
1607
1615
|
has_twitter_linked = False
|
|
@@ -1647,6 +1655,8 @@ class AgentResponse(BaseModel):
|
|
|
1647
1655
|
data.update(
|
|
1648
1656
|
{
|
|
1649
1657
|
"cdp_wallet_address": cdp_wallet_address,
|
|
1658
|
+
"evm_wallet_address": evm_wallet_address,
|
|
1659
|
+
"solana_wallet_address": solana_wallet_address,
|
|
1650
1660
|
"has_twitter_linked": has_twitter_linked,
|
|
1651
1661
|
"linked_twitter_username": linked_twitter_username,
|
|
1652
1662
|
"linked_twitter_name": linked_twitter_name,
|
intentkit/models/agent_data.py
CHANGED
|
@@ -814,3 +814,33 @@ class AgentQuota(BaseModel):
|
|
|
814
814
|
# Update this instance
|
|
815
815
|
await db.refresh(quota_record)
|
|
816
816
|
self.model_validate(quota_record)
|
|
817
|
+
|
|
818
|
+
@staticmethod
|
|
819
|
+
async def reset_daily_quotas():
|
|
820
|
+
"""Reset daily quotas for all agents at UTC 00:00.
|
|
821
|
+
Resets message_count_daily and twitter_count_daily to 0.
|
|
822
|
+
"""
|
|
823
|
+
from sqlalchemy import update
|
|
824
|
+
|
|
825
|
+
async with get_session() as session:
|
|
826
|
+
stmt = update(AgentQuotaTable).values(
|
|
827
|
+
message_count_daily=0,
|
|
828
|
+
twitter_count_daily=0,
|
|
829
|
+
free_income_daily=0,
|
|
830
|
+
)
|
|
831
|
+
await session.execute(stmt)
|
|
832
|
+
await session.commit()
|
|
833
|
+
|
|
834
|
+
@staticmethod
|
|
835
|
+
async def reset_monthly_quotas():
|
|
836
|
+
"""Reset monthly quotas for all agents at the start of each month.
|
|
837
|
+
Resets message_count_monthly and autonomous_count_monthly to 0.
|
|
838
|
+
"""
|
|
839
|
+
from sqlalchemy import update
|
|
840
|
+
|
|
841
|
+
async with get_session() as session:
|
|
842
|
+
stmt = update(AgentQuotaTable).values(
|
|
843
|
+
message_count_monthly=0, autonomous_count_monthly=0
|
|
844
|
+
)
|
|
845
|
+
await session.execute(stmt)
|
|
846
|
+
await session.commit()
|
intentkit/models/app_setting.py
CHANGED
|
@@ -46,6 +46,8 @@ class PaymentSettings(BaseModel):
|
|
|
46
46
|
"credit_per_usdc": 1000,
|
|
47
47
|
"fee_platform_percentage": 100,
|
|
48
48
|
"fee_dev_percentage": 20,
|
|
49
|
+
"free_quota": 480,
|
|
50
|
+
"refill_amount": 20,
|
|
49
51
|
"agent_whitelist_enabled": False,
|
|
50
52
|
"agent_whitelist": [],
|
|
51
53
|
}
|
|
@@ -68,6 +70,22 @@ class PaymentSettings(BaseModel):
|
|
|
68
70
|
default=Decimal("20"), description="Developer fee percentage", ge=0, le=100
|
|
69
71
|
),
|
|
70
72
|
]
|
|
73
|
+
free_quota: Annotated[
|
|
74
|
+
Decimal,
|
|
75
|
+
Field(
|
|
76
|
+
default=Decimal("480"),
|
|
77
|
+
description="Daily free credit quota for new users",
|
|
78
|
+
ge=0,
|
|
79
|
+
),
|
|
80
|
+
]
|
|
81
|
+
refill_amount: Annotated[
|
|
82
|
+
Decimal,
|
|
83
|
+
Field(
|
|
84
|
+
default=Decimal("20"),
|
|
85
|
+
description="Hourly refill amount for free credits",
|
|
86
|
+
ge=0,
|
|
87
|
+
),
|
|
88
|
+
]
|
|
71
89
|
agent_whitelist_enabled: Annotated[
|
|
72
90
|
bool,
|
|
73
91
|
Field(default=False, description="Whether agent whitelist is enabled"),
|
|
@@ -77,7 +95,13 @@ class PaymentSettings(BaseModel):
|
|
|
77
95
|
Field(default_factory=list, description="List of whitelisted agent IDs"),
|
|
78
96
|
]
|
|
79
97
|
|
|
80
|
-
@field_validator(
|
|
98
|
+
@field_validator(
|
|
99
|
+
"credit_per_usdc",
|
|
100
|
+
"fee_platform_percentage",
|
|
101
|
+
"fee_dev_percentage",
|
|
102
|
+
"free_quota",
|
|
103
|
+
"refill_amount",
|
|
104
|
+
)
|
|
81
105
|
@classmethod
|
|
82
106
|
def round_decimal(cls, v: Any) -> Decimal:
|
|
83
107
|
"""Round decimal values to 4 decimal places."""
|
intentkit/models/credit.py
CHANGED
|
@@ -6,6 +6,7 @@ from typing import Annotated, Any, Dict, List, Optional, Tuple
|
|
|
6
6
|
|
|
7
7
|
from epyxid import XID
|
|
8
8
|
from fastapi import HTTPException
|
|
9
|
+
from intentkit.models.app_setting import AppSetting
|
|
9
10
|
from intentkit.models.base import Base
|
|
10
11
|
from intentkit.models.db import get_session
|
|
11
12
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
@@ -437,8 +438,8 @@ class CreditAccount(BaseModel):
|
|
|
437
438
|
session: AsyncSession,
|
|
438
439
|
owner_type: OwnerType,
|
|
439
440
|
owner_id: str,
|
|
440
|
-
free_quota: Decimal =
|
|
441
|
-
refill_amount: Decimal =
|
|
441
|
+
free_quota: Optional[Decimal] = None,
|
|
442
|
+
refill_amount: Optional[Decimal] = None,
|
|
442
443
|
) -> "CreditAccount":
|
|
443
444
|
"""Get an existing credit account or create a new one if it doesn't exist.
|
|
444
445
|
|
|
@@ -448,15 +449,24 @@ class CreditAccount(BaseModel):
|
|
|
448
449
|
session: Async session to use for database queries
|
|
449
450
|
owner_type: Type of the owner
|
|
450
451
|
owner_id: ID of the owner
|
|
451
|
-
free_quota: Daily quota for a new account if created
|
|
452
|
+
free_quota: Daily quota for a new account if created (if None, reads from payment settings)
|
|
453
|
+
refill_amount: Hourly refill amount (if None, reads from payment settings)
|
|
452
454
|
|
|
453
455
|
Returns:
|
|
454
456
|
CreditAccount: The existing or newly created credit account
|
|
455
457
|
"""
|
|
458
|
+
# Get payment settings if values not provided
|
|
459
|
+
if free_quota is None or refill_amount is None:
|
|
460
|
+
payment_settings = await AppSetting.payment()
|
|
461
|
+
if free_quota is None:
|
|
462
|
+
free_quota = payment_settings.free_quota
|
|
463
|
+
if refill_amount is None:
|
|
464
|
+
refill_amount = payment_settings.refill_amount
|
|
465
|
+
|
|
456
466
|
if owner_type != OwnerType.USER:
|
|
457
467
|
# only users have daily quota
|
|
458
|
-
free_quota = 0.0
|
|
459
|
-
refill_amount = 0.0
|
|
468
|
+
free_quota = Decimal("0.0")
|
|
469
|
+
refill_amount = Decimal("0.0")
|
|
460
470
|
# Create event_id at the beginning for consistency
|
|
461
471
|
event_id = str(XID())
|
|
462
472
|
|
|
@@ -5,7 +5,11 @@ from typing import TypedDict
|
|
|
5
5
|
|
|
6
6
|
from intentkit.abstracts.skill import SkillStoreABC
|
|
7
7
|
from intentkit.skills.base import SkillConfig, SkillOwnerState
|
|
8
|
+
from intentkit.skills.system.add_autonomous_task import AddAutonomousTask
|
|
8
9
|
from intentkit.skills.system.base import SystemBaseTool
|
|
10
|
+
from intentkit.skills.system.delete_autonomous_task import DeleteAutonomousTask
|
|
11
|
+
from intentkit.skills.system.edit_autonomous_task import EditAutonomousTask
|
|
12
|
+
from intentkit.skills.system.list_autonomous_tasks import ListAutonomousTasks
|
|
9
13
|
from intentkit.skills.system.read_agent_api_key import ReadAgentApiKey
|
|
10
14
|
from intentkit.skills.system.regenerate_agent_api_key import RegenerateAgentApiKey
|
|
11
15
|
|
|
@@ -18,6 +22,10 @@ logger = logging.getLogger(__name__)
|
|
|
18
22
|
class SkillStates(TypedDict):
|
|
19
23
|
read_agent_api_key: SkillOwnerState
|
|
20
24
|
regenerate_agent_api_key: SkillOwnerState
|
|
25
|
+
list_autonomous_tasks: SkillOwnerState
|
|
26
|
+
add_autonomous_task: SkillOwnerState
|
|
27
|
+
delete_autonomous_task: SkillOwnerState
|
|
28
|
+
edit_autonomous_task: SkillOwnerState
|
|
21
29
|
|
|
22
30
|
|
|
23
31
|
class Config(SkillConfig):
|
|
@@ -85,6 +93,30 @@ def get_system_skill(
|
|
|
85
93
|
skill_store=store,
|
|
86
94
|
)
|
|
87
95
|
return _cache[name]
|
|
96
|
+
elif name == "list_autonomous_tasks":
|
|
97
|
+
if name not in _cache:
|
|
98
|
+
_cache[name] = ListAutonomousTasks(
|
|
99
|
+
skill_store=store,
|
|
100
|
+
)
|
|
101
|
+
return _cache[name]
|
|
102
|
+
elif name == "add_autonomous_task":
|
|
103
|
+
if name not in _cache:
|
|
104
|
+
_cache[name] = AddAutonomousTask(
|
|
105
|
+
skill_store=store,
|
|
106
|
+
)
|
|
107
|
+
return _cache[name]
|
|
108
|
+
elif name == "delete_autonomous_task":
|
|
109
|
+
if name not in _cache:
|
|
110
|
+
_cache[name] = DeleteAutonomousTask(
|
|
111
|
+
skill_store=store,
|
|
112
|
+
)
|
|
113
|
+
return _cache[name]
|
|
114
|
+
elif name == "edit_autonomous_task":
|
|
115
|
+
if name not in _cache:
|
|
116
|
+
_cache[name] = EditAutonomousTask(
|
|
117
|
+
skill_store=store,
|
|
118
|
+
)
|
|
119
|
+
return _cache[name]
|
|
88
120
|
else:
|
|
89
121
|
logger.warning(f"Unknown system skill: {name}")
|
|
90
122
|
return None
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from langchain_core.runnables import RunnableConfig
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
from intentkit.models.agent import AgentAutonomous
|
|
7
|
+
from intentkit.skills.system.base import SystemBaseTool
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AddAutonomousTaskInput(BaseModel):
|
|
11
|
+
"""Input model for add_autonomous_task skill."""
|
|
12
|
+
|
|
13
|
+
name: Optional[str] = Field(
|
|
14
|
+
default=None,
|
|
15
|
+
description="Display name of the autonomous task configuration",
|
|
16
|
+
max_length=50,
|
|
17
|
+
)
|
|
18
|
+
description: Optional[str] = Field(
|
|
19
|
+
default=None,
|
|
20
|
+
description="Description of the autonomous task configuration",
|
|
21
|
+
max_length=200,
|
|
22
|
+
)
|
|
23
|
+
minutes: Optional[int] = Field(
|
|
24
|
+
default=None,
|
|
25
|
+
description="Interval in minutes between operations, mutually exclusive with cron",
|
|
26
|
+
)
|
|
27
|
+
cron: Optional[str] = Field(
|
|
28
|
+
default=None,
|
|
29
|
+
description="Cron expression for scheduling operations, mutually exclusive with minutes",
|
|
30
|
+
)
|
|
31
|
+
prompt: str = Field(description="Special prompt used during autonomous operation")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class AddAutonomousTaskOutput(BaseModel):
|
|
35
|
+
"""Output model for add_autonomous_task skill."""
|
|
36
|
+
|
|
37
|
+
task: AgentAutonomous = Field(
|
|
38
|
+
description="The created autonomous task configuration"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class AddAutonomousTask(SystemBaseTool):
|
|
43
|
+
"""Skill to add a new autonomous task to an agent."""
|
|
44
|
+
|
|
45
|
+
name: str = "system_add_autonomous_task"
|
|
46
|
+
description: str = (
|
|
47
|
+
"Add a new autonomous task configuration to the agent. "
|
|
48
|
+
"Allows setting up scheduled operations with custom prompts and intervals. "
|
|
49
|
+
"The minutes and cron fields are mutually exclusive. But you must provide one of them. "
|
|
50
|
+
"If user want to add a condition task, you can add a 5 minutes task to check the condition. "
|
|
51
|
+
"If the user does not explicitly state that the condition task should be executed continuously, "
|
|
52
|
+
"then add in the task prompt that it will delete itself after successful execution. "
|
|
53
|
+
)
|
|
54
|
+
args_schema = AddAutonomousTaskInput
|
|
55
|
+
|
|
56
|
+
async def _arun(
|
|
57
|
+
self,
|
|
58
|
+
name: Optional[str] = None,
|
|
59
|
+
description: Optional[str] = None,
|
|
60
|
+
minutes: Optional[int] = None,
|
|
61
|
+
cron: Optional[str] = None,
|
|
62
|
+
prompt: str = "",
|
|
63
|
+
config: RunnableConfig = None,
|
|
64
|
+
**kwargs,
|
|
65
|
+
) -> AddAutonomousTaskOutput:
|
|
66
|
+
"""Add an autonomous task to the agent.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
name: Display name of the task
|
|
70
|
+
description: Description of the task
|
|
71
|
+
minutes: Interval in minutes (mutually exclusive with cron)
|
|
72
|
+
cron: Cron expression (mutually exclusive with minutes)
|
|
73
|
+
prompt: Special prompt for autonomous operation
|
|
74
|
+
config: Runtime configuration containing agent context
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
AddAutonomousTaskOutput: The created task
|
|
78
|
+
"""
|
|
79
|
+
context = self.context_from_config(config)
|
|
80
|
+
agent_id = context.agent_id
|
|
81
|
+
|
|
82
|
+
task = AgentAutonomous(
|
|
83
|
+
name=name,
|
|
84
|
+
description=description,
|
|
85
|
+
minutes=minutes,
|
|
86
|
+
cron=cron,
|
|
87
|
+
prompt=prompt,
|
|
88
|
+
enabled=True,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
created_task = await self.skill_store.add_autonomous_task(agent_id, task)
|
|
92
|
+
|
|
93
|
+
return AddAutonomousTaskOutput(task=created_task)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from langchain_core.runnables import RunnableConfig
|
|
2
|
+
from pydantic import BaseModel, Field
|
|
3
|
+
|
|
4
|
+
from intentkit.skills.system.base import SystemBaseTool
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DeleteAutonomousTaskInput(BaseModel):
|
|
8
|
+
"""Input model for delete_autonomous_task skill."""
|
|
9
|
+
|
|
10
|
+
task_id: str = Field(
|
|
11
|
+
description="The unique identifier of the autonomous task to delete"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DeleteAutonomousTaskOutput(BaseModel):
|
|
16
|
+
"""Output model for delete_autonomous_task skill."""
|
|
17
|
+
|
|
18
|
+
success: bool = Field(
|
|
19
|
+
description="Whether the task was successfully deleted", default=True
|
|
20
|
+
)
|
|
21
|
+
message: str = Field(description="Confirmation message about the deletion")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DeleteAutonomousTask(SystemBaseTool):
|
|
25
|
+
"""Skill to delete an autonomous task from an agent."""
|
|
26
|
+
|
|
27
|
+
name: str = "system_delete_autonomous_task"
|
|
28
|
+
description: str = (
|
|
29
|
+
"Delete an autonomous task configuration from the agent. "
|
|
30
|
+
"Requires the task ID to identify which task to remove."
|
|
31
|
+
)
|
|
32
|
+
args_schema = DeleteAutonomousTaskInput
|
|
33
|
+
|
|
34
|
+
async def _arun(
|
|
35
|
+
self,
|
|
36
|
+
task_id: str,
|
|
37
|
+
config: RunnableConfig,
|
|
38
|
+
**kwargs,
|
|
39
|
+
) -> DeleteAutonomousTaskOutput:
|
|
40
|
+
"""Delete an autonomous task from the agent.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
task_id: The ID of the task to delete
|
|
44
|
+
config: Runtime configuration containing agent context
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
DeleteAutonomousTaskOutput: Confirmation of deletion
|
|
48
|
+
"""
|
|
49
|
+
context = self.context_from_config(config)
|
|
50
|
+
agent_id = context.agent_id
|
|
51
|
+
|
|
52
|
+
await self.skill_store.delete_autonomous_task(agent_id, task_id)
|
|
53
|
+
|
|
54
|
+
return DeleteAutonomousTaskOutput(
|
|
55
|
+
success=True, message=f"Successfully deleted autonomous task {task_id}"
|
|
56
|
+
)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from langchain_core.runnables import RunnableConfig
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
from intentkit.models.agent import AgentAutonomous
|
|
7
|
+
from intentkit.skills.system.base import SystemBaseTool
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class EditAutonomousTaskInput(BaseModel):
|
|
11
|
+
"""Input model for edit_autonomous_task skill."""
|
|
12
|
+
|
|
13
|
+
task_id: str = Field(
|
|
14
|
+
description="The unique identifier of the autonomous task to edit"
|
|
15
|
+
)
|
|
16
|
+
name: Optional[str] = Field(
|
|
17
|
+
default=None,
|
|
18
|
+
description="Display name of the autonomous task configuration",
|
|
19
|
+
max_length=50,
|
|
20
|
+
)
|
|
21
|
+
description: Optional[str] = Field(
|
|
22
|
+
default=None,
|
|
23
|
+
description="Description of the autonomous task configuration",
|
|
24
|
+
max_length=200,
|
|
25
|
+
)
|
|
26
|
+
minutes: Optional[int] = Field(
|
|
27
|
+
default=None,
|
|
28
|
+
description="Interval in minutes between operations, mutually exclusive with cron",
|
|
29
|
+
)
|
|
30
|
+
cron: Optional[str] = Field(
|
|
31
|
+
default=None,
|
|
32
|
+
description="Cron expression for scheduling operations, mutually exclusive with minutes",
|
|
33
|
+
)
|
|
34
|
+
prompt: Optional[str] = Field(
|
|
35
|
+
default=None, description="Special prompt used during autonomous operation"
|
|
36
|
+
)
|
|
37
|
+
enabled: Optional[bool] = Field(
|
|
38
|
+
default=None, description="Whether the autonomous task is enabled"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class EditAutonomousTaskOutput(BaseModel):
|
|
43
|
+
"""Output model for edit_autonomous_task skill."""
|
|
44
|
+
|
|
45
|
+
task: AgentAutonomous = Field(
|
|
46
|
+
description="The updated autonomous task configuration"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class EditAutonomousTask(SystemBaseTool):
|
|
51
|
+
"""Skill to edit an existing autonomous task for an agent."""
|
|
52
|
+
|
|
53
|
+
name: str = "system_edit_autonomous_task"
|
|
54
|
+
description: str = (
|
|
55
|
+
"Edit an existing autonomous task configuration for the agent. "
|
|
56
|
+
"Allows updating the name, description, schedule (minutes or cron), prompt, and enabled status. "
|
|
57
|
+
"Only provided fields will be updated; omitted fields will keep their current values. "
|
|
58
|
+
"The minutes and cron fields are mutually exclusive. Do not provide both of them. "
|
|
59
|
+
)
|
|
60
|
+
args_schema = EditAutonomousTaskInput
|
|
61
|
+
|
|
62
|
+
async def _arun(
|
|
63
|
+
self,
|
|
64
|
+
task_id: str,
|
|
65
|
+
name: Optional[str] = None,
|
|
66
|
+
description: Optional[str] = None,
|
|
67
|
+
minutes: Optional[int] = None,
|
|
68
|
+
cron: Optional[str] = None,
|
|
69
|
+
prompt: Optional[str] = None,
|
|
70
|
+
enabled: Optional[bool] = None,
|
|
71
|
+
config: RunnableConfig = None,
|
|
72
|
+
**kwargs,
|
|
73
|
+
) -> EditAutonomousTaskOutput:
|
|
74
|
+
"""Edit an autonomous task for the agent.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
task_id: ID of the task to edit
|
|
78
|
+
name: Display name of the task
|
|
79
|
+
description: Description of the task
|
|
80
|
+
minutes: Interval in minutes (mutually exclusive with cron)
|
|
81
|
+
cron: Cron expression (mutually exclusive with minutes)
|
|
82
|
+
prompt: Special prompt for autonomous operation
|
|
83
|
+
enabled: Whether the task is enabled
|
|
84
|
+
config: Runtime configuration containing agent context
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
EditAutonomousTaskOutput: The updated task
|
|
88
|
+
"""
|
|
89
|
+
context = self.context_from_config(config)
|
|
90
|
+
agent_id = context.agent_id
|
|
91
|
+
|
|
92
|
+
if minutes is not None and cron is not None:
|
|
93
|
+
raise ValueError("minutes and cron are mutually exclusive")
|
|
94
|
+
|
|
95
|
+
# Build the updates dictionary with only provided fields
|
|
96
|
+
task_updates = {}
|
|
97
|
+
if name is not None:
|
|
98
|
+
task_updates["name"] = name
|
|
99
|
+
if description is not None:
|
|
100
|
+
task_updates["description"] = description
|
|
101
|
+
if minutes is not None:
|
|
102
|
+
task_updates["minutes"] = minutes
|
|
103
|
+
task_updates["cron"] = None
|
|
104
|
+
if cron is not None:
|
|
105
|
+
task_updates["cron"] = cron
|
|
106
|
+
task_updates["minutes"] = None
|
|
107
|
+
if prompt is not None:
|
|
108
|
+
task_updates["prompt"] = prompt
|
|
109
|
+
if enabled is not None:
|
|
110
|
+
task_updates["enabled"] = enabled
|
|
111
|
+
|
|
112
|
+
updated_task = await self.skill_store.update_autonomous_task(
|
|
113
|
+
agent_id, task_id, task_updates
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return EditAutonomousTaskOutput(task=updated_task)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from langchain_core.runnables import RunnableConfig
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
from intentkit.models.agent import AgentAutonomous
|
|
7
|
+
from intentkit.skills.system.base import SystemBaseTool
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ListAutonomousTasksInput(BaseModel):
|
|
11
|
+
"""Input model for list_autonomous_tasks skill."""
|
|
12
|
+
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ListAutonomousTasksOutput(BaseModel):
|
|
17
|
+
"""Output model for list_autonomous_tasks skill."""
|
|
18
|
+
|
|
19
|
+
tasks: List[AgentAutonomous] = Field(
|
|
20
|
+
description="List of autonomous task configurations for the agent"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ListAutonomousTasks(SystemBaseTool):
|
|
25
|
+
"""Skill to list all autonomous tasks for an agent."""
|
|
26
|
+
|
|
27
|
+
name: str = "system_list_autonomous_tasks"
|
|
28
|
+
description: str = (
|
|
29
|
+
"List all autonomous task configurations for the agent. "
|
|
30
|
+
"Returns details about each task including scheduling, prompts, and status."
|
|
31
|
+
)
|
|
32
|
+
args_schema = ListAutonomousTasksInput
|
|
33
|
+
|
|
34
|
+
async def _arun(
|
|
35
|
+
self,
|
|
36
|
+
config: RunnableConfig,
|
|
37
|
+
**kwargs,
|
|
38
|
+
) -> ListAutonomousTasksOutput:
|
|
39
|
+
"""List autonomous tasks for the agent.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
config: Runtime configuration containing agent context
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
ListAutonomousTasksOutput: List of autonomous tasks
|
|
46
|
+
"""
|
|
47
|
+
context = self.context_from_config(config)
|
|
48
|
+
agent_id = context.agent_id
|
|
49
|
+
|
|
50
|
+
tasks = await self.skill_store.list_autonomous_tasks(agent_id)
|
|
51
|
+
|
|
52
|
+
return ListAutonomousTasksOutput(tasks=tasks)
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"Agent Owner Only"
|
|
32
32
|
],
|
|
33
33
|
"description": "Retrieve the API key for the agent. If no API key exists, generates and sets a new one.",
|
|
34
|
-
"default": "
|
|
34
|
+
"default": "disabled"
|
|
35
35
|
},
|
|
36
36
|
"regenerate_agent_api_key": {
|
|
37
37
|
"type": "string",
|
|
@@ -45,7 +45,63 @@
|
|
|
45
45
|
"Agent Owner Only"
|
|
46
46
|
],
|
|
47
47
|
"description": "Generate a new API key for the agent, replacing any existing key.",
|
|
48
|
-
"default": "
|
|
48
|
+
"default": "disabled"
|
|
49
|
+
},
|
|
50
|
+
"list_autonomous_tasks": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"title": "List Autonomous Tasks",
|
|
53
|
+
"enum": [
|
|
54
|
+
"disabled",
|
|
55
|
+
"private"
|
|
56
|
+
],
|
|
57
|
+
"x-enum-title": [
|
|
58
|
+
"Disabled",
|
|
59
|
+
"Agent Owner Only"
|
|
60
|
+
],
|
|
61
|
+
"description": "List all autonomous task configurations for the agent.",
|
|
62
|
+
"default": "disabled"
|
|
63
|
+
},
|
|
64
|
+
"add_autonomous_task": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"title": "Add Autonomous Task",
|
|
67
|
+
"enum": [
|
|
68
|
+
"disabled",
|
|
69
|
+
"private"
|
|
70
|
+
],
|
|
71
|
+
"x-enum-title": [
|
|
72
|
+
"Disabled",
|
|
73
|
+
"Agent Owner Only"
|
|
74
|
+
],
|
|
75
|
+
"description": "Add a new autonomous task configuration to the agent.",
|
|
76
|
+
"default": "disabled"
|
|
77
|
+
},
|
|
78
|
+
"delete_autonomous_task": {
|
|
79
|
+
"type": "string",
|
|
80
|
+
"title": "Delete Autonomous Task",
|
|
81
|
+
"enum": [
|
|
82
|
+
"disabled",
|
|
83
|
+
"private"
|
|
84
|
+
],
|
|
85
|
+
"x-enum-title": [
|
|
86
|
+
"Disabled",
|
|
87
|
+
"Agent Owner Only"
|
|
88
|
+
],
|
|
89
|
+
"description": "Delete an autonomous task configuration from the agent.",
|
|
90
|
+
"default": "disabled"
|
|
91
|
+
},
|
|
92
|
+
"edit_autonomous_task": {
|
|
93
|
+
"type": "string",
|
|
94
|
+
"title": "Edit Autonomous Task",
|
|
95
|
+
"enum": [
|
|
96
|
+
"disabled",
|
|
97
|
+
"private"
|
|
98
|
+
],
|
|
99
|
+
"x-enum-title": [
|
|
100
|
+
"Disabled",
|
|
101
|
+
"Agent Owner Only"
|
|
102
|
+
],
|
|
103
|
+
"description": "Edit an existing autonomous task configuration for the agent.",
|
|
104
|
+
"default": "disabled"
|
|
49
105
|
}
|
|
50
106
|
}
|
|
51
107
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: intentkit
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.7
|
|
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
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
intentkit/__init__.py,sha256=
|
|
1
|
+
intentkit/__init__.py,sha256=fIrJ9bOWDF1C4eSgiZndEAAzdSloSyRr31q5aGL2ex4,378
|
|
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
|
|
5
5
|
intentkit/abstracts/engine.py,sha256=C5C9d8vVMePhkKWURKIAbZSDZnmjxj5epL_04E6RpxQ,1449
|
|
6
6
|
intentkit/abstracts/exception.py,sha256=NX7u_eFP0Cowu6fK4QW8LmDqd_Vybm3_6W5UiO6nMYA,239
|
|
7
7
|
intentkit/abstracts/graph.py,sha256=QhaVLtKyo9iTotIWhjgUi7BbmRCcb8yrHCTSq4Hsvnw,735
|
|
8
|
-
intentkit/abstracts/skill.py,sha256=
|
|
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
11
|
intentkit/clients/cdp.py,sha256=_CkvnBkzdq7-sFMGct4lz85FpaOoHxOGstWubhClzrA,5921
|
|
@@ -13,22 +13,22 @@ intentkit/clients/twitter.py,sha256=Lfa7srHOFnY96SXcElW0jfg7XKS_WliWnXjPZEe6SQc,
|
|
|
13
13
|
intentkit/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
intentkit/config/config.py,sha256=Gn3KXgFyh4u0zmb-Awpu4AxvDFaGDa_5GrFrKBbOAXk,7509
|
|
15
15
|
intentkit/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
-
intentkit/core/agent.py,sha256=
|
|
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
19
|
intentkit/core/credit.py,sha256=vLT47NlLrGyvSU1OP8dkVXV5_VHqRNSeAK5t1FqSSYs,61742
|
|
20
|
-
intentkit/core/engine.py,sha256=
|
|
20
|
+
intentkit/core/engine.py,sha256=1JJuTSVs3k57M0aKD87Yx4T86Mc2DeefhLDXcHV13fY,42554
|
|
21
21
|
intentkit/core/node.py,sha256=RqAdcR1Fcpgw4k7q9l1Sry8LgcuZWdNxSjOHDcoavCI,9108
|
|
22
22
|
intentkit/core/prompt.py,sha256=RfLhlUktkB2kCr3wfldqq6ZP2l8heZIMc8jVp31KIyQ,3631
|
|
23
|
-
intentkit/core/skill.py,sha256=
|
|
24
|
-
intentkit/models/agent.py,sha256=
|
|
25
|
-
intentkit/models/agent_data.py,sha256=
|
|
23
|
+
intentkit/core/skill.py,sha256=vPK37sDRT9kzkMBymPwqZ5uEdxTTRtb_DfREIeyz-Xw,5788
|
|
24
|
+
intentkit/models/agent.py,sha256=L1nB-9RMvmZ38LRjtHeIdGbmdGeS8Ji1j_s0NJsFtSQ,57216
|
|
25
|
+
intentkit/models/agent_data.py,sha256=mVsiK8TziYa1W1ujU1KwI9osIVIeSM7XJEogGRL1WVU,28263
|
|
26
26
|
intentkit/models/agent_schema.json,sha256=5RMn474uWeN8Mo7RwPQuvPa5twXcenNbUjXCWjzywrI,21659
|
|
27
|
-
intentkit/models/app_setting.py,sha256=
|
|
27
|
+
intentkit/models/app_setting.py,sha256=4fuW4J6NV826e53OAsW1bnn3Pgw8iUVKH9-AUMTSYQc,5550
|
|
28
28
|
intentkit/models/base.py,sha256=o-zRjVrak-f5Jokdvj8BjLm8gcC3yYiYMCTLegwT2lA,185
|
|
29
29
|
intentkit/models/chat.py,sha256=O-7qmFh9Qag-gY2xXR6tpLJ1i-D0wQzzZ1hXnrt0BA0,19052
|
|
30
30
|
intentkit/models/conversation.py,sha256=nrbDIw-3GK5BYi_xkI15FLdx4a6SNrFK8wfAGLCsrqk,9032
|
|
31
|
-
intentkit/models/credit.py,sha256=
|
|
31
|
+
intentkit/models/credit.py,sha256=bcasHyrCwforLGrH8ZWEvN6y6ml7NeAFrGl8cfqvqbI,42956
|
|
32
32
|
intentkit/models/db.py,sha256=Ked8-PsvKvqxgvytGpWlDxZNgEuyac-uGM0xWWshKmY,4210
|
|
33
33
|
intentkit/models/db_mig.py,sha256=vT6Tanm-BHC2T7dTztuB1UG494EFBAlHADKsNzR6xaQ,3577
|
|
34
34
|
intentkit/models/generator.py,sha256=lyZu9U9rZUGkqd_QT5SAhay9DY358JJY8EhDSpN8I1M,10298
|
|
@@ -291,11 +291,15 @@ intentkit/skills/supabase/schema.json,sha256=cqjo20flg6Xlv6b-2nrsJAbdCMBCJfmlfz8
|
|
|
291
291
|
intentkit/skills/supabase/supabase.svg,sha256=65_80QCtJiKKV4EAuny_xbOD5JlTONEiq9xqO00hDtM,1107
|
|
292
292
|
intentkit/skills/supabase/update_data.py,sha256=Hbwsoa52GZNTPIhWdR9vj9VlcPRUn_vCMOYDzmMoPsI,4023
|
|
293
293
|
intentkit/skills/supabase/upsert_data.py,sha256=JgKLFPcQkUwnQhqTZojT4Ae53hYULeGEkQ1gxZJEe-c,2538
|
|
294
|
-
intentkit/skills/system/__init__.py,sha256=
|
|
294
|
+
intentkit/skills/system/__init__.py,sha256=bqNYJCjLx9p23E21ELLP-T0B_NP0ltzT0TMqsBI-9Bg,3668
|
|
295
|
+
intentkit/skills/system/add_autonomous_task.py,sha256=dUNppykHlCNtlxWfK2DzwT1FyaH2VNp0UU9V2Ecq07o,3269
|
|
295
296
|
intentkit/skills/system/base.py,sha256=Sm4lSNgbxwGK5YimnBfwi3Hc8E1EwSMZIXsCJbIPiLM,700
|
|
297
|
+
intentkit/skills/system/delete_autonomous_task.py,sha256=1zChfY3SkWr1V2QFotyitkVLaBsYBtk68qkhyA_qh-A,1741
|
|
298
|
+
intentkit/skills/system/edit_autonomous_task.py,sha256=MahT7gDPH5ZpjAqEKfJ-xQx6KpmgG3RrkikJ9KAf-CI,4131
|
|
299
|
+
intentkit/skills/system/list_autonomous_tasks.py,sha256=QTPL4He3OuNfil_xLwMwL1uoe1lbww-XZxD1837usuo,1496
|
|
296
300
|
intentkit/skills/system/read_agent_api_key.py,sha256=x8DIQwDxZ1MONz4tyN3o6QUf2-2aEjZd4yVOY28-IaU,3410
|
|
297
301
|
intentkit/skills/system/regenerate_agent_api_key.py,sha256=AiFXOEIRxXJRWiDufKCi3_ViyAyK19P1XZOleM1eQUc,3070
|
|
298
|
-
intentkit/skills/system/schema.json,sha256=
|
|
302
|
+
intentkit/skills/system/schema.json,sha256=Yfd_pnSrJUQc__dwAoN9jl4WyzCKuauFjTV60U4MFaI,3099
|
|
299
303
|
intentkit/skills/system/system.svg,sha256=PVbC6r6rOhvht0lB1fcxDNTcbMUa7haHAkJ8rxp7gm0,3740
|
|
300
304
|
intentkit/skills/tavily/README.md,sha256=VagMkuHrS_ge2Sir9M9CoeqmWc_rysKhTO9-LGICQsA,2840
|
|
301
305
|
intentkit/skills/tavily/__init__.py,sha256=PDtH-O3fdAPCc3lGMbgcXKK1fDdkTO1CW-40825FtGU,2386
|
|
@@ -390,7 +394,7 @@ intentkit/utils/random.py,sha256=DymMxu9g0kuQLgJUqalvgksnIeLdS-v0aRk5nQU0mLI,452
|
|
|
390
394
|
intentkit/utils/s3.py,sha256=9trQNkKQ5VgxWsewVsV8Y0q_pXzGRvsCYP8xauyUYkg,8549
|
|
391
395
|
intentkit/utils/slack_alert.py,sha256=s7UpRgyzLW7Pbmt8cKzTJgMA9bm4EP-1rQ5KXayHu6E,2264
|
|
392
396
|
intentkit/utils/tx.py,sha256=2yLLGuhvfBEY5n_GJ8wmIWLCzn0FsYKv5kRNzw_sLUI,1454
|
|
393
|
-
intentkit-0.6.
|
|
394
|
-
intentkit-0.6.
|
|
395
|
-
intentkit-0.6.
|
|
396
|
-
intentkit-0.6.
|
|
397
|
+
intentkit-0.6.7.dist-info/METADATA,sha256=0c6E761qVmheLN9l7_CSmYBxELBCGVCO9Xw9JbJmDoI,6316
|
|
398
|
+
intentkit-0.6.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
399
|
+
intentkit-0.6.7.dist-info/licenses/LICENSE,sha256=Bln6DhK-LtcO4aXy-PBcdZv2f24MlJFm_qn222biJtE,1071
|
|
400
|
+
intentkit-0.6.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|