intentkit 0.8.6.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 (312) 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 +10 -5
  5. intentkit/abstracts/skill.py +6 -144
  6. intentkit/abstracts/twitter.py +4 -5
  7. intentkit/clients/__init__.py +3 -2
  8. intentkit/clients/cdp.py +53 -92
  9. intentkit/clients/twitter.py +56 -57
  10. intentkit/clients/web3.py +1 -3
  11. intentkit/config/config.py +5 -0
  12. intentkit/core/agent.py +16 -388
  13. intentkit/core/asset.py +64 -18
  14. intentkit/core/client.py +1 -1
  15. intentkit/core/credit.py +19 -20
  16. intentkit/core/engine.py +26 -11
  17. intentkit/core/node.py +2 -1
  18. intentkit/core/prompt.py +53 -15
  19. intentkit/core/scheduler.py +9 -9
  20. intentkit/core/statistics.py +6 -7
  21. intentkit/models/agent.py +256 -176
  22. intentkit/models/agent_data.py +62 -36
  23. intentkit/models/agent_schema.json +6 -9
  24. intentkit/models/app_setting.py +6 -6
  25. intentkit/models/chat.py +28 -24
  26. intentkit/models/conversation.py +8 -8
  27. intentkit/models/credit.py +62 -64
  28. intentkit/models/db.py +8 -7
  29. intentkit/models/db_mig.py +2 -2
  30. intentkit/models/llm.csv +15 -12
  31. intentkit/models/llm.py +18 -16
  32. intentkit/models/redis.py +2 -3
  33. intentkit/models/skill.py +62 -66
  34. intentkit/models/skills.csv +30 -26
  35. intentkit/models/user.py +46 -21
  36. intentkit/skills/acolyt/__init__.py +2 -9
  37. intentkit/skills/acolyt/ask.py +3 -4
  38. intentkit/skills/acolyt/base.py +4 -9
  39. intentkit/skills/aixbt/__init__.py +2 -13
  40. intentkit/skills/aixbt/base.py +1 -7
  41. intentkit/skills/aixbt/projects.py +14 -15
  42. intentkit/skills/allora/__init__.py +2 -9
  43. intentkit/skills/allora/base.py +4 -9
  44. intentkit/skills/allora/price.py +3 -4
  45. intentkit/skills/base.py +175 -52
  46. intentkit/skills/basename/__init__.py +4 -8
  47. intentkit/skills/carv/__init__.py +115 -121
  48. intentkit/skills/carv/base.py +184 -185
  49. intentkit/skills/carv/fetch_news.py +3 -3
  50. intentkit/skills/carv/onchain_query.py +4 -4
  51. intentkit/skills/carv/token_info_and_price.py +5 -5
  52. intentkit/skills/casino/__init__.py +4 -15
  53. intentkit/skills/casino/base.py +1 -7
  54. intentkit/skills/casino/deck_draw.py +5 -8
  55. intentkit/skills/casino/deck_shuffle.py +6 -6
  56. intentkit/skills/casino/dice_roll.py +2 -4
  57. intentkit/skills/cdp/__init__.py +3 -10
  58. intentkit/skills/cdp/base.py +1 -7
  59. intentkit/skills/cdp/schema.json +1 -17
  60. intentkit/skills/chainlist/__init__.py +2 -7
  61. intentkit/skills/chainlist/base.py +1 -7
  62. intentkit/skills/chainlist/chain_lookup.py +18 -18
  63. intentkit/skills/common/__init__.py +2 -9
  64. intentkit/skills/common/base.py +1 -7
  65. intentkit/skills/common/current_time.py +1 -2
  66. intentkit/skills/cookiefun/__init__.py +6 -9
  67. intentkit/skills/cookiefun/base.py +2 -7
  68. intentkit/skills/cookiefun/get_account_details.py +7 -7
  69. intentkit/skills/cookiefun/get_account_feed.py +19 -19
  70. intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
  71. intentkit/skills/cookiefun/get_sectors.py +3 -3
  72. intentkit/skills/cookiefun/search_accounts.py +9 -9
  73. intentkit/skills/cryptocompare/__init__.py +7 -24
  74. intentkit/skills/cryptocompare/api.py +2 -3
  75. intentkit/skills/cryptocompare/base.py +10 -24
  76. intentkit/skills/cryptocompare/fetch_news.py +4 -5
  77. intentkit/skills/cryptocompare/fetch_price.py +6 -7
  78. intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
  79. intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
  80. intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
  81. intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
  82. intentkit/skills/cryptopanic/__init__.py +7 -10
  83. intentkit/skills/cryptopanic/base.py +51 -55
  84. intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
  85. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
  86. intentkit/skills/dapplooker/__init__.py +2 -9
  87. intentkit/skills/dapplooker/base.py +4 -9
  88. intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
  89. intentkit/skills/defillama/__init__.py +24 -74
  90. intentkit/skills/defillama/api.py +6 -9
  91. intentkit/skills/defillama/base.py +8 -19
  92. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
  93. intentkit/skills/defillama/coins/fetch_block.py +6 -8
  94. intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
  95. intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
  96. intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
  97. intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
  98. intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
  99. intentkit/skills/defillama/config/chains.py +1 -3
  100. intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
  101. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
  102. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
  103. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
  104. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
  105. intentkit/skills/defillama/tests/api_integration.test.py +1 -1
  106. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
  107. intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
  108. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
  109. intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
  110. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
  111. intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
  112. intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
  113. intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
  114. intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
  115. intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
  116. intentkit/skills/defillama/yields/fetch_pools.py +26 -30
  117. intentkit/skills/dexscreener/__init__.py +97 -102
  118. intentkit/skills/dexscreener/base.py +125 -130
  119. intentkit/skills/dexscreener/get_pair_info.py +4 -5
  120. intentkit/skills/dexscreener/get_token_pairs.py +4 -5
  121. intentkit/skills/dexscreener/get_tokens_info.py +7 -8
  122. intentkit/skills/dexscreener/model/search_token_response.py +80 -82
  123. intentkit/skills/dexscreener/search_token.py +182 -184
  124. intentkit/skills/dexscreener/utils.py +15 -14
  125. intentkit/skills/dune_analytics/__init__.py +7 -9
  126. intentkit/skills/dune_analytics/base.py +48 -52
  127. intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
  128. intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
  129. intentkit/skills/elfa/__init__.py +5 -18
  130. intentkit/skills/elfa/base.py +10 -14
  131. intentkit/skills/elfa/mention.py +19 -21
  132. intentkit/skills/elfa/stats.py +4 -4
  133. intentkit/skills/elfa/tokens.py +12 -12
  134. intentkit/skills/elfa/utils.py +26 -28
  135. intentkit/skills/enso/__init__.py +11 -31
  136. intentkit/skills/enso/base.py +9 -15
  137. intentkit/skills/enso/best_yield.py +5 -7
  138. intentkit/skills/enso/networks.py +3 -9
  139. intentkit/skills/enso/prices.py +2 -4
  140. intentkit/skills/enso/route.py +6 -12
  141. intentkit/skills/enso/tokens.py +4 -16
  142. intentkit/skills/enso/wallet.py +6 -6
  143. intentkit/skills/erc20/__init__.py +5 -11
  144. intentkit/skills/erc721/__init__.py +5 -9
  145. intentkit/skills/firecrawl/__init__.py +5 -18
  146. intentkit/skills/firecrawl/base.py +4 -9
  147. intentkit/skills/firecrawl/clear.py +4 -8
  148. intentkit/skills/firecrawl/crawl.py +19 -19
  149. intentkit/skills/firecrawl/query.py +4 -3
  150. intentkit/skills/firecrawl/scrape.py +17 -22
  151. intentkit/skills/firecrawl/utils.py +50 -42
  152. intentkit/skills/github/__init__.py +2 -7
  153. intentkit/skills/github/base.py +1 -7
  154. intentkit/skills/github/github_search.py +1 -2
  155. intentkit/skills/heurist/__init__.py +8 -27
  156. intentkit/skills/heurist/base.py +4 -9
  157. intentkit/skills/heurist/image_generation_animagine_xl.py +12 -13
  158. intentkit/skills/heurist/image_generation_arthemy_comics.py +12 -13
  159. intentkit/skills/heurist/image_generation_arthemy_real.py +12 -13
  160. intentkit/skills/heurist/image_generation_braindance.py +12 -13
  161. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +12 -13
  162. intentkit/skills/heurist/image_generation_flux_1_dev.py +12 -13
  163. intentkit/skills/heurist/image_generation_sdxl.py +12 -13
  164. intentkit/skills/http/__init__.py +4 -15
  165. intentkit/skills/http/base.py +1 -7
  166. intentkit/skills/http/get.py +21 -16
  167. intentkit/skills/http/post.py +23 -18
  168. intentkit/skills/http/put.py +23 -18
  169. intentkit/skills/lifi/__init__.py +5 -10
  170. intentkit/skills/lifi/base.py +1 -7
  171. intentkit/skills/lifi/token_execute.py +14 -17
  172. intentkit/skills/lifi/token_quote.py +7 -9
  173. intentkit/skills/lifi/utils.py +16 -16
  174. intentkit/skills/moralis/__init__.py +6 -10
  175. intentkit/skills/moralis/api.py +6 -7
  176. intentkit/skills/moralis/base.py +5 -10
  177. intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
  178. intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
  179. intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
  180. intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
  181. intentkit/skills/morpho/__init__.py +5 -9
  182. intentkit/skills/nation/__init__.py +4 -9
  183. intentkit/skills/nation/base.py +5 -10
  184. intentkit/skills/nation/nft_check.py +3 -4
  185. intentkit/skills/onchain.py +23 -0
  186. intentkit/skills/openai/__init__.py +17 -18
  187. intentkit/skills/openai/base.py +10 -14
  188. intentkit/skills/openai/dalle_image_generation.py +3 -8
  189. intentkit/skills/openai/gpt_avatar_generator.py +102 -0
  190. intentkit/skills/openai/gpt_image_generation.py +4 -8
  191. intentkit/skills/openai/gpt_image_mini_generator.py +91 -0
  192. intentkit/skills/openai/gpt_image_to_image.py +4 -8
  193. intentkit/skills/openai/image_to_text.py +3 -7
  194. intentkit/skills/openai/schema.json +32 -0
  195. intentkit/skills/portfolio/__init__.py +11 -35
  196. intentkit/skills/portfolio/base.py +33 -19
  197. intentkit/skills/portfolio/token_balances.py +21 -21
  198. intentkit/skills/portfolio/wallet_approvals.py +17 -18
  199. intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
  200. intentkit/skills/portfolio/wallet_history.py +31 -31
  201. intentkit/skills/portfolio/wallet_net_worth.py +13 -13
  202. intentkit/skills/portfolio/wallet_nfts.py +19 -19
  203. intentkit/skills/portfolio/wallet_profitability.py +18 -18
  204. intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
  205. intentkit/skills/portfolio/wallet_stats.py +3 -3
  206. intentkit/skills/portfolio/wallet_swaps.py +19 -19
  207. intentkit/skills/pyth/__init__.py +4 -10
  208. intentkit/skills/skills.toml +4 -0
  209. intentkit/skills/slack/__init__.py +5 -17
  210. intentkit/skills/slack/base.py +3 -9
  211. intentkit/skills/slack/get_channel.py +8 -8
  212. intentkit/skills/slack/get_message.py +9 -9
  213. intentkit/skills/slack/schedule_message.py +5 -5
  214. intentkit/skills/slack/send_message.py +3 -5
  215. intentkit/skills/supabase/__init__.py +7 -23
  216. intentkit/skills/supabase/base.py +1 -7
  217. intentkit/skills/supabase/delete_data.py +4 -4
  218. intentkit/skills/supabase/fetch_data.py +12 -12
  219. intentkit/skills/supabase/insert_data.py +4 -4
  220. intentkit/skills/supabase/invoke_function.py +6 -6
  221. intentkit/skills/supabase/update_data.py +6 -6
  222. intentkit/skills/supabase/upsert_data.py +4 -4
  223. intentkit/skills/superfluid/__init__.py +5 -9
  224. intentkit/skills/system/__init__.py +7 -24
  225. intentkit/skills/system/add_autonomous_task.py +10 -12
  226. intentkit/skills/system/delete_autonomous_task.py +2 -2
  227. intentkit/skills/system/edit_autonomous_task.py +14 -18
  228. intentkit/skills/system/list_autonomous_tasks.py +3 -5
  229. intentkit/skills/system/read_agent_api_key.py +6 -4
  230. intentkit/skills/system/regenerate_agent_api_key.py +6 -4
  231. intentkit/skills/tavily/__init__.py +3 -12
  232. intentkit/skills/tavily/base.py +4 -9
  233. intentkit/skills/tavily/tavily_extract.py +2 -4
  234. intentkit/skills/tavily/tavily_search.py +4 -6
  235. intentkit/skills/token/__init__.py +5 -10
  236. intentkit/skills/token/base.py +7 -11
  237. intentkit/skills/token/erc20_transfers.py +19 -19
  238. intentkit/skills/token/token_analytics.py +3 -3
  239. intentkit/skills/token/token_price.py +13 -13
  240. intentkit/skills/token/token_search.py +9 -9
  241. intentkit/skills/twitter/__init__.py +11 -35
  242. intentkit/skills/twitter/base.py +22 -34
  243. intentkit/skills/twitter/follow_user.py +2 -6
  244. intentkit/skills/twitter/get_mentions.py +5 -12
  245. intentkit/skills/twitter/get_timeline.py +4 -12
  246. intentkit/skills/twitter/get_user_by_username.py +2 -6
  247. intentkit/skills/twitter/get_user_tweets.py +5 -13
  248. intentkit/skills/twitter/like_tweet.py +2 -6
  249. intentkit/skills/twitter/post_tweet.py +6 -9
  250. intentkit/skills/twitter/reply_tweet.py +6 -9
  251. intentkit/skills/twitter/retweet.py +2 -6
  252. intentkit/skills/twitter/search_tweets.py +4 -12
  253. intentkit/skills/unrealspeech/__init__.py +2 -7
  254. intentkit/skills/unrealspeech/base.py +2 -8
  255. intentkit/skills/unrealspeech/text_to_speech.py +8 -8
  256. intentkit/skills/venice_audio/__init__.py +98 -106
  257. intentkit/skills/venice_audio/base.py +117 -121
  258. intentkit/skills/venice_audio/input.py +41 -41
  259. intentkit/skills/venice_audio/venice_audio.py +7 -11
  260. intentkit/skills/venice_image/__init__.py +147 -154
  261. intentkit/skills/venice_image/api.py +138 -138
  262. intentkit/skills/venice_image/base.py +185 -192
  263. intentkit/skills/venice_image/config.py +33 -35
  264. intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
  265. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
  266. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
  267. intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
  268. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
  269. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
  270. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
  271. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
  272. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
  273. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
  274. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
  275. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
  276. intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
  277. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
  278. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
  279. intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
  280. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
  281. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
  282. intentkit/skills/venice_image/utils.py +77 -78
  283. intentkit/skills/web_scraper/__init__.py +5 -18
  284. intentkit/skills/web_scraper/base.py +21 -7
  285. intentkit/skills/web_scraper/document_indexer.py +7 -6
  286. intentkit/skills/web_scraper/scrape_and_index.py +15 -15
  287. intentkit/skills/web_scraper/utils.py +62 -63
  288. intentkit/skills/web_scraper/website_indexer.py +17 -19
  289. intentkit/skills/weth/__init__.py +5 -11
  290. intentkit/skills/wow/__init__.py +5 -11
  291. intentkit/skills/x402/__init__.py +61 -0
  292. intentkit/skills/x402/ask_agent.py +98 -0
  293. intentkit/skills/x402/base.py +99 -0
  294. intentkit/skills/x402/http_request.py +117 -0
  295. intentkit/skills/x402/schema.json +45 -0
  296. intentkit/skills/x402/x402.webp +0 -0
  297. intentkit/skills/xmtp/__init__.py +4 -15
  298. intentkit/skills/xmtp/base.py +5 -5
  299. intentkit/skills/xmtp/price.py +6 -6
  300. intentkit/skills/xmtp/swap.py +6 -8
  301. intentkit/skills/xmtp/transfer.py +4 -6
  302. intentkit/utils/error.py +2 -2
  303. intentkit/utils/logging.py +2 -4
  304. intentkit/utils/s3.py +8 -9
  305. intentkit/utils/schema.py +100 -0
  306. intentkit/utils/slack_alert.py +7 -8
  307. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +3 -4
  308. intentkit-0.8.17.dist-info/RECORD +466 -0
  309. intentkit/models/generator.py +0 -347
  310. intentkit-0.8.6.dev2.dist-info/RECORD +0 -457
  311. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
  312. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
@@ -1,28 +1,28 @@
1
- from intentkit.skills.venice_image.image_generation.image_generation_base import (
2
- VeniceImageGenerationBaseTool,
3
- )
4
- from intentkit.skills.venice_image.image_generation.image_generation_input import (
5
- STYLE_PRESETS,
6
- )
7
-
8
-
9
- class ImageGenerationVeniceSD35(VeniceImageGenerationBaseTool):
10
- """
11
- Tool for generating images using Venice AI's interface to Stable Diffusion 3.5 Large.
12
- Developed by Stability AI, using MMDiT architecture. Good for art and design.
13
- """
14
-
15
- # --- Model Specific Configuration ---
16
- name: str = "venice_image_generation_venice_sd35"
17
- description: str = (
18
- "Generate images using Stability AI's Stable Diffusion 3.5 Large model (via Venice AI).\n"
19
- "Ideal for artworks, design processes, and educational use. Not for factual representations.\n"
20
- "Provide a text prompt describing the image (up to 1500 chars).\n"
21
- f"Optionally specify a style preset from the list: {', '.join(STYLE_PRESETS)}.\n"
22
- "Supports dimensions up to 2048x2048 (multiple of 16).\n"
23
- "Use must comply with Stability AI's Acceptable Use Policy."
24
- )
25
- # Use the specific ID provided by Venice, assuming it matches the name
26
- model_id: str = "venice-sd35"
27
-
28
- # args_schema and _arun are inherited from VeniceImageGenerationBaseTool
1
+ from intentkit.skills.venice_image.image_generation.image_generation_base import (
2
+ VeniceImageGenerationBaseTool,
3
+ )
4
+ from intentkit.skills.venice_image.image_generation.image_generation_input import (
5
+ STYLE_PRESETS,
6
+ )
7
+
8
+
9
+ class ImageGenerationVeniceSD35(VeniceImageGenerationBaseTool):
10
+ """
11
+ Tool for generating images using Venice AI's interface to Stable Diffusion 3.5 Large.
12
+ Developed by Stability AI, using MMDiT architecture. Good for art and design.
13
+ """
14
+
15
+ # --- Model Specific Configuration ---
16
+ name: str = "venice_image_generation_venice_sd35"
17
+ description: str = (
18
+ "Generate images using Stability AI's Stable Diffusion 3.5 Large model (via Venice AI).\n"
19
+ "Ideal for artworks, design processes, and educational use. Not for factual representations.\n"
20
+ "Provide a text prompt describing the image (up to 1500 chars).\n"
21
+ f"Optionally specify a style preset from the list: {', '.join(STYLE_PRESETS)}.\n"
22
+ "Supports dimensions up to 2048x2048 (multiple of 16).\n"
23
+ "Use must comply with Stability AI's Acceptable Use Policy."
24
+ )
25
+ # Use the specific ID provided by Venice, assuming it matches the name
26
+ model_id: str = "venice-sd35"
27
+
28
+ # args_schema and _arun are inherited from VeniceImageGenerationBaseTool
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Literal, Optional
2
+ from typing import Literal
3
3
 
4
4
  from pydantic import HttpUrl
5
5
 
@@ -32,7 +32,7 @@ class ImageUpscale(VeniceImageUpscaleBaseTool):
32
32
  self,
33
33
  image_url: HttpUrl,
34
34
  scale: Literal[2, 4],
35
- replication: Optional[float] = 0.35,
35
+ replication: float | None = 0.35,
36
36
  **kwargs,
37
37
  ) -> dict:
38
38
  """
@@ -41,7 +41,7 @@ class ImageUpscale(VeniceImageUpscaleBaseTool):
41
41
  Args:
42
42
  image_url (HttpUrl): The public URL of the image to upscale.
43
43
  scale (Literal[2, 4]): The scale factor for upscaling (2x or 4x).
44
- replication (Optional[float]): The replication factor for the upscale process, defaults to 0.35.
44
+ replication (float | None): The replication factor for the upscale process, defaults to 0.35.
45
45
  config (RunnableConfig, optional): Configuration for the runnable, if any.
46
46
  **kwargs: Additional keyword arguments.
47
47
 
@@ -1,23 +1,21 @@
1
- from typing import Type
2
-
3
- from pydantic import BaseModel, Field
4
-
5
- # Import the generic base and shared input
6
- from intentkit.skills.venice_image.base import VeniceImageBaseTool
7
- from intentkit.skills.venice_image.image_upscale.image_upscale_input import (
8
- VeniceImageUpscaleInput,
9
- )
10
-
11
-
12
- class VeniceImageUpscaleBaseTool(VeniceImageBaseTool):
13
- """
14
- Base class for Venice AI *Image Upscaling* tools.
15
- Inherits from VeniceAIBaseTool and handles specifics of the
16
- /image/upscale endpoint
17
- """
18
-
19
- args_schema: Type[BaseModel] = VeniceImageUpscaleInput
20
- name: str = Field(description="The unique name of the image upscaling tool.")
21
- description: str = Field(
22
- description="A description of what the image upscaling tool does."
23
- )
1
+ from pydantic import BaseModel, Field
2
+
3
+ # Import the generic base and shared input
4
+ from intentkit.skills.venice_image.base import VeniceImageBaseTool
5
+ from intentkit.skills.venice_image.image_upscale.image_upscale_input import (
6
+ VeniceImageUpscaleInput,
7
+ )
8
+
9
+
10
+ class VeniceImageUpscaleBaseTool(VeniceImageBaseTool):
11
+ """
12
+ Base class for Venice AI *Image Upscaling* tools.
13
+ Inherits from VeniceAIBaseTool and handles specifics of the
14
+ /image/upscale endpoint
15
+ """
16
+
17
+ args_schema: type[BaseModel] = VeniceImageUpscaleInput
18
+ name: str = Field(description="The unique name of the image upscaling tool.")
19
+ description: str = Field(
20
+ description="A description of what the image upscaling tool does."
21
+ )
@@ -1,22 +1,22 @@
1
- from typing import Literal, Optional
2
-
3
- from pydantic import BaseModel, Field, HttpUrl
4
-
5
-
6
- class VeniceImageUpscaleInput(BaseModel):
7
- """Input for the Image Upscale tool."""
8
-
9
- image_url: HttpUrl = Field(
10
- description="The URL of the image to upscale. Must be a publicly accessible URL.",
11
- )
12
- replication: Optional[float] = Field(
13
- default=0.35,
14
- description=(
15
- 'How strongly lines and noise in the base image are preserved. Higher values are noisier but less plastic/AI "generated"/hallucinated. Must be between 0.1 and 1.'
16
- "Required range: 0.1 <= x <= 1"
17
- ),
18
- )
19
- scale: Literal[2, 4] = Field(
20
- default=2,
21
- description="The factor by which to upscale the image (either 2 or 4). Defaults to 2.",
22
- )
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel, Field, HttpUrl
4
+
5
+
6
+ class VeniceImageUpscaleInput(BaseModel):
7
+ """Input for the Image Upscale tool."""
8
+
9
+ image_url: HttpUrl = Field(
10
+ description="The URL of the image to upscale. Must be a publicly accessible URL.",
11
+ )
12
+ replication: float | None = Field(
13
+ default=0.35,
14
+ description=(
15
+ 'How strongly lines and noise in the base image are preserved. Higher values are noisier but less plastic/AI "generated"/hallucinated. Must be between 0.1 and 1.'
16
+ "Required range: 0.1 <= x <= 1"
17
+ ),
18
+ )
19
+ scale: Literal[2, 4] = Field(
20
+ default=2,
21
+ description="The factor by which to upscale the image (either 2 or 4). Defaults to 2.",
22
+ )
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Type
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, HttpUrl
5
5
 
@@ -27,7 +27,7 @@ class ImageVision(VeniceImageVisionBaseTool):
27
27
  "Provide the public URL of the image to describe.\n"
28
28
  "Returns a descriptive text of the image."
29
29
  )
30
- args_schema: Type[BaseModel] = VeniceImageVision
30
+ args_schema: type[BaseModel] = VeniceImageVision
31
31
  # No model_id needed for the generic vision endpoint currently
32
32
 
33
33
  async def _arun(
@@ -1,17 +1,17 @@
1
- from pydantic import Field
2
-
3
- # Import the generic base and shared input
4
- from intentkit.skills.venice_image.base import VeniceImageBaseTool
5
-
6
-
7
- class VeniceImageVisionBaseTool(VeniceImageBaseTool):
8
- """
9
- Base class for Venice AI *Image Vision* tools.
10
- Inherits from VeniceAIBaseTool and handles specifics of the
11
- /chat/completions endpoint.
12
- """
13
-
14
- name: str = Field(description="The unique name of the image vision tool.")
15
- description: str = Field(
16
- description="A description of what the image vision tool does."
17
- )
1
+ from pydantic import Field
2
+
3
+ # Import the generic base and shared input
4
+ from intentkit.skills.venice_image.base import VeniceImageBaseTool
5
+
6
+
7
+ class VeniceImageVisionBaseTool(VeniceImageBaseTool):
8
+ """
9
+ Base class for Venice AI *Image Vision* tools.
10
+ Inherits from VeniceAIBaseTool and handles specifics of the
11
+ /chat/completions endpoint.
12
+ """
13
+
14
+ name: str = Field(description="The unique name of the image vision tool.")
15
+ description: str = Field(
16
+ description="A description of what the image vision tool does."
17
+ )
@@ -1,9 +1,9 @@
1
- from pydantic import BaseModel, Field, HttpUrl
2
-
3
-
4
- class VeniceImageVision(BaseModel):
5
- """Input for the Image Vision tool."""
6
-
7
- image_url: HttpUrl = Field(
8
- description="The URL of the image to to be described by the Vision model. Must be a publicly accessible URL.",
9
- )
1
+ from pydantic import BaseModel, Field, HttpUrl
2
+
3
+
4
+ class VeniceImageVision(BaseModel):
5
+ """Input for the Image Vision tool."""
6
+
7
+ image_url: HttpUrl = Field(
8
+ description="The URL of the image to to be described by the Vision model. Must be a publicly accessible URL.",
9
+ )
@@ -1,78 +1,77 @@
1
- import base64
2
- import io
3
- import logging
4
- from typing import Optional
5
-
6
- import filetype
7
- import httpx
8
- from PIL import Image
9
- from pydantic import HttpUrl
10
-
11
- from intentkit.skills.base import ToolException
12
-
13
- logger = logging.getLogger(__name__)
14
-
15
-
16
- async def fetch_image_as_bytes(image_url: HttpUrl) -> bytes:
17
- """Fetches image bytes from a given URL. Converts unsupported formats to PNG using Pillow.
18
-
19
- Raises:
20
- ToolException: If fetching or converting the image fails.
21
- """
22
- try:
23
- async with httpx.AsyncClient(timeout=90) as client:
24
- response = await client.get(str(image_url), follow_redirects=True)
25
- response.raise_for_status()
26
-
27
- original_bytes = response.content
28
-
29
- # Guess file type from content
30
- kind = filetype.guess(original_bytes)
31
- detected_ext = kind.extension if kind else None
32
- detected_mime = kind.mime if kind else "unknown"
33
-
34
- if not detected_ext or not detected_mime.startswith("image/"):
35
- msg = f"URL {image_url} did not return a recognizable image format. Detected: {detected_mime}"
36
- logger.error(msg)
37
- raise ToolException(msg)
38
-
39
- if detected_ext in ("jpg", "jpeg", "png"):
40
- return original_bytes
41
-
42
- # Convert unsupported image to PNG
43
- try:
44
- img = Image.open(io.BytesIO(original_bytes)).convert("RGBA")
45
- with io.BytesIO() as output:
46
- img.save(output, format="PNG")
47
- logger.info(
48
- f"Converted unsupported image type '{detected_ext}' to PNG."
49
- )
50
- return output.getvalue()
51
- except Exception as e:
52
- msg = f"Failed to convert image ({detected_ext}) to PNG: {e}"
53
- logger.error(msg, exc_info=True)
54
- raise ToolException(msg) from e
55
-
56
- except httpx.HTTPStatusError as e:
57
- msg = f"HTTP error fetching image {image_url}: Status {e.response.status_code}"
58
- logger.error(msg)
59
- raise ToolException(msg) from e
60
- except httpx.RequestError as e:
61
- msg = f"Network error fetching image {image_url}: {e}"
62
- logger.error(msg)
63
- raise ToolException(msg) from e
64
- except Exception as e:
65
- msg = f"Unexpected error fetching image {image_url}: {e}"
66
- logger.error(msg, exc_info=True)
67
- raise ToolException(msg) from e
68
-
69
-
70
- async def fetch_image_as_base64(image_url: HttpUrl) -> Optional[str]:
71
- """Fetches an image from the URL and returns the image as a Base64-encoded string."""
72
- image_bytes = await fetch_image_as_bytes(image_url)
73
-
74
- if image_bytes is None:
75
- return None
76
-
77
- # Convert image bytes to a Base64-encoded string
78
- return base64.b64encode(image_bytes).decode("utf-8")
1
+ import base64
2
+ import io
3
+ import logging
4
+
5
+ import filetype
6
+ import httpx
7
+ from PIL import Image
8
+ from pydantic import HttpUrl
9
+
10
+ from intentkit.skills.base import ToolException
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ async def fetch_image_as_bytes(image_url: HttpUrl) -> bytes:
16
+ """Fetches image bytes from a given URL. Converts unsupported formats to PNG using Pillow.
17
+
18
+ Raises:
19
+ ToolException: If fetching or converting the image fails.
20
+ """
21
+ try:
22
+ async with httpx.AsyncClient(timeout=90) as client:
23
+ response = await client.get(str(image_url), follow_redirects=True)
24
+ response.raise_for_status()
25
+
26
+ original_bytes = response.content
27
+
28
+ # Guess file type from content
29
+ kind = filetype.guess(original_bytes)
30
+ detected_ext = kind.extension if kind else None
31
+ detected_mime = kind.mime if kind else "unknown"
32
+
33
+ if not detected_ext or not detected_mime.startswith("image/"):
34
+ msg = f"URL {image_url} did not return a recognizable image format. Detected: {detected_mime}"
35
+ logger.error(msg)
36
+ raise ToolException(msg)
37
+
38
+ if detected_ext in ("jpg", "jpeg", "png"):
39
+ return original_bytes
40
+
41
+ # Convert unsupported image to PNG
42
+ try:
43
+ img = Image.open(io.BytesIO(original_bytes)).convert("RGBA")
44
+ with io.BytesIO() as output:
45
+ img.save(output, format="PNG")
46
+ logger.info(
47
+ f"Converted unsupported image type '{detected_ext}' to PNG."
48
+ )
49
+ return output.getvalue()
50
+ except Exception as e:
51
+ msg = f"Failed to convert image ({detected_ext}) to PNG: {e}"
52
+ logger.error(msg, exc_info=True)
53
+ raise ToolException(msg) from e
54
+
55
+ except httpx.HTTPStatusError as e:
56
+ msg = f"HTTP error fetching image {image_url}: Status {e.response.status_code}"
57
+ logger.error(msg)
58
+ raise ToolException(msg) from e
59
+ except httpx.RequestError as e:
60
+ msg = f"Network error fetching image {image_url}: {e}"
61
+ logger.error(msg)
62
+ raise ToolException(msg) from e
63
+ except Exception as e:
64
+ msg = f"Unexpected error fetching image {image_url}: {e}"
65
+ logger.error(msg, exc_info=True)
66
+ raise ToolException(msg) from e
67
+
68
+
69
+ async def fetch_image_as_base64(image_url: HttpUrl) -> str | None:
70
+ """Fetches an image from the URL and returns the image as a Base64-encoded string."""
71
+ image_bytes = await fetch_image_as_bytes(image_url)
72
+
73
+ if image_bytes is None:
74
+ return None
75
+
76
+ # Convert image bytes to a Base64-encoded string
77
+ return base64.b64encode(image_bytes).decode("utf-8")
@@ -3,7 +3,6 @@
3
3
  import logging
4
4
  from typing import TypedDict
5
5
 
6
- from intentkit.abstracts.skill import SkillStoreABC
7
6
  from intentkit.skills.base import SkillConfig, SkillOwnerState, SkillState
8
7
  from intentkit.skills.web_scraper.base import WebScraperBaseTool
9
8
  from intentkit.skills.web_scraper.document_indexer import DocumentIndexer
@@ -35,7 +34,6 @@ class Config(SkillConfig):
35
34
  async def get_skills(
36
35
  config: "Config",
37
36
  is_private: bool,
38
- store: SkillStoreABC,
39
37
  **_,
40
38
  ) -> list[WebScraperBaseTool]:
41
39
  """Get all web scraper skills.
@@ -43,7 +41,6 @@ async def get_skills(
43
41
  Args:
44
42
  config: The configuration for web scraper skills.
45
43
  is_private: Whether to include private skills.
46
- store: The skill store for persisting data.
47
44
 
48
45
  Returns:
49
46
  A list of web scraper skills.
@@ -60,7 +57,7 @@ async def get_skills(
60
57
  # Get each skill using the cached getter
61
58
  result = []
62
59
  for name in available_skills:
63
- skill = get_web_scraper_skill(name, store)
60
+ skill = get_web_scraper_skill(name)
64
61
  if skill:
65
62
  result.append(skill)
66
63
  return result
@@ -68,40 +65,30 @@ async def get_skills(
68
65
 
69
66
  def get_web_scraper_skill(
70
67
  name: str,
71
- store: SkillStoreABC,
72
68
  ) -> WebScraperBaseTool:
73
69
  """Get a web scraper skill by name.
74
70
 
75
71
  Args:
76
72
  name: The name of the skill to get
77
- store: The skill store for persisting data
78
73
 
79
74
  Returns:
80
75
  The requested web scraper skill
81
76
  """
82
77
  if name == "scrape_and_index":
83
78
  if name not in _cache:
84
- _cache[name] = ScrapeAndIndex(
85
- skill_store=store,
86
- )
79
+ _cache[name] = ScrapeAndIndex()
87
80
  return _cache[name]
88
81
  elif name == "query_indexed_content":
89
82
  if name not in _cache:
90
- _cache[name] = QueryIndexedContent(
91
- skill_store=store,
92
- )
83
+ _cache[name] = QueryIndexedContent()
93
84
  return _cache[name]
94
85
  elif name == "website_indexer":
95
86
  if name not in _cache:
96
- _cache[name] = WebsiteIndexer(
97
- skill_store=store,
98
- )
87
+ _cache[name] = WebsiteIndexer()
99
88
  return _cache[name]
100
89
  elif name == "document_indexer":
101
90
  if name not in _cache:
102
- _cache[name] = DocumentIndexer(
103
- skill_store=store,
104
- )
91
+ _cache[name] = DocumentIndexer()
105
92
  return _cache[name]
106
93
  else:
107
94
  logger.warning(f"Unknown web scraper skill: {name}")
@@ -1,8 +1,7 @@
1
- from typing import Type
2
-
1
+ from langchain_core.tools.base import ToolException
3
2
  from pydantic import BaseModel, Field
4
3
 
5
- from intentkit.abstracts.skill import SkillStoreABC
4
+ from intentkit.config.config import config
6
5
  from intentkit.skills.base import IntentKitSkill
7
6
 
8
7
 
@@ -11,11 +10,26 @@ class WebScraperBaseTool(IntentKitSkill):
11
10
 
12
11
  name: str = Field(description="The name of the tool")
13
12
  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
- )
13
+ args_schema: type[BaseModel]
18
14
 
19
15
  @property
20
16
  def category(self) -> str:
21
17
  return "web_scraper"
18
+
19
+ def get_openai_api_key(self) -> str:
20
+ """Retrieve the OpenAI API key for embedding operations."""
21
+ context = self.get_context()
22
+ skill_config = context.agent.skill_config(self.category)
23
+ api_key_provider = skill_config.get("api_key_provider")
24
+
25
+ if api_key_provider == "platform":
26
+ if not config.openai_api_key:
27
+ raise ToolException("OpenAI API key is not configured")
28
+ return config.openai_api_key
29
+
30
+ if skill_config.get("api_key"):
31
+ return skill_config["api_key"]
32
+
33
+ raise ToolException(
34
+ f"Invalid API key provider: {api_key_provider}, or no api_key in config"
35
+ )
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import Type
3
2
 
4
3
  from pydantic import BaseModel, Field
5
4
 
@@ -65,7 +64,7 @@ class DocumentIndexer(WebScraperBaseTool):
65
64
  "Perfect for adding content from Google Docs, Notion pages, PDFs, or any other document sources. "
66
65
  "The indexed content can then be queried using the query_indexed_content tool."
67
66
  )
68
- args_schema: Type[BaseModel] = DocumentIndexerInput
67
+ args_schema: type[BaseModel] = DocumentIndexerInput
69
68
 
70
69
  async def _arun(
71
70
  self,
@@ -108,17 +107,19 @@ class DocumentIndexer(WebScraperBaseTool):
108
107
  f"[{agent_id}] Document created, length: {len(document.page_content)} chars"
109
108
  )
110
109
 
110
+ embedding_api_key = self.get_openai_api_key()
111
+ vector_manager = VectorStoreManager(embedding_api_key)
112
+
111
113
  # Index the document
112
114
  total_chunks, was_merged = await index_documents(
113
- [document], agent_id, self.skill_store, chunk_size, chunk_overlap
115
+ [document], agent_id, vector_manager, chunk_size, chunk_overlap
114
116
  )
115
117
 
116
118
  # Get current storage size for response
117
- vs_manager = VectorStoreManager(self.skill_store)
118
- current_size = await vs_manager.get_content_size(agent_id)
119
+ current_size = await vector_manager.get_content_size(agent_id)
119
120
 
120
121
  # Update metadata
121
- metadata_manager = MetadataManager(self.skill_store)
122
+ metadata_manager = MetadataManager(vector_manager)
122
123
  new_metadata = metadata_manager.create_document_metadata(
123
124
  title, source, tags, [document], len(text_content)
124
125
  )
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import List, Type
3
2
 
4
3
  from pydantic import BaseModel, Field
5
4
 
@@ -19,7 +18,7 @@ logger = logging.getLogger(__name__)
19
18
  class ScrapeAndIndexInput(BaseModel):
20
19
  """Input for ScrapeAndIndex tool."""
21
20
 
22
- urls: List[str] = Field(
21
+ urls: list[str] = Field(
23
22
  description="List of URLs to scrape and index. Each URL should be a valid web address starting with http:// or https://",
24
23
  min_items=1,
25
24
  max_items=25,
@@ -67,11 +66,11 @@ class ScrapeAndIndex(WebScraperBaseTool):
67
66
  "Use this tool to collect and index web content that you want to reference later.\n"
68
67
  "The indexed content can then be queried using the query_indexed_content tool."
69
68
  )
70
- args_schema: Type[BaseModel] = ScrapeAndIndexInput
69
+ args_schema: type[BaseModel] = ScrapeAndIndexInput
71
70
 
72
71
  async def _arun(
73
72
  self,
74
- urls: List[str],
73
+ urls: list[str],
75
74
  chunk_size: int = DEFAULT_CHUNK_SIZE,
76
75
  chunk_overlap: int = DEFAULT_CHUNK_OVERLAP,
77
76
  **kwargs,
@@ -92,9 +91,12 @@ class ScrapeAndIndex(WebScraperBaseTool):
92
91
  f"[{agent_id}] Starting scrape and index operation with {len(urls)} URLs"
93
92
  )
94
93
 
94
+ embedding_api_key = self.get_openai_api_key()
95
+ vector_manager = VectorStoreManager(embedding_api_key)
96
+
95
97
  # Use the utility function to scrape and index URLs
96
98
  total_chunks, was_merged, valid_urls = await scrape_and_index_urls(
97
- urls, agent_id, self.skill_store, chunk_size, chunk_overlap
99
+ urls, agent_id, vector_manager, chunk_size, chunk_overlap
98
100
  )
99
101
 
100
102
  logger.info(
@@ -110,12 +112,11 @@ class ScrapeAndIndex(WebScraperBaseTool):
110
112
  return "Error: No content could be extracted from the provided URLs."
111
113
 
112
114
  # Get current storage size for response
113
- vs_manager = VectorStoreManager(self.skill_store)
114
- current_size = await vs_manager.get_content_size(agent_id)
115
+ current_size = await vector_manager.get_content_size(agent_id)
115
116
  size_limit_reached = len(valid_urls) < len(urls)
116
117
 
117
118
  # Update metadata
118
- metadata_manager = MetadataManager(self.skill_store)
119
+ metadata_manager = MetadataManager(vector_manager)
119
120
  new_metadata = metadata_manager.create_url_metadata(
120
121
  valid_urls, [], "scrape_and_index"
121
122
  )
@@ -169,7 +170,7 @@ class QueryIndexedContent(WebScraperBaseTool):
169
170
  "Use this tool to search through content that was previously scraped and indexed.\n"
170
171
  "This tool can help answer questions based on the indexed web content."
171
172
  )
172
- args_schema: Type[BaseModel] = QueryIndexInput
173
+ args_schema: type[BaseModel] = QueryIndexInput
173
174
 
174
175
  async def _arun(
175
176
  self,
@@ -196,9 +197,9 @@ class QueryIndexedContent(WebScraperBaseTool):
196
197
 
197
198
  logger.info(f"[{agent_id}] Looking for vector store: {vector_store_key}")
198
199
 
199
- stored_data = await self.skill_store.get_agent_skill_data(
200
- agent_id, "web_scraper", vector_store_key
201
- )
200
+ embedding_api_key = self.get_openai_api_key()
201
+ vector_manager = VectorStoreManager(embedding_api_key)
202
+ stored_data = await vector_manager.get_existing_vector_store(agent_id)
202
203
 
203
204
  if not stored_data:
204
205
  logger.warning(f"[{agent_id}] No vector store found")
@@ -210,9 +211,8 @@ class QueryIndexedContent(WebScraperBaseTool):
210
211
 
211
212
  # Create embeddings and decode vector store
212
213
  logger.info(f"[{agent_id}] Decoding vector store")
213
- vs_manager = VectorStoreManager(self.skill_store)
214
- embeddings = vs_manager.create_embeddings()
215
- vector_store = vs_manager.decode_vector_store(
214
+ embeddings = vector_manager.create_embeddings()
215
+ vector_store = vector_manager.decode_vector_store(
216
216
  stored_data["faiss_files"], embeddings
217
217
  )
218
218