intentkit 0.6.13.dev2__py3-none-any.whl → 0.8.17__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 (385) hide show
  1. intentkit/__init__.py +1 -1
  2. intentkit/abstracts/agent.py +4 -5
  3. intentkit/abstracts/engine.py +5 -5
  4. intentkit/abstracts/graph.py +14 -7
  5. intentkit/abstracts/skill.py +6 -144
  6. intentkit/abstracts/twitter.py +4 -5
  7. intentkit/clients/__init__.py +5 -2
  8. intentkit/clients/cdp.py +101 -141
  9. intentkit/clients/twitter.py +83 -62
  10. intentkit/clients/web3.py +29 -0
  11. intentkit/config/config.py +8 -5
  12. intentkit/core/agent.py +472 -195
  13. intentkit/core/asset.py +253 -0
  14. intentkit/core/chat.py +51 -0
  15. intentkit/core/client.py +1 -1
  16. intentkit/core/credit.py +460 -130
  17. intentkit/core/engine.py +262 -233
  18. intentkit/core/node.py +15 -16
  19. intentkit/core/prompt.py +62 -28
  20. intentkit/core/scheduler.py +92 -0
  21. intentkit/core/statistics.py +168 -0
  22. intentkit/models/agent.py +1096 -949
  23. intentkit/models/agent_data.py +68 -38
  24. intentkit/models/agent_public.json +98 -0
  25. intentkit/models/agent_schema.json +54 -439
  26. intentkit/models/app_setting.py +96 -33
  27. intentkit/models/chat.py +74 -27
  28. intentkit/models/conversation.py +8 -8
  29. intentkit/models/credit.py +362 -74
  30. intentkit/models/db.py +26 -8
  31. intentkit/models/db_mig.py +2 -2
  32. intentkit/models/llm.csv +28 -0
  33. intentkit/models/llm.py +185 -350
  34. intentkit/models/redis.py +6 -4
  35. intentkit/models/skill.py +186 -72
  36. intentkit/models/skills.csv +174 -0
  37. intentkit/models/user.py +82 -24
  38. intentkit/skills/acolyt/__init__.py +2 -9
  39. intentkit/skills/acolyt/ask.py +3 -4
  40. intentkit/skills/acolyt/base.py +4 -9
  41. intentkit/skills/acolyt/schema.json +4 -3
  42. intentkit/skills/aixbt/__init__.py +2 -13
  43. intentkit/skills/aixbt/base.py +1 -7
  44. intentkit/skills/aixbt/projects.py +14 -15
  45. intentkit/skills/aixbt/schema.json +4 -4
  46. intentkit/skills/allora/__init__.py +2 -9
  47. intentkit/skills/allora/base.py +4 -9
  48. intentkit/skills/allora/price.py +3 -4
  49. intentkit/skills/allora/schema.json +3 -2
  50. intentkit/skills/base.py +248 -85
  51. intentkit/skills/basename/__init__.py +51 -0
  52. intentkit/skills/basename/base.py +11 -0
  53. intentkit/skills/basename/basename.svg +11 -0
  54. intentkit/skills/basename/schema.json +58 -0
  55. intentkit/skills/carv/__init__.py +115 -121
  56. intentkit/skills/carv/base.py +184 -185
  57. intentkit/skills/carv/fetch_news.py +3 -3
  58. intentkit/skills/carv/onchain_query.py +4 -4
  59. intentkit/skills/carv/schema.json +134 -137
  60. intentkit/skills/carv/token_info_and_price.py +5 -5
  61. intentkit/skills/casino/README.md +254 -0
  62. intentkit/skills/casino/__init__.py +86 -0
  63. intentkit/skills/casino/base.py +17 -0
  64. intentkit/skills/casino/casino.png +0 -0
  65. intentkit/skills/casino/deck_draw.py +127 -0
  66. intentkit/skills/casino/deck_shuffle.py +118 -0
  67. intentkit/skills/casino/dice_roll.py +100 -0
  68. intentkit/skills/casino/schema.json +77 -0
  69. intentkit/skills/casino/utils.py +107 -0
  70. intentkit/skills/cdp/__init__.py +22 -84
  71. intentkit/skills/cdp/base.py +1 -7
  72. intentkit/skills/cdp/schema.json +11 -314
  73. intentkit/skills/chainlist/__init__.py +2 -7
  74. intentkit/skills/chainlist/base.py +1 -7
  75. intentkit/skills/chainlist/chain_lookup.py +18 -18
  76. intentkit/skills/chainlist/schema.json +3 -5
  77. intentkit/skills/common/__init__.py +2 -9
  78. intentkit/skills/common/base.py +1 -7
  79. intentkit/skills/common/current_time.py +1 -2
  80. intentkit/skills/common/schema.json +2 -2
  81. intentkit/skills/cookiefun/__init__.py +6 -9
  82. intentkit/skills/cookiefun/base.py +2 -7
  83. intentkit/skills/cookiefun/get_account_details.py +7 -7
  84. intentkit/skills/cookiefun/get_account_feed.py +19 -19
  85. intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
  86. intentkit/skills/cookiefun/get_sectors.py +3 -3
  87. intentkit/skills/cookiefun/schema.json +1 -3
  88. intentkit/skills/cookiefun/search_accounts.py +9 -9
  89. intentkit/skills/cryptocompare/__init__.py +7 -24
  90. intentkit/skills/cryptocompare/api.py +2 -3
  91. intentkit/skills/cryptocompare/base.py +11 -25
  92. intentkit/skills/cryptocompare/fetch_news.py +4 -5
  93. intentkit/skills/cryptocompare/fetch_price.py +6 -7
  94. intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
  95. intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
  96. intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
  97. intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
  98. intentkit/skills/cryptocompare/schema.json +3 -3
  99. intentkit/skills/cryptopanic/__init__.py +7 -10
  100. intentkit/skills/cryptopanic/base.py +51 -55
  101. intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
  102. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
  103. intentkit/skills/cryptopanic/schema.json +105 -103
  104. intentkit/skills/dapplooker/__init__.py +2 -9
  105. intentkit/skills/dapplooker/base.py +4 -9
  106. intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
  107. intentkit/skills/dapplooker/schema.json +3 -5
  108. intentkit/skills/defillama/__init__.py +24 -74
  109. intentkit/skills/defillama/api.py +6 -9
  110. intentkit/skills/defillama/base.py +11 -21
  111. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
  112. intentkit/skills/defillama/coins/fetch_block.py +6 -8
  113. intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
  114. intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
  115. intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
  116. intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
  117. intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
  118. intentkit/skills/defillama/config/chains.py +1 -3
  119. intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
  120. intentkit/skills/defillama/schema.json +5 -1
  121. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
  122. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
  123. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
  124. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
  125. intentkit/skills/defillama/tests/api_integration.test.py +1 -1
  126. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
  127. intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
  128. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
  129. intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
  130. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
  131. intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
  132. intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
  133. intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
  134. intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
  135. intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
  136. intentkit/skills/defillama/yields/fetch_pools.py +26 -30
  137. intentkit/skills/dexscreener/README.md +154 -0
  138. intentkit/skills/dexscreener/__init__.py +97 -93
  139. intentkit/skills/dexscreener/base.py +125 -133
  140. intentkit/skills/dexscreener/get_pair_info.py +158 -0
  141. intentkit/skills/dexscreener/get_token_pairs.py +165 -0
  142. intentkit/skills/dexscreener/get_tokens_info.py +212 -0
  143. intentkit/skills/dexscreener/model/search_token_response.py +80 -82
  144. intentkit/skills/dexscreener/schema.json +91 -48
  145. intentkit/skills/dexscreener/search_token.py +182 -321
  146. intentkit/skills/dexscreener/utils.py +420 -0
  147. intentkit/skills/dune_analytics/__init__.py +7 -9
  148. intentkit/skills/dune_analytics/base.py +48 -52
  149. intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
  150. intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
  151. intentkit/skills/dune_analytics/schema.json +104 -99
  152. intentkit/skills/elfa/__init__.py +5 -18
  153. intentkit/skills/elfa/base.py +10 -14
  154. intentkit/skills/elfa/mention.py +19 -21
  155. intentkit/skills/elfa/schema.json +3 -2
  156. intentkit/skills/elfa/stats.py +4 -4
  157. intentkit/skills/elfa/tokens.py +12 -12
  158. intentkit/skills/elfa/utils.py +26 -28
  159. intentkit/skills/enso/__init__.py +11 -31
  160. intentkit/skills/enso/base.py +50 -35
  161. intentkit/skills/enso/best_yield.py +16 -24
  162. intentkit/skills/enso/networks.py +6 -11
  163. intentkit/skills/enso/prices.py +11 -13
  164. intentkit/skills/enso/route.py +34 -38
  165. intentkit/skills/enso/schema.json +3 -2
  166. intentkit/skills/enso/tokens.py +29 -38
  167. intentkit/skills/enso/wallet.py +76 -191
  168. intentkit/skills/erc20/__init__.py +50 -0
  169. intentkit/skills/erc20/base.py +11 -0
  170. intentkit/skills/erc20/erc20.svg +5 -0
  171. intentkit/skills/erc20/schema.json +74 -0
  172. intentkit/skills/erc721/__init__.py +53 -0
  173. intentkit/skills/erc721/base.py +11 -0
  174. intentkit/skills/erc721/erc721.svg +5 -0
  175. intentkit/skills/erc721/schema.json +90 -0
  176. intentkit/skills/firecrawl/README.md +11 -5
  177. intentkit/skills/firecrawl/__init__.py +5 -18
  178. intentkit/skills/firecrawl/base.py +4 -11
  179. intentkit/skills/firecrawl/clear.py +4 -8
  180. intentkit/skills/firecrawl/crawl.py +19 -19
  181. intentkit/skills/firecrawl/query.py +4 -3
  182. intentkit/skills/firecrawl/schema.json +6 -8
  183. intentkit/skills/firecrawl/scrape.py +150 -40
  184. intentkit/skills/firecrawl/utils.py +50 -42
  185. intentkit/skills/github/__init__.py +2 -7
  186. intentkit/skills/github/base.py +1 -7
  187. intentkit/skills/github/github_search.py +1 -2
  188. intentkit/skills/github/schema.json +3 -4
  189. intentkit/skills/heurist/__init__.py +8 -27
  190. intentkit/skills/heurist/base.py +4 -9
  191. intentkit/skills/heurist/image_generation_animagine_xl.py +12 -13
  192. intentkit/skills/heurist/image_generation_arthemy_comics.py +12 -13
  193. intentkit/skills/heurist/image_generation_arthemy_real.py +12 -13
  194. intentkit/skills/heurist/image_generation_braindance.py +12 -13
  195. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +12 -13
  196. intentkit/skills/heurist/image_generation_flux_1_dev.py +12 -13
  197. intentkit/skills/heurist/image_generation_sdxl.py +12 -13
  198. intentkit/skills/heurist/schema.json +2 -2
  199. intentkit/skills/http/__init__.py +4 -15
  200. intentkit/skills/http/base.py +1 -7
  201. intentkit/skills/http/get.py +21 -16
  202. intentkit/skills/http/post.py +23 -18
  203. intentkit/skills/http/put.py +23 -18
  204. intentkit/skills/http/schema.json +4 -5
  205. intentkit/skills/lifi/__init__.py +8 -13
  206. intentkit/skills/lifi/base.py +1 -7
  207. intentkit/skills/lifi/schema.json +17 -8
  208. intentkit/skills/lifi/token_execute.py +36 -30
  209. intentkit/skills/lifi/token_quote.py +8 -10
  210. intentkit/skills/lifi/utils.py +104 -51
  211. intentkit/skills/moralis/__init__.py +6 -10
  212. intentkit/skills/moralis/api.py +6 -7
  213. intentkit/skills/moralis/base.py +5 -10
  214. intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
  215. intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
  216. intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
  217. intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
  218. intentkit/skills/moralis/schema.json +7 -2
  219. intentkit/skills/morpho/__init__.py +52 -0
  220. intentkit/skills/morpho/base.py +11 -0
  221. intentkit/skills/morpho/morpho.svg +12 -0
  222. intentkit/skills/morpho/schema.json +73 -0
  223. intentkit/skills/nation/__init__.py +4 -9
  224. intentkit/skills/nation/base.py +5 -10
  225. intentkit/skills/nation/nft_check.py +3 -4
  226. intentkit/skills/nation/schema.json +4 -3
  227. intentkit/skills/onchain.py +23 -0
  228. intentkit/skills/openai/__init__.py +17 -18
  229. intentkit/skills/openai/base.py +10 -14
  230. intentkit/skills/openai/dalle_image_generation.py +3 -8
  231. intentkit/skills/openai/gpt_avatar_generator.py +102 -0
  232. intentkit/skills/openai/gpt_image_generation.py +4 -8
  233. intentkit/skills/openai/gpt_image_mini_generator.py +91 -0
  234. intentkit/skills/openai/gpt_image_to_image.py +4 -8
  235. intentkit/skills/openai/image_to_text.py +3 -7
  236. intentkit/skills/openai/schema.json +34 -3
  237. intentkit/skills/portfolio/__init__.py +11 -35
  238. intentkit/skills/portfolio/base.py +33 -19
  239. intentkit/skills/portfolio/schema.json +3 -5
  240. intentkit/skills/portfolio/token_balances.py +21 -21
  241. intentkit/skills/portfolio/wallet_approvals.py +17 -18
  242. intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
  243. intentkit/skills/portfolio/wallet_history.py +31 -31
  244. intentkit/skills/portfolio/wallet_net_worth.py +13 -13
  245. intentkit/skills/portfolio/wallet_nfts.py +19 -19
  246. intentkit/skills/portfolio/wallet_profitability.py +18 -18
  247. intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
  248. intentkit/skills/portfolio/wallet_stats.py +3 -3
  249. intentkit/skills/portfolio/wallet_swaps.py +19 -19
  250. intentkit/skills/pyth/__init__.py +50 -0
  251. intentkit/skills/pyth/base.py +11 -0
  252. intentkit/skills/pyth/pyth.svg +6 -0
  253. intentkit/skills/pyth/schema.json +75 -0
  254. intentkit/skills/skills.toml +40 -0
  255. intentkit/skills/slack/__init__.py +5 -17
  256. intentkit/skills/slack/base.py +3 -9
  257. intentkit/skills/slack/get_channel.py +8 -8
  258. intentkit/skills/slack/get_message.py +9 -9
  259. intentkit/skills/slack/schedule_message.py +5 -5
  260. intentkit/skills/slack/schema.json +2 -2
  261. intentkit/skills/slack/send_message.py +3 -5
  262. intentkit/skills/supabase/__init__.py +7 -23
  263. intentkit/skills/supabase/base.py +9 -13
  264. intentkit/skills/supabase/delete_data.py +5 -6
  265. intentkit/skills/supabase/fetch_data.py +13 -14
  266. intentkit/skills/supabase/insert_data.py +5 -6
  267. intentkit/skills/supabase/invoke_function.py +7 -8
  268. intentkit/skills/supabase/schema.json +2 -3
  269. intentkit/skills/supabase/update_data.py +7 -8
  270. intentkit/skills/supabase/upsert_data.py +5 -6
  271. intentkit/skills/superfluid/__init__.py +53 -0
  272. intentkit/skills/superfluid/base.py +11 -0
  273. intentkit/skills/superfluid/schema.json +89 -0
  274. intentkit/skills/superfluid/superfluid.svg +6 -0
  275. intentkit/skills/system/__init__.py +7 -24
  276. intentkit/skills/system/add_autonomous_task.py +10 -12
  277. intentkit/skills/system/delete_autonomous_task.py +2 -2
  278. intentkit/skills/system/edit_autonomous_task.py +14 -18
  279. intentkit/skills/system/list_autonomous_tasks.py +3 -5
  280. intentkit/skills/system/read_agent_api_key.py +6 -4
  281. intentkit/skills/system/regenerate_agent_api_key.py +6 -4
  282. intentkit/skills/system/schema.json +6 -8
  283. intentkit/skills/tavily/__init__.py +3 -12
  284. intentkit/skills/tavily/base.py +4 -9
  285. intentkit/skills/tavily/schema.json +3 -5
  286. intentkit/skills/tavily/tavily_extract.py +2 -4
  287. intentkit/skills/tavily/tavily_search.py +4 -6
  288. intentkit/skills/token/__init__.py +5 -10
  289. intentkit/skills/token/base.py +7 -11
  290. intentkit/skills/token/erc20_transfers.py +19 -19
  291. intentkit/skills/token/schema.json +3 -6
  292. intentkit/skills/token/token_analytics.py +3 -3
  293. intentkit/skills/token/token_price.py +13 -13
  294. intentkit/skills/token/token_search.py +9 -9
  295. intentkit/skills/twitter/__init__.py +11 -35
  296. intentkit/skills/twitter/base.py +23 -35
  297. intentkit/skills/twitter/follow_user.py +3 -7
  298. intentkit/skills/twitter/get_mentions.py +6 -13
  299. intentkit/skills/twitter/get_timeline.py +5 -13
  300. intentkit/skills/twitter/get_user_by_username.py +3 -7
  301. intentkit/skills/twitter/get_user_tweets.py +6 -14
  302. intentkit/skills/twitter/like_tweet.py +3 -7
  303. intentkit/skills/twitter/post_tweet.py +23 -12
  304. intentkit/skills/twitter/reply_tweet.py +21 -12
  305. intentkit/skills/twitter/retweet.py +3 -7
  306. intentkit/skills/twitter/schema.json +1 -0
  307. intentkit/skills/twitter/search_tweets.py +5 -13
  308. intentkit/skills/unrealspeech/__init__.py +2 -7
  309. intentkit/skills/unrealspeech/base.py +2 -8
  310. intentkit/skills/unrealspeech/schema.json +2 -5
  311. intentkit/skills/unrealspeech/text_to_speech.py +8 -8
  312. intentkit/skills/venice_audio/__init__.py +98 -106
  313. intentkit/skills/venice_audio/base.py +117 -121
  314. intentkit/skills/venice_audio/input.py +41 -41
  315. intentkit/skills/venice_audio/schema.json +151 -152
  316. intentkit/skills/venice_audio/venice_audio.py +38 -21
  317. intentkit/skills/venice_image/__init__.py +147 -154
  318. intentkit/skills/venice_image/api.py +138 -138
  319. intentkit/skills/venice_image/base.py +185 -192
  320. intentkit/skills/venice_image/config.py +33 -35
  321. intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
  322. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
  323. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
  324. intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
  325. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
  326. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
  327. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
  328. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
  329. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
  330. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
  331. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
  332. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
  333. intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
  334. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
  335. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
  336. intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
  337. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
  338. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
  339. intentkit/skills/venice_image/schema.json +267 -267
  340. intentkit/skills/venice_image/utils.py +77 -78
  341. intentkit/skills/web_scraper/__init__.py +5 -18
  342. intentkit/skills/web_scraper/base.py +21 -7
  343. intentkit/skills/web_scraper/document_indexer.py +7 -6
  344. intentkit/skills/web_scraper/schema.json +2 -6
  345. intentkit/skills/web_scraper/scrape_and_index.py +15 -15
  346. intentkit/skills/web_scraper/utils.py +62 -63
  347. intentkit/skills/web_scraper/website_indexer.py +17 -19
  348. intentkit/skills/weth/__init__.py +49 -0
  349. intentkit/skills/weth/base.py +11 -0
  350. intentkit/skills/weth/schema.json +58 -0
  351. intentkit/skills/weth/weth.svg +6 -0
  352. intentkit/skills/wow/__init__.py +51 -0
  353. intentkit/skills/wow/base.py +11 -0
  354. intentkit/skills/wow/schema.json +89 -0
  355. intentkit/skills/wow/wow.svg +7 -0
  356. intentkit/skills/x402/__init__.py +61 -0
  357. intentkit/skills/x402/ask_agent.py +98 -0
  358. intentkit/skills/x402/base.py +99 -0
  359. intentkit/skills/x402/http_request.py +117 -0
  360. intentkit/skills/x402/schema.json +45 -0
  361. intentkit/skills/x402/x402.webp +0 -0
  362. intentkit/skills/xmtp/__init__.py +4 -15
  363. intentkit/skills/xmtp/base.py +61 -2
  364. intentkit/skills/xmtp/price.py +18 -13
  365. intentkit/skills/xmtp/schema.json +69 -71
  366. intentkit/skills/xmtp/swap.py +22 -25
  367. intentkit/skills/xmtp/transfer.py +71 -32
  368. intentkit/utils/chain.py +3 -3
  369. intentkit/utils/error.py +14 -1
  370. intentkit/utils/logging.py +2 -4
  371. intentkit/utils/s3.py +59 -7
  372. intentkit/utils/schema.py +100 -0
  373. intentkit/utils/slack_alert.py +7 -8
  374. {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +14 -16
  375. intentkit-0.8.17.dist-info/RECORD +466 -0
  376. intentkit/abstracts/exception.py +0 -9
  377. intentkit/core/skill.py +0 -200
  378. intentkit/models/generator.py +0 -347
  379. intentkit/skills/cdp/get_balance.py +0 -110
  380. intentkit/skills/cdp/swap.py +0 -121
  381. intentkit/skills/moralis/tests/__init__.py +0 -0
  382. intentkit/skills/moralis/tests/test_wallet.py +0 -511
  383. intentkit-0.6.13.dev2.dist-info/RECORD +0 -409
  384. {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
  385. {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import List, Optional, Type
3
2
 
4
3
  import httpx
5
4
  from langchain_core.documents import Document
@@ -16,7 +15,7 @@ class FirecrawlScrapeInput(BaseModel):
16
15
  url: str = Field(
17
16
  description="The URL to scrape. Must be a valid HTTP or HTTPS URL."
18
17
  )
19
- formats: List[str] = Field(
18
+ formats: list[str] = Field(
20
19
  description="Output formats to include in the response. Options: 'markdown', 'html', 'rawHtml', 'screenshot', 'links', 'json'",
21
20
  default=["markdown"],
22
21
  )
@@ -24,11 +23,11 @@ class FirecrawlScrapeInput(BaseModel):
24
23
  description="Whether to extract only the main content (excluding headers, footers, navigation, etc.)",
25
24
  default=True,
26
25
  )
27
- include_tags: Optional[List[str]] = Field(
26
+ include_tags: list[str] | None = Field(
28
27
  description="HTML tags, classes, or IDs to include in the response (e.g., ['h1', 'p', '.main-content'])",
29
28
  default=None,
30
29
  )
31
- exclude_tags: Optional[List[str]] = Field(
30
+ exclude_tags: list[str] | None = Field(
32
31
  description="HTML tags, classes, or IDs to exclude from the response (e.g., ['#ad', '#footer'])",
33
32
  default=None,
34
33
  )
@@ -62,10 +61,11 @@ class FirecrawlScrapeInput(BaseModel):
62
61
 
63
62
 
64
63
  class FirecrawlScrape(FirecrawlBaseTool):
65
- """Tool for scraping web pages using Firecrawl.
64
+ """Tool for scraping web pages using Firecrawl with REPLACE behavior.
66
65
 
67
- This tool uses Firecrawl's API to scrape web pages and convert them into clean,
68
- LLM-ready formats like markdown, HTML, or structured JSON data.
66
+ This tool uses Firecrawl's API to scrape web pages and REPLACES any existing
67
+ indexed content for the same URL instead of appending to it. This prevents
68
+ duplicate content when re-scraping the same page.
69
69
 
70
70
  Attributes:
71
71
  name: The name of the tool.
@@ -75,20 +75,20 @@ class FirecrawlScrape(FirecrawlBaseTool):
75
75
 
76
76
  name: str = "firecrawl_scrape"
77
77
  description: str = (
78
- "Scrape a single web page and extract its content in various formats (markdown, HTML, JSON, etc.). "
78
+ "Scrape a single web page and REPLACE any existing indexed content for that URL. "
79
+ "Unlike regular scrape, this tool removes old content before adding new content, preventing duplicates. "
79
80
  "This tool can handle JavaScript-rendered content, PDFs, and dynamic websites. "
80
- "Optionally indexes the content for later querying using the firecrawl_query_indexed_content tool. "
81
- "Use this when you need to extract clean, structured content from a specific URL."
81
+ "Use this when you want to refresh/update content from a URL that was previously scraped."
82
82
  )
83
- args_schema: Type[BaseModel] = FirecrawlScrapeInput
83
+ args_schema: type[BaseModel] = FirecrawlScrapeInput
84
84
 
85
85
  async def _arun(
86
86
  self,
87
87
  url: str,
88
- formats: List[str] = None,
88
+ formats: list[str] = None,
89
89
  only_main_content: bool = True,
90
- include_tags: Optional[List[str]] = None,
91
- exclude_tags: Optional[List[str]] = None,
90
+ include_tags: list[str] | None = None,
91
+ exclude_tags: list[str] | None = None,
92
92
  wait_for: int = 0,
93
93
  timeout: int = 30000,
94
94
  index_content: bool = True,
@@ -123,9 +123,8 @@ class FirecrawlScrape(FirecrawlBaseTool):
123
123
  "rate_limit_minutes"
124
124
  ):
125
125
  await self.user_rate_limit_by_category(
126
- context.user_id,
127
126
  skill_config["rate_limit_number"],
128
- skill_config["rate_limit_minutes"],
127
+ skill_config["rate_limit_minutes"] * 60,
129
128
  )
130
129
 
131
130
  # Get the API key from the agent's configuration
@@ -187,7 +186,7 @@ class FirecrawlScrape(FirecrawlBaseTool):
187
186
  result_data = data.get("data", {})
188
187
 
189
188
  # Format the results based on requested formats
190
- formatted_result = f"Successfully scraped: {url}\n\n"
189
+ formatted_result = f"Successfully scraped (REPLACE mode): {url}\n\n"
191
190
 
192
191
  if "markdown" in formats and result_data.get("markdown"):
193
192
  formatted_result += "## Markdown Content\n"
@@ -236,13 +235,16 @@ class FirecrawlScrape(FirecrawlBaseTool):
236
235
  formatted_result += f"Language: {metadata['language']}\n"
237
236
  formatted_result += "\n"
238
237
 
239
- # Index content if requested
238
+ # Index content if requested - REPLACE MODE
240
239
  if index_content and result_data.get("markdown"):
241
240
  try:
242
- # Import indexing utilities from firecrawl utils
241
+ # Import indexing utilities
242
+ from langchain_community.vectorstores import FAISS
243
+
243
244
  from intentkit.skills.firecrawl.utils import (
245
+ FirecrawlDocumentProcessor,
244
246
  FirecrawlMetadataManager,
245
- index_documents,
247
+ FirecrawlVectorStoreManager,
246
248
  )
247
249
 
248
250
  # Create document from scraped content
@@ -261,38 +263,146 @@ class FirecrawlScrape(FirecrawlBaseTool):
261
263
  # Get agent ID for indexing
262
264
  agent_id = context.agent_id
263
265
  if agent_id:
264
- # Index the document
265
- total_chunks, was_merged = await index_documents(
266
- [document],
267
- agent_id,
268
- self.skill_store,
269
- chunk_size,
270
- chunk_overlap,
266
+ # Initialize vector store manager
267
+ vs_manager = FirecrawlVectorStoreManager()
268
+
269
+ # Load existing vector store
270
+ existing_vector_store = await vs_manager.load_vector_store(
271
+ agent_id
271
272
  )
272
273
 
273
- # Update metadata
274
- metadata_manager = FirecrawlMetadataManager(
275
- self.skill_store
274
+ # Split the new document into chunks
275
+ split_docs = FirecrawlDocumentProcessor.split_documents(
276
+ [document], chunk_size, chunk_overlap
276
277
  )
277
- new_metadata = metadata_manager.create_url_metadata(
278
- [url], [document], "firecrawl_scrape"
278
+
279
+ # Create embeddings
280
+ embeddings = vs_manager.create_embeddings()
281
+
282
+ if existing_vector_store:
283
+ # Get all existing documents and filter out those from the same URL
284
+ try:
285
+ # Try to access documents directly if available
286
+ if hasattr(
287
+ existing_vector_store, "docstore"
288
+ ) and hasattr(
289
+ existing_vector_store.docstore, "_dict"
290
+ ):
291
+ # Access FAISS documents directly
292
+ all_docs = list(
293
+ existing_vector_store.docstore._dict.values()
294
+ )
295
+ else:
296
+ # Fallback: use a reasonable k value for similarity search
297
+ # Use a dummy query to retrieve documents
298
+ all_docs = existing_vector_store.similarity_search(
299
+ "dummy", # Use a dummy query instead of empty string
300
+ k=1000, # Use reasonable upper bound
301
+ )
302
+
303
+ # Filter out documents from the same URL
304
+ preserved_docs = [
305
+ doc
306
+ for doc in all_docs
307
+ if doc.metadata.get("source") != url
308
+ ]
309
+
310
+ logger.info(
311
+ f"firecrawl_scrape: Preserving {len(preserved_docs)} docs from other URLs, "
312
+ f"replacing content from {url}"
313
+ )
314
+
315
+ # Create new vector store with preserved docs + new docs
316
+ if preserved_docs:
317
+ # Combine preserved and new documents
318
+ all_documents = preserved_docs + split_docs
319
+ new_vector_store = FAISS.from_documents(
320
+ all_documents, embeddings
321
+ )
322
+ formatted_result += "\n## Content Replacement\n"
323
+ formatted_result += f"Replaced existing content for URL: {url}\n"
324
+ num_preserved_urls = len(
325
+ set(
326
+ doc.metadata.get("source", "")
327
+ for doc in preserved_docs
328
+ )
329
+ )
330
+ formatted_result += f"Preserved content from {num_preserved_urls} other URLs\n"
331
+ else:
332
+ # No other documents to preserve, just create from new docs
333
+ new_vector_store = FAISS.from_documents(
334
+ split_docs, embeddings
335
+ )
336
+ formatted_result += "\n## Content Replacement\n"
337
+ formatted_result += f"Created new index with content from: {url}\n"
338
+ except Exception as e:
339
+ logger.warning(
340
+ f"Could not preserve other URLs, creating fresh index: {e}"
341
+ )
342
+ # Fallback: create new store with just the new documents
343
+ new_vector_store = FAISS.from_documents(
344
+ split_docs, embeddings
345
+ )
346
+ formatted_result += "\n## Content Replacement\n"
347
+ formatted_result += f"Created fresh index with content from: {url}\n"
348
+ else:
349
+ # No existing store, create new one
350
+ new_vector_store = FAISS.from_documents(
351
+ split_docs, embeddings
352
+ )
353
+ formatted_result += "\n## Content Indexing\n"
354
+ formatted_result += (
355
+ f"Created new index with content from: {url}\n"
356
+ )
357
+
358
+ # Save the new vector store
359
+ await vs_manager.save_vector_store(
360
+ agent_id, new_vector_store, chunk_size, chunk_overlap
279
361
  )
280
- await metadata_manager.update_metadata(
281
- agent_id, new_metadata
362
+
363
+ # Update metadata to track all URLs
364
+ # Get existing metadata to preserve other URLs
365
+ metadata_key = f"indexed_urls_{agent_id}"
366
+ existing_metadata = await self.get_agent_skill_data_raw(
367
+ "firecrawl", metadata_key
282
368
  )
283
369
 
284
- formatted_result += "\n## Content Indexing\n"
285
- formatted_result += (
286
- "Successfully indexed content into vector store:\n"
370
+ if existing_metadata and existing_metadata.get("urls"):
371
+ # Remove the current URL and add it back (to update timestamp)
372
+ existing_urls = [
373
+ u for u in existing_metadata["urls"] if u != url
374
+ ]
375
+ existing_urls.append(url)
376
+ updated_metadata = {
377
+ "urls": existing_urls,
378
+ "document_count": len(existing_urls),
379
+ "source_type": "firecrawl_mixed",
380
+ "indexed_at": str(len(existing_urls)),
381
+ }
382
+ else:
383
+ # Create new metadata
384
+ updated_metadata = (
385
+ FirecrawlMetadataManager.create_url_metadata(
386
+ [url], [document], "firecrawl_scrape"
387
+ )
388
+ )
389
+
390
+ await FirecrawlMetadataManager.update_metadata(
391
+ agent_id, updated_metadata
287
392
  )
288
- formatted_result += f"- Chunks created: {total_chunks}\n"
393
+
394
+ formatted_result += "\n## Content Indexing (REPLACE MODE)\n"
395
+ formatted_result += "Successfully REPLACED indexed content in vector store:\n"
396
+ formatted_result += f"- Chunks created: {len(split_docs)}\n"
289
397
  formatted_result += f"- Chunk size: {chunk_size}\n"
290
398
  formatted_result += f"- Chunk overlap: {chunk_overlap}\n"
291
- formatted_result += f"- Content merged with existing: {'Yes' if was_merged else 'No'}\n"
399
+ formatted_result += (
400
+ "- Previous content for this URL: REPLACED\n"
401
+ )
292
402
  formatted_result += "Use the 'firecrawl_query_indexed_content' skill to search this content.\n"
293
403
 
294
404
  logger.info(
295
- f"firecrawl_scrape: Successfully indexed {url} with {total_chunks} chunks"
405
+ f"firecrawl_scrape: Successfully replaced content for {url} with {len(split_docs)} chunks"
296
406
  )
297
407
  else:
298
408
  formatted_result += "\n## Content Indexing\n"
@@ -2,14 +2,15 @@
2
2
 
3
3
  import logging
4
4
  import re
5
- from typing import Any, Dict, List, Optional, Tuple
5
+ from typing import Any
6
6
 
7
- from langchain.text_splitter import RecursiveCharacterTextSplitter
8
7
  from langchain_community.vectorstores import FAISS
9
8
  from langchain_core.documents import Document
10
9
  from langchain_openai import OpenAIEmbeddings
10
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
11
11
 
12
- from intentkit.abstracts.skill import SkillStoreABC
12
+ from intentkit.config.config import config
13
+ from intentkit.models.skill import AgentSkillData, AgentSkillDataCreate
13
14
 
14
15
  logger = logging.getLogger(__name__)
15
16
 
@@ -35,8 +36,8 @@ class FirecrawlDocumentProcessor:
35
36
 
36
37
  @staticmethod
37
38
  def split_documents(
38
- documents: List[Document], chunk_size: int = 1000, chunk_overlap: int = 200
39
- ) -> List[Document]:
39
+ documents: list[Document], chunk_size: int = 1000, chunk_overlap: int = 200
40
+ ) -> list[Document]:
40
41
  """Split documents into smaller chunks for better indexing."""
41
42
  text_splitter = RecursiveCharacterTextSplitter(
42
43
  chunk_size=chunk_size,
@@ -62,20 +63,25 @@ class FirecrawlDocumentProcessor:
62
63
  class FirecrawlVectorStoreManager:
63
64
  """Manages vector store operations for Firecrawl content."""
64
65
 
65
- def __init__(self, skill_store: SkillStoreABC):
66
- self.skill_store = skill_store
66
+ def __init__(self, embedding_api_key: str | None = None):
67
+ self._embedding_api_key = embedding_api_key
68
+
69
+ def _resolve_api_key(self) -> str:
70
+ """Resolve the API key to use for embeddings."""
71
+ if self._embedding_api_key:
72
+ return self._embedding_api_key
73
+ if config.openai_api_key:
74
+ return config.openai_api_key
75
+ raise ValueError("OpenAI API key not found in system configuration")
67
76
 
68
77
  def create_embeddings(self) -> OpenAIEmbeddings:
69
78
  """Create OpenAI embeddings instance."""
70
- openai_api_key = self.skill_store.get_system_config("openai_api_key")
71
- if not openai_api_key:
72
- raise ValueError("OpenAI API key not found in system configuration")
73
-
79
+ openai_api_key = self._resolve_api_key()
74
80
  return OpenAIEmbeddings(
75
81
  openai_api_key=openai_api_key, model="text-embedding-3-small"
76
82
  )
77
83
 
78
- def encode_vector_store(self, vector_store: FAISS) -> Dict[str, str]:
84
+ def encode_vector_store(self, vector_store: FAISS) -> dict[str, str]:
79
85
  """Encode FAISS vector store to base64 for storage (compatible with web_scraper)."""
80
86
  import base64
81
87
  import os
@@ -100,7 +106,7 @@ class FirecrawlVectorStoreManager:
100
106
  raise
101
107
 
102
108
  def decode_vector_store(
103
- self, encoded_files: Dict[str, str], embeddings: OpenAIEmbeddings
109
+ self, encoded_files: dict[str, str], embeddings: OpenAIEmbeddings
104
110
  ) -> FAISS:
105
111
  """Decode base64 files back to FAISS vector store (compatible with web_scraper)."""
106
112
  import base64
@@ -125,11 +131,11 @@ class FirecrawlVectorStoreManager:
125
131
  logger.error(f"Error decoding vector store: {e}")
126
132
  raise
127
133
 
128
- async def load_vector_store(self, agent_id: str) -> Optional[FAISS]:
134
+ async def load_vector_store(self, agent_id: str) -> FAISS | None:
129
135
  """Load existing vector store for an agent."""
130
136
  try:
131
137
  vector_store_key = f"vector_store_{agent_id}"
132
- stored_data = await self.skill_store.get_agent_skill_data(
138
+ stored_data = await AgentSkillData.get(
133
139
  agent_id, "web_scraper", vector_store_key
134
140
  )
135
141
 
@@ -162,9 +168,13 @@ class FirecrawlVectorStoreManager:
162
168
  "chunk_overlap": chunk_overlap,
163
169
  }
164
170
 
165
- await self.skill_store.save_agent_skill_data(
166
- agent_id, "web_scraper", vector_store_key, storage_data
171
+ skill_data = AgentSkillDataCreate(
172
+ agent_id=agent_id,
173
+ skill="web_scraper",
174
+ key=vector_store_key,
175
+ data=storage_data,
167
176
  )
177
+ await skill_data.save()
168
178
 
169
179
  except Exception as e:
170
180
  logger.error(f"Error saving vector store for agent {agent_id}: {e}")
@@ -174,12 +184,10 @@ class FirecrawlVectorStoreManager:
174
184
  class FirecrawlMetadataManager:
175
185
  """Manages metadata for Firecrawl indexed content."""
176
186
 
177
- def __init__(self, skill_store: SkillStoreABC):
178
- self.skill_store = skill_store
179
-
187
+ @staticmethod
180
188
  def create_url_metadata(
181
- self, urls: List[str], documents: List[Document], source_type: str
182
- ) -> Dict[str, Any]:
189
+ urls: list[str], documents: list[Document], source_type: str
190
+ ) -> dict[str, Any]:
183
191
  """Create metadata for indexed URLs."""
184
192
  return {
185
193
  "urls": urls,
@@ -188,34 +196,38 @@ class FirecrawlMetadataManager:
188
196
  "indexed_at": str(len(urls)), # Simple counter
189
197
  }
190
198
 
191
- async def update_metadata(
192
- self, agent_id: str, new_metadata: Dict[str, Any]
193
- ) -> None:
199
+ @staticmethod
200
+ @staticmethod
201
+ async def update_metadata(agent_id: str, new_metadata: dict[str, Any]) -> None:
194
202
  """Update metadata for an agent."""
195
203
  try:
196
204
  metadata_key = f"indexed_urls_{agent_id}"
197
- await self.skill_store.save_agent_skill_data(
198
- agent_id, "web_scraper", metadata_key, new_metadata
205
+ skill_data = AgentSkillDataCreate(
206
+ agent_id=agent_id,
207
+ skill="web_scraper",
208
+ key=metadata_key,
209
+ data=new_metadata,
199
210
  )
211
+ await skill_data.save()
200
212
  except Exception as e:
201
213
  logger.error(f"Error updating metadata for agent {agent_id}: {e}")
202
214
  raise
203
215
 
204
216
 
205
217
  async def index_documents(
206
- documents: List[Document],
218
+ documents: list[Document],
207
219
  agent_id: str,
208
- skill_store: SkillStoreABC,
220
+ vector_manager: FirecrawlVectorStoreManager,
209
221
  chunk_size: int = 1000,
210
222
  chunk_overlap: int = 200,
211
- ) -> Tuple[int, bool]:
223
+ ) -> tuple[int, bool]:
212
224
  """
213
225
  Index documents into the Firecrawl vector store.
214
226
 
215
227
  Args:
216
228
  documents: List of documents to index
217
229
  agent_id: Agent ID for storage
218
- skill_store: Skill store for persistence
230
+ vector_manager: Vector store manager
219
231
  chunk_size: Size of text chunks
220
232
  chunk_overlap: Overlap between chunks
221
233
 
@@ -224,8 +236,6 @@ async def index_documents(
224
236
  """
225
237
  try:
226
238
  # Initialize managers
227
- vs_manager = FirecrawlVectorStoreManager(skill_store)
228
-
229
239
  # Split documents into chunks
230
240
  split_docs = FirecrawlDocumentProcessor.split_documents(
231
241
  documents, chunk_size, chunk_overlap
@@ -236,10 +246,10 @@ async def index_documents(
236
246
  return 0, False
237
247
 
238
248
  # Create embeddings
239
- embeddings = vs_manager.create_embeddings()
249
+ embeddings = vector_manager.create_embeddings()
240
250
 
241
251
  # Try to load existing vector store
242
- existing_vector_store = await vs_manager.load_vector_store(agent_id)
252
+ existing_vector_store = await vector_manager.load_vector_store(agent_id)
243
253
 
244
254
  if existing_vector_store:
245
255
  # Add to existing vector store
@@ -252,7 +262,7 @@ async def index_documents(
252
262
  was_merged = False
253
263
 
254
264
  # Save the vector store
255
- await vs_manager.save_vector_store(
265
+ await vector_manager.save_vector_store(
256
266
  agent_id, vector_store, chunk_size, chunk_overlap
257
267
  )
258
268
 
@@ -269,16 +279,16 @@ async def index_documents(
269
279
  async def query_indexed_content(
270
280
  query: str,
271
281
  agent_id: str,
272
- skill_store: SkillStoreABC,
282
+ vector_manager: FirecrawlVectorStoreManager,
273
283
  max_results: int = 4,
274
- ) -> List[Document]:
284
+ ) -> list[Document]:
275
285
  """
276
286
  Query the Firecrawl indexed content.
277
287
 
278
288
  Args:
279
289
  query: Search query
280
290
  agent_id: Agent ID
281
- skill_store: Skill store for persistence
291
+ vector_manager: Manager for vector store persistence
282
292
  max_results: Maximum number of results to return
283
293
 
284
294
  Returns:
@@ -286,10 +296,8 @@ async def query_indexed_content(
286
296
  """
287
297
  try:
288
298
  # Initialize vector store manager
289
- vs_manager = FirecrawlVectorStoreManager(skill_store)
290
-
291
299
  # Load vector store
292
- vector_store = await vs_manager.load_vector_store(agent_id)
300
+ vector_store = await vector_manager.load_vector_store(agent_id)
293
301
 
294
302
  if not vector_store:
295
303
  logger.warning(f"No vector store found for agent {agent_id}")
@@ -1,6 +1,5 @@
1
1
  from typing import TypedDict
2
2
 
3
- from intentkit.abstracts.skill import SkillStoreABC
4
3
  from intentkit.skills.base import SkillConfig, SkillState
5
4
  from intentkit.skills.github.base import GitHubBaseTool
6
5
  from intentkit.skills.github.github_search import GitHubSearch
@@ -22,7 +21,6 @@ class Config(SkillConfig):
22
21
  async def get_skills(
23
22
  config: "Config",
24
23
  is_private: bool,
25
- store: SkillStoreABC,
26
24
  **_,
27
25
  ) -> list[GitHubBaseTool]:
28
26
  """Get all GitHub skills."""
@@ -36,19 +34,16 @@ async def get_skills(
36
34
  available_skills.append(skill_name)
37
35
 
38
36
  # Get each skill using the cached getter
39
- return [get_github_skill(name, store) for name in available_skills]
37
+ return [get_github_skill(name) for name in available_skills]
40
38
 
41
39
 
42
40
  def get_github_skill(
43
41
  name: str,
44
- store: SkillStoreABC,
45
42
  ) -> GitHubBaseTool:
46
43
  """Get a GitHub skill by name."""
47
44
  if name == "github_search":
48
45
  if name not in _cache:
49
- _cache[name] = GitHubSearch(
50
- skill_store=store,
51
- )
46
+ _cache[name] = GitHubSearch()
52
47
  return _cache[name]
53
48
  else:
54
49
  raise ValueError(f"Unknown GitHub skill: {name}")
@@ -1,8 +1,5 @@
1
- from typing import Type
2
-
3
1
  from pydantic import BaseModel, Field
4
2
 
5
- from intentkit.abstracts.skill import SkillStoreABC
6
3
  from intentkit.skills.base import IntentKitSkill
7
4
 
8
5
 
@@ -11,10 +8,7 @@ class GitHubBaseTool(IntentKitSkill):
11
8
 
12
9
  name: str = Field(description="The name of the tool")
13
10
  description: str = Field(description="A description of what the tool does")
14
- args_schema: Type[BaseModel]
15
- skill_store: SkillStoreABC = Field(
16
- description="The skill store for persisting data"
17
- )
11
+ args_schema: type[BaseModel]
18
12
 
19
13
  @property
20
14
  def category(self) -> str:
@@ -1,6 +1,5 @@
1
1
  import logging
2
2
  from enum import Enum
3
- from typing import Type
4
3
 
5
4
  import httpx
6
5
  from pydantic import BaseModel, Field
@@ -54,7 +53,7 @@ class GitHubSearch(GitHubBaseTool):
54
53
  "- Code snippets across GitHub repositories\n"
55
54
  "You must call this tool whenever the user asks about finding something on GitHub."
56
55
  )
57
- args_schema: Type[BaseModel] = GitHubSearchInput
56
+ args_schema: type[BaseModel] = GitHubSearchInput
58
57
 
59
58
  async def _arun(
60
59
  self,
@@ -5,9 +5,8 @@
5
5
  "description": "Search capabilities for GitHub repositories, users, and code",
6
6
  "x-icon": "https://ai.service.crestal.dev/skills/github/github.jpg",
7
7
  "x-tags": [
8
- "GitHub",
9
- "Search",
10
- "Code"
8
+ "Developer Tools",
9
+ "Search"
11
10
  ],
12
11
  "properties": {
13
12
  "enabled": {
@@ -56,4 +55,4 @@
56
55
  "enabled"
57
56
  ],
58
57
  "additionalProperties": true
59
- }
58
+ }