intentkit 0.8.12rc0__py3-none-any.whl → 0.8.13.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of intentkit might be problematic. Click here for more details.

Files changed (175) hide show
  1. intentkit/__init__.py +1 -1
  2. intentkit/abstracts/skill.py +2 -59
  3. intentkit/clients/twitter.py +35 -28
  4. intentkit/config/config.py +1 -0
  5. intentkit/core/agent.py +2 -279
  6. intentkit/core/asset.py +63 -16
  7. intentkit/core/engine.py +9 -5
  8. intentkit/core/scheduler.py +8 -8
  9. intentkit/models/agent.py +138 -94
  10. intentkit/models/agent_schema.json +6 -9
  11. intentkit/models/chat.py +1 -0
  12. intentkit/models/llm.csv +15 -12
  13. intentkit/skills/acolyt/__init__.py +2 -9
  14. intentkit/skills/acolyt/base.py +2 -5
  15. intentkit/skills/aixbt/__init__.py +2 -13
  16. intentkit/skills/aixbt/base.py +0 -4
  17. intentkit/skills/aixbt/projects.py +1 -2
  18. intentkit/skills/allora/__init__.py +2 -9
  19. intentkit/skills/allora/base.py +2 -5
  20. intentkit/skills/base.py +101 -27
  21. intentkit/skills/basename/__init__.py +1 -3
  22. intentkit/skills/carv/__init__.py +116 -121
  23. intentkit/skills/carv/base.py +184 -185
  24. intentkit/skills/casino/__init__.py +4 -15
  25. intentkit/skills/casino/base.py +0 -4
  26. intentkit/skills/casino/deck_draw.py +1 -2
  27. intentkit/skills/casino/deck_shuffle.py +1 -2
  28. intentkit/skills/casino/dice_roll.py +1 -2
  29. intentkit/skills/cdp/__init__.py +0 -5
  30. intentkit/skills/cdp/base.py +0 -4
  31. intentkit/skills/cdp/schema.json +1 -17
  32. intentkit/skills/chainlist/__init__.py +2 -7
  33. intentkit/skills/chainlist/base.py +0 -4
  34. intentkit/skills/common/__init__.py +2 -9
  35. intentkit/skills/common/base.py +0 -4
  36. intentkit/skills/cookiefun/__init__.py +6 -9
  37. intentkit/skills/cookiefun/base.py +0 -4
  38. intentkit/skills/cryptocompare/__init__.py +7 -24
  39. intentkit/skills/cryptocompare/base.py +0 -5
  40. intentkit/skills/cryptopanic/__init__.py +3 -6
  41. intentkit/skills/cryptopanic/base.py +53 -55
  42. intentkit/skills/cryptopanic/fetch_crypto_news.py +0 -2
  43. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +1 -3
  44. intentkit/skills/dapplooker/__init__.py +2 -9
  45. intentkit/skills/dapplooker/base.py +2 -5
  46. intentkit/skills/defillama/__init__.py +24 -74
  47. intentkit/skills/defillama/base.py +0 -4
  48. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +2 -2
  49. intentkit/skills/defillama/coins/fetch_block.py +2 -2
  50. intentkit/skills/defillama/coins/fetch_current_prices.py +2 -2
  51. intentkit/skills/defillama/coins/fetch_first_price.py +2 -2
  52. intentkit/skills/defillama/coins/fetch_historical_prices.py +2 -2
  53. intentkit/skills/defillama/coins/fetch_price_chart.py +2 -2
  54. intentkit/skills/defillama/coins/fetch_price_percentage.py +2 -2
  55. intentkit/skills/defillama/fees/fetch_fees_overview.py +2 -2
  56. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +2 -2
  57. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +2 -2
  58. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +2 -2
  59. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +2 -2
  60. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +2 -2
  61. intentkit/skills/defillama/tvl/fetch_chains.py +2 -2
  62. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +2 -2
  63. intentkit/skills/defillama/tvl/fetch_protocol.py +2 -2
  64. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +2 -2
  65. intentkit/skills/defillama/tvl/fetch_protocols.py +2 -2
  66. intentkit/skills/defillama/volumes/fetch_dex_overview.py +2 -2
  67. intentkit/skills/defillama/volumes/fetch_dex_summary.py +2 -2
  68. intentkit/skills/defillama/volumes/fetch_options_overview.py +2 -2
  69. intentkit/skills/defillama/yields/fetch_pool_chart.py +2 -2
  70. intentkit/skills/defillama/yields/fetch_pools.py +2 -2
  71. intentkit/skills/dexscreener/__init__.py +97 -102
  72. intentkit/skills/dexscreener/base.py +125 -130
  73. intentkit/skills/dexscreener/get_pair_info.py +2 -3
  74. intentkit/skills/dexscreener/get_token_pairs.py +2 -3
  75. intentkit/skills/dexscreener/get_tokens_info.py +2 -3
  76. intentkit/skills/dexscreener/search_token.py +2 -4
  77. intentkit/skills/dune_analytics/__init__.py +4 -6
  78. intentkit/skills/dune_analytics/base.py +50 -52
  79. intentkit/skills/dune_analytics/fetch_kol_buys.py +0 -2
  80. intentkit/skills/dune_analytics/fetch_nation_metrics.py +0 -2
  81. intentkit/skills/elfa/__init__.py +5 -18
  82. intentkit/skills/elfa/base.py +8 -10
  83. intentkit/skills/enso/__init__.py +9 -29
  84. intentkit/skills/enso/base.py +3 -6
  85. intentkit/skills/enso/route.py +1 -3
  86. intentkit/skills/erc20/__init__.py +1 -5
  87. intentkit/skills/erc721/__init__.py +1 -3
  88. intentkit/skills/firecrawl/__init__.py +5 -18
  89. intentkit/skills/firecrawl/base.py +2 -5
  90. intentkit/skills/firecrawl/crawl.py +10 -9
  91. intentkit/skills/firecrawl/query.py +3 -1
  92. intentkit/skills/firecrawl/scrape.py +8 -10
  93. intentkit/skills/firecrawl/utils.py +25 -26
  94. intentkit/skills/github/__init__.py +2 -7
  95. intentkit/skills/github/base.py +0 -4
  96. intentkit/skills/heurist/__init__.py +8 -27
  97. intentkit/skills/heurist/base.py +2 -5
  98. intentkit/skills/heurist/image_generation_animagine_xl.py +5 -5
  99. intentkit/skills/heurist/image_generation_arthemy_comics.py +5 -5
  100. intentkit/skills/heurist/image_generation_arthemy_real.py +5 -5
  101. intentkit/skills/heurist/image_generation_braindance.py +5 -5
  102. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +5 -5
  103. intentkit/skills/heurist/image_generation_flux_1_dev.py +5 -5
  104. intentkit/skills/heurist/image_generation_sdxl.py +5 -5
  105. intentkit/skills/http/__init__.py +4 -15
  106. intentkit/skills/http/base.py +0 -4
  107. intentkit/skills/lifi/__init__.py +1 -6
  108. intentkit/skills/lifi/base.py +0 -4
  109. intentkit/skills/lifi/token_execute.py +1 -4
  110. intentkit/skills/lifi/token_quote.py +1 -3
  111. intentkit/skills/moralis/__init__.py +3 -7
  112. intentkit/skills/moralis/base.py +2 -5
  113. intentkit/skills/morpho/__init__.py +1 -3
  114. intentkit/skills/nation/__init__.py +2 -7
  115. intentkit/skills/nation/base.py +4 -7
  116. intentkit/skills/openai/__init__.py +5 -18
  117. intentkit/skills/openai/base.py +8 -10
  118. intentkit/skills/openai/dalle_image_generation.py +2 -5
  119. intentkit/skills/openai/gpt_image_generation.py +2 -5
  120. intentkit/skills/openai/gpt_image_to_image.py +2 -5
  121. intentkit/skills/openai/image_to_text.py +2 -5
  122. intentkit/skills/portfolio/__init__.py +11 -35
  123. intentkit/skills/portfolio/base.py +2 -5
  124. intentkit/skills/pyth/__init__.py +1 -5
  125. intentkit/skills/slack/__init__.py +5 -17
  126. intentkit/skills/slack/base.py +0 -4
  127. intentkit/skills/supabase/__init__.py +7 -23
  128. intentkit/skills/supabase/base.py +0 -4
  129. intentkit/skills/superfluid/__init__.py +1 -3
  130. intentkit/skills/system/__init__.py +7 -24
  131. intentkit/skills/system/add_autonomous_task.py +2 -2
  132. intentkit/skills/system/delete_autonomous_task.py +2 -2
  133. intentkit/skills/system/edit_autonomous_task.py +2 -4
  134. intentkit/skills/system/list_autonomous_tasks.py +2 -2
  135. intentkit/skills/system/read_agent_api_key.py +6 -4
  136. intentkit/skills/system/regenerate_agent_api_key.py +6 -4
  137. intentkit/skills/tavily/__init__.py +3 -12
  138. intentkit/skills/tavily/base.py +2 -5
  139. intentkit/skills/tavily/tavily_extract.py +1 -2
  140. intentkit/skills/tavily/tavily_search.py +3 -3
  141. intentkit/skills/token/__init__.py +5 -10
  142. intentkit/skills/token/base.py +2 -6
  143. intentkit/skills/twitter/__init__.py +11 -35
  144. intentkit/skills/twitter/base.py +14 -16
  145. intentkit/skills/twitter/follow_user.py +0 -1
  146. intentkit/skills/twitter/get_mentions.py +0 -1
  147. intentkit/skills/twitter/get_timeline.py +0 -1
  148. intentkit/skills/twitter/get_user_by_username.py +0 -1
  149. intentkit/skills/twitter/get_user_tweets.py +0 -1
  150. intentkit/skills/twitter/like_tweet.py +0 -1
  151. intentkit/skills/twitter/post_tweet.py +2 -2
  152. intentkit/skills/twitter/reply_tweet.py +2 -2
  153. intentkit/skills/twitter/retweet.py +0 -1
  154. intentkit/skills/twitter/search_tweets.py +0 -1
  155. intentkit/skills/unrealspeech/__init__.py +2 -7
  156. intentkit/skills/unrealspeech/base.py +0 -4
  157. intentkit/skills/venice_audio/__init__.py +99 -106
  158. intentkit/skills/venice_audio/base.py +118 -121
  159. intentkit/skills/venice_audio/venice_audio.py +1 -5
  160. intentkit/skills/venice_image/__init__.py +147 -154
  161. intentkit/skills/venice_image/base.py +185 -192
  162. intentkit/skills/web_scraper/__init__.py +5 -18
  163. intentkit/skills/web_scraper/base.py +20 -4
  164. intentkit/skills/web_scraper/document_indexer.py +6 -4
  165. intentkit/skills/web_scraper/scrape_and_index.py +11 -8
  166. intentkit/skills/web_scraper/utils.py +31 -27
  167. intentkit/skills/web_scraper/website_indexer.py +7 -8
  168. intentkit/skills/weth/__init__.py +1 -5
  169. intentkit/skills/wow/__init__.py +1 -5
  170. intentkit/skills/xmtp/__init__.py +4 -15
  171. intentkit/utils/schema.py +100 -0
  172. {intentkit-0.8.12rc0.dist-info → intentkit-0.8.13.dev1.dist-info}/METADATA +1 -1
  173. {intentkit-0.8.12rc0.dist-info → intentkit-0.8.13.dev1.dist-info}/RECORD +175 -174
  174. {intentkit-0.8.12rc0.dist-info → intentkit-0.8.13.dev1.dist-info}/WHEEL +0 -0
  175. {intentkit-0.8.12rc0.dist-info → intentkit-0.8.13.dev1.dist-info}/licenses/LICENSE +0 -0
intentkit/core/engine.py CHANGED
@@ -21,7 +21,6 @@ from typing import Optional, Tuple
21
21
 
22
22
  import sqlalchemy
23
23
  from epyxid import XID
24
- from langchain.agents import create_agent as create_react_agent
25
24
  from langchain_core.language_models import BaseChatModel
26
25
  from langchain_core.messages import (
27
26
  BaseMessage,
@@ -30,13 +29,13 @@ from langchain_core.messages import (
30
29
  from langchain_core.tools import BaseTool
31
30
  from langgraph.errors import GraphRecursionError
32
31
  from langgraph.graph.state import CompiledStateGraph
32
+ from langgraph.prebuilt import create_react_agent
33
33
  from langgraph.runtime import Runtime
34
34
  from sqlalchemy import func, update
35
35
  from sqlalchemy.exc import SQLAlchemyError
36
36
 
37
37
  from intentkit.abstracts.graph import AgentContext, AgentError, AgentState
38
38
  from intentkit.config.config import config
39
- from intentkit.core.agent import agent_store
40
39
  from intentkit.core.chat import clear_thread_memory
41
40
  from intentkit.core.credit import expense_message, expense_skill
42
41
  from intentkit.core.node import PreModelNode, post_model_node
@@ -56,7 +55,7 @@ from intentkit.models.chat import (
56
55
  from intentkit.models.credit import CreditAccount, OwnerType
57
56
  from intentkit.models.db import get_langgraph_checkpointer, get_session
58
57
  from intentkit.models.llm import LLMModelInfo, LLMProvider, create_llm_model
59
- from intentkit.models.skill import AgentSkillData, ChatSkillData
58
+ from intentkit.models.skill import AgentSkillData, ChatSkillData, Skill
60
59
  from intentkit.models.user import User
61
60
  from intentkit.utils.error import IntentKitAPIError
62
61
 
@@ -115,13 +114,13 @@ async def build_agent(
115
114
  if hasattr(skill_module, "get_skills"):
116
115
  # all
117
116
  skill_tools = await skill_module.get_skills(
118
- v, False, agent_store, agent_id=agent.id, agent=agent
117
+ v, False, agent_id=agent.id, agent=agent
119
118
  )
120
119
  if skill_tools and len(skill_tools) > 0:
121
120
  tools.extend(skill_tools)
122
121
  # private
123
122
  skill_private_tools = await skill_module.get_skills(
124
- v, True, agent_store, agent_id=agent.id, agent=agent
123
+ v, True, agent_id=agent.id, agent=agent
125
124
  )
126
125
  if skill_private_tools and len(skill_private_tools) > 0:
127
126
  private_tools.extend(skill_private_tools)
@@ -333,6 +332,8 @@ async def stream_agent_raw(
333
332
  model = await LLMModelInfo.get(agent.model)
334
333
 
335
334
  payment_enabled = config.payment_enabled
335
+ if user_message.author_type == AuthorType.X402:
336
+ payment_enabled = False
336
337
 
337
338
  # check user balance
338
339
  if payment_enabled:
@@ -703,6 +704,9 @@ async def stream_agent_raw(
703
704
  for skill_call in skill_calls:
704
705
  if not skill_call["success"]:
705
706
  continue
707
+ skill = await Skill.get(skill_call["name"])
708
+ if not skill:
709
+ continue
706
710
  payment_event = await expense_skill(
707
711
  session,
708
712
  payer,
@@ -11,7 +11,6 @@ from apscheduler.triggers.cron import CronTrigger
11
11
  from intentkit.core.agent import (
12
12
  update_agent_action_cost,
13
13
  update_agents_account_snapshot,
14
- update_agents_assets,
15
14
  update_agents_statistics,
16
15
  )
17
16
  from intentkit.core.credit import refill_all_free_credits
@@ -63,13 +62,14 @@ def create_scheduler(
63
62
  )
64
63
 
65
64
  # Update agent assets daily at UTC midnight
66
- scheduler.add_job(
67
- update_agents_assets,
68
- trigger=CronTrigger(hour=0, minute=0, timezone="UTC"),
69
- id="update_agent_assets",
70
- name="Update agent assets",
71
- replace_existing=True,
72
- )
65
+ # This is too expensive to run daily, so it will only be triggered when detail page is visited
66
+ # scheduler.add_job(
67
+ # update_agents_assets,
68
+ # trigger=CronTrigger(hour=0, minute=0, timezone="UTC"),
69
+ # id="update_agent_assets",
70
+ # name="Update agent assets",
71
+ # replace_existing=True,
72
+ # )
73
73
 
74
74
  # Update agent action costs hourly at minute 40
75
75
  scheduler.add_job(
intentkit/models/agent.py CHANGED
@@ -436,21 +436,13 @@ class AgentCore(BaseModel):
436
436
  title="Name",
437
437
  description="Display name of the agent",
438
438
  max_length=50,
439
- json_schema_extra={
440
- "x-group": "basic",
441
- "x-placeholder": "Name your agent",
442
- },
443
439
  ),
444
440
  ]
445
441
  picture: Annotated[
446
442
  Optional[str],
447
443
  PydanticField(
448
444
  default=None,
449
- description="Picture of the agent",
450
- json_schema_extra={
451
- "x-group": "experimental",
452
- "x-placeholder": "Upload a picture of your agent",
453
- },
445
+ description="Avatar of the agent",
454
446
  ),
455
447
  ]
456
448
  purpose: Annotated[
@@ -459,14 +451,6 @@ class AgentCore(BaseModel):
459
451
  default=None,
460
452
  description="Purpose or role of the agent",
461
453
  max_length=20000,
462
- json_schema_extra={
463
- "x-group": "basic",
464
- "x-placeholder": "Enter agent purpose, it will be a part of the system prompt",
465
- "pattern": "^(([^#].*)|#[^# ].*|#{3,}[ ].*|$)(\n(([^#].*)|#[^# ].*|#{3,}[ ].*|$))*$",
466
- "errorMessage": {
467
- "pattern": "Level 1 and 2 headings (# and ##) are not allowed. Please use level 3+ headings (###, ####, etc.) instead."
468
- },
469
- },
470
454
  ),
471
455
  ]
472
456
  personality: Annotated[
@@ -475,14 +459,6 @@ class AgentCore(BaseModel):
475
459
  default=None,
476
460
  description="Personality traits of the agent",
477
461
  max_length=20000,
478
- json_schema_extra={
479
- "x-group": "basic",
480
- "x-placeholder": "Enter agent personality, it will be a part of the system prompt",
481
- "pattern": "^(([^#].*)|#[^# ].*|#{3,}[ ].*|$)(\n(([^#].*)|#[^# ].*|#{3,}[ ].*|$))*$",
482
- "errorMessage": {
483
- "pattern": "Level 1 and 2 headings (# and ##) are not allowed. Please use level 3+ headings (###, ####, etc.) instead."
484
- },
485
- },
486
462
  ),
487
463
  ]
488
464
  principles: Annotated[
@@ -491,14 +467,6 @@ class AgentCore(BaseModel):
491
467
  default=None,
492
468
  description="Principles or values of the agent",
493
469
  max_length=20000,
494
- json_schema_extra={
495
- "x-group": "basic",
496
- "x-placeholder": "Enter agent principles, it will be a part of the system prompt",
497
- "pattern": "^(([^#].*)|#[^# ].*|#{3,}[ ].*|$)(\n(([^#].*)|#[^# ].*|#{3,}[ ].*|$))*$",
498
- "errorMessage": {
499
- "pattern": "Level 1 and 2 headings (# and ##) are not allowed. Please use level 3+ headings (###, ####, etc.) instead."
500
- },
501
- },
502
470
  ),
503
471
  ]
504
472
  # AI part
@@ -506,10 +474,7 @@ class AgentCore(BaseModel):
506
474
  str,
507
475
  PydanticField(
508
476
  default="gpt-5-mini",
509
- description="AI model identifier to be used by this agent for processing requests.",
510
- json_schema_extra={
511
- "x-group": "ai",
512
- },
477
+ description="LLM of the agent",
513
478
  ),
514
479
  ]
515
480
  prompt: Annotated[
@@ -518,13 +483,6 @@ class AgentCore(BaseModel):
518
483
  default=None,
519
484
  description="Base system prompt that defines the agent's behavior and capabilities",
520
485
  max_length=20000,
521
- json_schema_extra={
522
- "x-group": "ai",
523
- "pattern": "^(([^#].*)|#[^# ].*|#{3,}[ ].*|$)(\n(([^#].*)|#[^# ].*|#{3,}[ ].*|$))*$",
524
- "errorMessage": {
525
- "pattern": "Level 1 and 2 headings (# and ##) are not allowed. Please use level 3+ headings (###, ####, etc.) instead."
526
- },
527
- },
528
486
  ),
529
487
  ]
530
488
  prompt_append: Annotated[
@@ -533,13 +491,6 @@ class AgentCore(BaseModel):
533
491
  default=None,
534
492
  description="Additional system prompt that has higher priority than the base prompt",
535
493
  max_length=20000,
536
- json_schema_extra={
537
- "x-group": "ai",
538
- "pattern": "^(([^#].*)|#[^# ].*|#{3,}[ ].*|$)(\n(([^#].*)|#[^# ].*|#{3,}[ ].*|$))*$",
539
- "errorMessage": {
540
- "pattern": "Level 1 and 2 headings (# and ##) are not allowed. Please use level 3+ headings (###, ####, etc.) instead."
541
- },
542
- },
543
494
  ),
544
495
  ]
545
496
  temperature: Annotated[
@@ -549,9 +500,6 @@ class AgentCore(BaseModel):
549
500
  description="The randomness of the generated results is such that the higher the number, the more creative the results will be. However, this also makes them wilder and increases the likelihood of errors. For creative tasks, you can adjust it to above 1, but for rigorous tasks, such as quantitative trading, it's advisable to set it lower, around 0.2. (0.0~2.0)",
550
501
  ge=0.0,
551
502
  le=2.0,
552
- json_schema_extra={
553
- "x-group": "ai",
554
- },
555
503
  ),
556
504
  ]
557
505
  frequency_penalty: Annotated[
@@ -561,9 +509,6 @@ class AgentCore(BaseModel):
561
509
  description="The frequency penalty is a measure of how much the AI is allowed to repeat itself. A lower value means the AI is more likely to repeat previous responses, while a higher value means the AI is more likely to generate new content. For creative tasks, you can adjust it to 1 or a bit higher. (-2.0~2.0)",
562
510
  ge=-2.0,
563
511
  le=2.0,
564
- json_schema_extra={
565
- "x-group": "ai",
566
- },
567
512
  ),
568
513
  ]
569
514
  presence_penalty: Annotated[
@@ -573,9 +518,6 @@ class AgentCore(BaseModel):
573
518
  description="The presence penalty is a measure of how much the AI is allowed to deviate from the topic. A higher value means the AI is more likely to deviate from the topic, while a lower value means the AI is more likely to follow the topic. For creative tasks, you can adjust it to 1 or a bit higher. (-2.0~2.0)",
574
519
  ge=-2.0,
575
520
  le=2.0,
576
- json_schema_extra={
577
- "x-group": "ai",
578
- },
579
521
  ),
580
522
  ]
581
523
  wallet_provider: Annotated[
@@ -583,9 +525,6 @@ class AgentCore(BaseModel):
583
525
  PydanticField(
584
526
  default=None,
585
527
  description="Provider of the agent's wallet",
586
- json_schema_extra={
587
- "x-group": "onchain",
588
- },
589
528
  ),
590
529
  ]
591
530
  readonly_wallet_address: Annotated[
@@ -599,24 +538,16 @@ class AgentCore(BaseModel):
599
538
  Optional[
600
539
  Literal[
601
540
  "base-mainnet",
602
- "base-sepolia",
603
541
  "ethereum-mainnet",
604
- "ethereum-sepolia",
605
542
  "polygon-mainnet",
606
- "polygon-mumbai",
607
543
  "arbitrum-mainnet",
608
- "arbitrum-sepolia",
609
544
  "optimism-mainnet",
610
- "optimism-sepolia",
611
545
  "solana",
612
546
  ]
613
547
  ],
614
548
  PydanticField(
615
549
  default="base-mainnet",
616
550
  description="Network identifier",
617
- json_schema_extra={
618
- "x-group": "onchain",
619
- },
620
551
  ),
621
552
  ]
622
553
  skills: Annotated[
@@ -624,10 +555,6 @@ class AgentCore(BaseModel):
624
555
  PydanticField(
625
556
  default=None,
626
557
  description="Dict of skills and their corresponding configurations",
627
- json_schema_extra={
628
- "x-group": "skills",
629
- "x-inline": True,
630
- },
631
558
  ),
632
559
  ]
633
560
 
@@ -674,9 +601,6 @@ class AgentUserInput(AgentCore):
674
601
  PydanticField(
675
602
  default="trim",
676
603
  description="Strategy for managing short-term memory when context limit is reached. 'trim' removes oldest messages, 'summarize' creates summaries.",
677
- json_schema_extra={
678
- "x-group": "ai",
679
- },
680
604
  ),
681
605
  ]
682
606
  # autonomous mode
@@ -698,10 +622,6 @@ class AgentUserInput(AgentCore):
698
622
  " prompt: |-\n"
699
623
  " Say hi [sequence], use number for sequence.\n"
700
624
  ),
701
- json_schema_extra={
702
- "x-group": "autonomous",
703
- "x-inline": True,
704
- },
705
625
  ),
706
626
  ]
707
627
  # if telegram_entrypoint_enabled, the telegram_entrypoint_enabled will be enabled, telegram_config will be checked
@@ -710,9 +630,6 @@ class AgentUserInput(AgentCore):
710
630
  PydanticField(
711
631
  default=False,
712
632
  description="Whether the agent can play telegram bot",
713
- json_schema_extra={
714
- "x-group": "entrypoint",
715
- },
716
633
  ),
717
634
  ]
718
635
  telegram_entrypoint_prompt: Annotated[
@@ -721,9 +638,6 @@ class AgentUserInput(AgentCore):
721
638
  default=None,
722
639
  description="Extra prompt for telegram entrypoint",
723
640
  max_length=10000,
724
- json_schema_extra={
725
- "x-group": "entrypoint",
726
- },
727
641
  ),
728
642
  ]
729
643
  telegram_config: Annotated[
@@ -731,9 +645,6 @@ class AgentUserInput(AgentCore):
731
645
  PydanticField(
732
646
  default=None,
733
647
  description="Telegram integration configuration settings",
734
- json_schema_extra={
735
- "x-group": "entrypoint",
736
- },
737
648
  ),
738
649
  ]
739
650
  xmtp_entrypoint_prompt: Annotated[
@@ -742,9 +653,6 @@ class AgentUserInput(AgentCore):
742
653
  default=None,
743
654
  description="Extra prompt for xmtp entrypoint, xmtp support is in beta",
744
655
  max_length=10000,
745
- json_schema_extra={
746
- "x-group": "entrypoint",
747
- },
748
656
  ),
749
657
  ]
750
658
 
@@ -1380,6 +1288,142 @@ class Agent(AgentCreate, AgentPublicInfo):
1380
1288
  return None
1381
1289
  return cls.model_validate(item)
1382
1290
 
1291
+ @classmethod
1292
+ async def get_by_id_or_slug(cls, agent_id: str) -> Optional["Agent"]:
1293
+ """Get agent by ID or slug.
1294
+
1295
+ First tries to get by ID if agent_id length <= 20,
1296
+ then falls back to searching by slug if not found.
1297
+
1298
+ Args:
1299
+ agent_id: Agent ID or slug to search for
1300
+
1301
+ Returns:
1302
+ Agent if found, None otherwise
1303
+ """
1304
+ async with get_session() as db:
1305
+ agent = None
1306
+
1307
+ # Try to get by ID if length <= 20
1308
+ if len(agent_id) <= 20:
1309
+ agent = await Agent.get(agent_id)
1310
+
1311
+ # If not found, try to get by slug
1312
+ if agent is None:
1313
+ slug_stmt = select(AgentTable).where(AgentTable.slug == agent_id)
1314
+ agent_row = await db.scalar(slug_stmt)
1315
+ if agent_row is not None:
1316
+ agent = Agent.model_validate(agent_row)
1317
+
1318
+ return agent
1319
+
1320
+ @staticmethod
1321
+ def _deserialize_autonomous(
1322
+ autonomous_data: Optional[List[Any]],
1323
+ ) -> List[AgentAutonomous]:
1324
+ if not autonomous_data:
1325
+ return []
1326
+
1327
+ deserialized: List[AgentAutonomous] = []
1328
+ for entry in autonomous_data:
1329
+ if isinstance(entry, AgentAutonomous):
1330
+ deserialized.append(entry)
1331
+ else:
1332
+ deserialized.append(AgentAutonomous.model_validate(entry))
1333
+ return deserialized
1334
+
1335
+ @staticmethod
1336
+ def _serialize_autonomous(tasks: List[AgentAutonomous]) -> List[Dict[str, Any]]:
1337
+ return [task.model_dump() for task in tasks]
1338
+
1339
+ @staticmethod
1340
+ def _autonomous_not_allowed_error() -> IntentKitAPIError:
1341
+ return IntentKitAPIError(
1342
+ 400,
1343
+ "AgentNotDeployed",
1344
+ "Only deployed agents can call this feature.",
1345
+ )
1346
+
1347
+ async def list_autonomous_tasks(self) -> List[AgentAutonomous]:
1348
+ persisted = await Agent.get(self.id)
1349
+ if persisted is None:
1350
+ raise self._autonomous_not_allowed_error()
1351
+
1352
+ tasks = persisted.autonomous or []
1353
+ # Keep local state in sync with persisted data
1354
+ self.autonomous = tasks
1355
+ return tasks
1356
+
1357
+ async def add_autonomous_task(self, task: AgentAutonomous) -> AgentAutonomous:
1358
+ async with get_session() as session:
1359
+ db_agent = await session.get(AgentTable, self.id)
1360
+ if db_agent is None:
1361
+ raise self._autonomous_not_allowed_error()
1362
+
1363
+ current_tasks = self._deserialize_autonomous(db_agent.autonomous)
1364
+ current_tasks.append(task)
1365
+
1366
+ db_agent.autonomous = self._serialize_autonomous(current_tasks)
1367
+ await session.commit()
1368
+
1369
+ self.autonomous = current_tasks
1370
+ return task
1371
+
1372
+ async def delete_autonomous_task(self, task_id: str) -> None:
1373
+ async with get_session() as session:
1374
+ db_agent = await session.get(AgentTable, self.id)
1375
+ if db_agent is None:
1376
+ raise self._autonomous_not_allowed_error()
1377
+
1378
+ current_tasks = self._deserialize_autonomous(db_agent.autonomous)
1379
+
1380
+ updated_tasks = [task for task in current_tasks if task.id != task_id]
1381
+ if len(updated_tasks) == len(current_tasks):
1382
+ raise IntentKitAPIError(
1383
+ 404,
1384
+ "TaskNotFound",
1385
+ f"Autonomous task with ID {task_id} not found.",
1386
+ )
1387
+
1388
+ db_agent.autonomous = self._serialize_autonomous(updated_tasks)
1389
+ await session.commit()
1390
+
1391
+ self.autonomous = updated_tasks
1392
+
1393
+ async def update_autonomous_task(
1394
+ self, task_id: str, task_updates: dict
1395
+ ) -> AgentAutonomous:
1396
+ async with get_session() as session:
1397
+ db_agent = await session.get(AgentTable, self.id)
1398
+ if db_agent is None:
1399
+ raise self._autonomous_not_allowed_error()
1400
+
1401
+ current_tasks = self._deserialize_autonomous(db_agent.autonomous)
1402
+
1403
+ updated_task: Optional[AgentAutonomous] = None
1404
+ rewritten_tasks: List[AgentAutonomous] = []
1405
+ for task in current_tasks:
1406
+ if task.id == task_id:
1407
+ task_dict = task.model_dump()
1408
+ task_dict.update(task_updates)
1409
+ updated_task = AgentAutonomous.model_validate(task_dict)
1410
+ rewritten_tasks.append(updated_task)
1411
+ else:
1412
+ rewritten_tasks.append(task)
1413
+
1414
+ if updated_task is None:
1415
+ raise IntentKitAPIError(
1416
+ 404,
1417
+ "TaskNotFound",
1418
+ f"Autonomous task with ID {task_id} not found.",
1419
+ )
1420
+
1421
+ db_agent.autonomous = self._serialize_autonomous(rewritten_tasks)
1422
+ await session.commit()
1423
+
1424
+ self.autonomous = rewritten_tasks
1425
+ return updated_task
1426
+
1383
1427
  def skill_config(self, category: str) -> Dict[str, Any]:
1384
1428
  return self.skills.get(category, {}) if self.skills else {}
1385
1429
 
@@ -158,7 +158,8 @@
158
158
  "trim",
159
159
  "summarize"
160
160
  ],
161
- "x-group": "llm"
161
+ "x-group": "llm",
162
+ "x-advanced": true
162
163
  },
163
164
  "temperature": {
164
165
  "title": "Temperature",
@@ -168,7 +169,8 @@
168
169
  "minimum": 0.0,
169
170
  "maximum": 1.5,
170
171
  "x-group": "llm",
171
- "x-step": 0.1
172
+ "x-step": 0.1,
173
+ "x-advanced": true
172
174
  },
173
175
  "frequency_penalty": {
174
176
  "title": "Frequency Penalty",
@@ -346,16 +348,11 @@
346
348
  "description": "Default Network, please note that some CDP Wallet native skills like swap only support the base network.",
347
349
  "default": "base-mainnet",
348
350
  "enum": [
351
+ "base-mainnet",
349
352
  "ethereum-mainnet",
350
- "ethereum-sepolia",
351
353
  "polygon-mainnet",
352
- "polygon-mumbai",
353
- "base-mainnet",
354
- "base-sepolia",
355
354
  "arbitrum-mainnet",
356
- "arbitrum-sepolia",
357
- "optimism-mainnet",
358
- "optimism-sepolia"
355
+ "optimism-mainnet"
359
356
  ],
360
357
  "x-group": "onchain"
361
358
  }
intentkit/models/chat.py CHANGED
@@ -47,6 +47,7 @@ class AuthorType(str, Enum):
47
47
  SYSTEM = "system"
48
48
  API = "api"
49
49
  XMTP = "xmtp"
50
+ X402 = "x402"
50
51
 
51
52
 
52
53
  class ChatMessageAttachment(TypedDict):
intentkit/models/llm.csv CHANGED
@@ -1,23 +1,26 @@
1
1
  id,name,provider,enabled,input_price,output_price,price_level,context_length,output_length,intelligence,speed,supports_image_input,supports_skill_calls,supports_structured_output,has_reasoning,supports_search,supports_temperature,supports_frequency_penalty,supports_presence_penalty,api_base,timeout
2
- qwen/qwen3-235b-a22b-2507,Qwen3 235B A22B Instruct 2507,gatewayz,TRUE,0.1,0.6,1,262000,262000,4,2,FALSE,TRUE,FALSE,TRUE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
3
- google/gemini-2.5-flash,Gemini 2.5 Flash,gatewayz,TRUE,0.3,2.5,2,1050000,65000,4,2,TRUE,TRUE,FALSE,TRUE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
4
- x-ai/grok-4-fast:free,Grok 4 Fast,gatewayz,TRUE,0.2,0.5,1,128000,30000,4,2,TRUE,TRUE,FALSE,TRUE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
5
- x-ai/grok-code-fast-1,Grok Code Fast 1,gatewayz,TRUE,3,15,5,200000,64000,5,1,TRUE,TRUE,FALSE,TRUE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
6
- anthropic/claude-sonnet-4,Anthropic Claude Sonnet 4,gatewayz,TRUE,3,15,5,200000,64000,5,1,TRUE,TRUE,FALSE,TRUE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
2
+ minimax/minimax-m2:free,MiniMax M2,gatewayz,TRUE,0,0,1,204800,131000,4,2,FALSE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
3
+ qwen/qwen3-235b-a22b-2507,Qwen3 235B A22B Instruct 2507,gatewayz,TRUE,0.1,0.6,1,262000,262000,3,3,FALSE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
4
+ qwen/qwen3-max,Qwen3 Max,gatewayz,TRUE,1.2,6,4,128000,32000,4,2,FALSE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
5
+ google/gemini-2.5-flash,Gemini 2.5 Flash,gatewayz,TRUE,0.3,2.5,2,1050000,65000,3,4,TRUE,TRUE,FALSE,TRUE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
6
+ google/gemini-2.5-pro,Gemini 2.5 Pro,gatewayz,TRUE,1.25,10,4,1050000,65000,4,2,TRUE,TRUE,FALSE,TRUE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
7
+ anthropic/claude-sonnet-4.5,Anthropic Claude Sonnet 4.5,gatewayz,TRUE,3,15,5,200000,64000,5,1,TRUE,TRUE,FALSE,TRUE,FALSE,TRUE,FALSE,FALSE,https://api.gatewayz.ai/v1,300
8
+ gpt-5-nano,GPT-5 Nano,openai,TRUE,0.05,0.4,1,400000,128000,3,5,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,,180
9
+ gpt-5-mini,GPT-5 Mini,openai,TRUE,0.25,2,2,400000,128000,4,4,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,,180
10
+ gpt-5,GPT-5,openai,TRUE,1.25,10,4,400000,128000,5,3,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,,180
7
11
  gpt-4o,GPT-4o,openai,FALSE,2.5,10,4,128000,4096,4,3,TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,FALSE,FALSE,,180
8
12
  gpt-4o-mini,GPT-4o Mini,openai,FALSE,0.15,0.6,1,128000,4096,3,4,FALSE,TRUE,TRUE,FALSE,TRUE,TRUE,FALSE,FALSE,,180
9
13
  gpt-4.1-nano,GPT-4.1 Nano,openai,TRUE,0.1,0.4,1,128000,4096,3,5,FALSE,TRUE,TRUE,FALSE,FALSE,TRUE,FALSE,FALSE,,180
10
14
  gpt-4.1-mini,GPT-4.1 Mini,openai,TRUE,0.4,1.6,2,128000,4096,4,4,FALSE,TRUE,TRUE,FALSE,TRUE,TRUE,FALSE,FALSE,,180
11
15
  gpt-4.1,GPT-4.1,openai,TRUE,2,8,4,128000,4096,5,3,TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,FALSE,FALSE,,180
12
- gpt-5-nano,GPT-5 Nano,openai,TRUE,0.05,0.4,1,400000,128000,3,5,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,,180
13
- gpt-5-mini,GPT-5 Mini,openai,TRUE,0.25,2,2,400000,128000,4,4,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,,180
14
- gpt-5,GPT-5,openai,TRUE,1.25,10,4,400000,128000,5,3,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,,180
15
16
  o3,OpenAI o3,openai,TRUE,2,8,4,200000,100000,5,1,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,,180
16
17
  o4-mini,OpenAI o4-mini,openai,TRUE,1.1,4.4,3,128000,4096,4,3,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,,180
17
- deepseek-chat,Deepseek V3.1,deepseek,TRUE,0.56,1.68,2,128000,4096,4,3,FALSE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,https://api.deepseek.com,300
18
- deepseek-reasoner,DeepSeek V3.1 (Thinking Mode),deepseek,TRUE,0.56,1.68,2,128000,32000,5,1,FALSE,TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,TRUE,https://api.deepseek.com,300
19
- grok-2,Grok 2,xai,TRUE,2,10,4,120000,4096,3,3,FALSE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,,180
20
- grok-3,Grok 3,xai,TRUE,3,15,4,131072,4096,5,3,FALSE,TRUE,TRUE,FALSE,TRUE,TRUE,TRUE,TRUE,,180
18
+ deepseek-chat,Deepseek V3.2 Exp,deepseek,TRUE,0.28,0.42,2,128000,4096,4,3,FALSE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,https://api.deepseek.com,300
19
+ deepseek-reasoner,DeepSeek V3.2 Exp (Thinking Mode),deepseek,TRUE,0.28,0.42,2,128000,32000,5,1,FALSE,TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,TRUE,https://api.deepseek.com,300
20
+ grok-4,Grok 4,xai,TRUE,3,15,4,256000,4096,5,3,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,,180
21
+ grok-4-fast-non-reasoning,Grok 4 Fast,xai,TRUE,0.2,0.5,2,2000000,4096,3,4,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,,180
22
+ grok-code-fast-1,Grok Code Fast 1,xai,TRUE,0.2,1.5,3,256000,4096,4,4,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,,180
23
+ grok-3,Grok 3,xai,TRUE,3,15,4,131072,4096,5,3,FALSE,TRUE,TRUE,FALSE,TRUE,TRUE,FALSE,FALSE,,180
21
24
  grok-3-mini,Grok 3 Mini,xai,TRUE,0.3,0.5,2,131072,4096,5,3,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,,180
22
25
  eternalai,Eternal AI (Llama-3.3-70B),eternal,FALSE,0.25,0.75,2,64000,4096,4,3,FALSE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,https://api.eternalai.org/v1,300
23
26
  reigent,REI Network,reigent,FALSE,0.5,1.5,3,32000,4096,4,3,FALSE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,https://api.reisearch.box/v1,300
@@ -3,7 +3,6 @@
3
3
  import logging
4
4
  from typing import NotRequired, TypedDict
5
5
 
6
- from intentkit.abstracts.skill import SkillStoreABC
7
6
  from intentkit.skills.acolyt.ask import AcolytAskGpt
8
7
  from intentkit.skills.acolyt.base import AcolytBaseTool
9
8
  from intentkit.skills.base import SkillConfig, SkillState
@@ -28,7 +27,6 @@ class Config(SkillConfig):
28
27
  async def get_skills(
29
28
  config: "Config",
30
29
  is_private: bool,
31
- store: SkillStoreABC,
32
30
  **_,
33
31
  ) -> list[AcolytBaseTool]:
34
32
  """Get all Acolyt skills.
@@ -36,7 +34,6 @@ async def get_skills(
36
34
  Args:
37
35
  config: The configuration for Acolyt skills.
38
36
  is_private: Whether to include private skills.
39
- store: The skill store for persisting data.
40
37
 
41
38
  Returns:
42
39
  A list of Acolyt skills.
@@ -53,7 +50,7 @@ async def get_skills(
53
50
  # Get each skill using the cached getter
54
51
  result = []
55
52
  for name in available_skills:
56
- skill = get_acolyt_skill(name, store)
53
+ skill = get_acolyt_skill(name)
57
54
  if skill:
58
55
  result.append(skill)
59
56
  return result
@@ -61,22 +58,18 @@ async def get_skills(
61
58
 
62
59
  def get_acolyt_skill(
63
60
  name: str,
64
- store: SkillStoreABC,
65
61
  ) -> AcolytBaseTool | None:
66
62
  """Get an Acolyt skill by name.
67
63
 
68
64
  Args:
69
65
  name: The name of the skill to get
70
- store: The skill store for persisting data
71
66
 
72
67
  Returns:
73
68
  The requested Acolyt skill
74
69
  """
75
70
  if name == "ask_gpt":
76
71
  if name not in _cache:
77
- _cache[name] = AcolytAskGpt(
78
- skill_store=store,
79
- )
72
+ _cache[name] = AcolytAskGpt()
80
73
  return _cache[name]
81
74
  else:
82
75
  logger.warning(f"Unknown Acolyt skill: {name}")
@@ -3,7 +3,7 @@ from typing import Type
3
3
  from langchain_core.tools.base import ToolException
4
4
  from pydantic import BaseModel, Field
5
5
 
6
- from intentkit.abstracts.skill import SkillStoreABC
6
+ from intentkit.config.config import config
7
7
  from intentkit.skills.base import IntentKitSkill
8
8
 
9
9
  base_url = "https://acolyt-oracle-poc.vercel.app"
@@ -15,16 +15,13 @@ class AcolytBaseTool(IntentKitSkill):
15
15
  name: str = Field(description="The name of the tool")
16
16
  description: str = Field(description="A description of what the tool does")
17
17
  args_schema: Type[BaseModel]
18
- skill_store: SkillStoreABC = Field(
19
- description="The skill store for persisting data"
20
- )
21
18
 
22
19
  def get_api_key(self) -> str:
23
20
  context = self.get_context()
24
21
  skill_config = context.agent.skill_config(self.category)
25
22
  api_key_provider = skill_config.get("api_key_provider")
26
23
  if api_key_provider == "platform":
27
- return self.skill_store.get_system_config("acolyt_api_key")
24
+ return config.acolyt_api_key
28
25
  # for backward compatibility, may only have api_key in skill_config
29
26
  elif skill_config.get("api_key"):
30
27
  return skill_config.get("api_key")