intentkit 0.5.0__py3-none-any.whl → 0.5.2__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 (366) hide show
  1. intentkit/__init__.py +17 -0
  2. intentkit/abstracts/__init__.py +0 -0
  3. intentkit/abstracts/agent.py +60 -0
  4. intentkit/abstracts/api.py +4 -0
  5. intentkit/abstracts/engine.py +38 -0
  6. intentkit/abstracts/exception.py +9 -0
  7. intentkit/abstracts/graph.py +25 -0
  8. intentkit/abstracts/skill.py +129 -0
  9. intentkit/abstracts/twitter.py +54 -0
  10. intentkit/clients/__init__.py +14 -0
  11. intentkit/clients/cdp.py +53 -0
  12. intentkit/clients/twitter.py +445 -0
  13. intentkit/config/__init__.py +0 -0
  14. intentkit/config/config.py +164 -0
  15. intentkit/core/__init__.py +0 -0
  16. intentkit/core/agent.py +191 -0
  17. intentkit/core/api.py +40 -0
  18. intentkit/core/client.py +45 -0
  19. intentkit/core/credit.py +1767 -0
  20. intentkit/core/engine.py +1018 -0
  21. intentkit/core/node.py +223 -0
  22. intentkit/core/prompt.py +58 -0
  23. intentkit/core/skill.py +124 -0
  24. intentkit/models/agent.py +1689 -0
  25. intentkit/models/agent_data.py +810 -0
  26. intentkit/models/agent_schema.json +733 -0
  27. intentkit/models/app_setting.py +156 -0
  28. intentkit/models/base.py +9 -0
  29. intentkit/models/chat.py +581 -0
  30. intentkit/models/conversation.py +286 -0
  31. intentkit/models/credit.py +1406 -0
  32. intentkit/models/db.py +120 -0
  33. intentkit/models/db_mig.py +102 -0
  34. intentkit/models/generator.py +347 -0
  35. intentkit/models/llm.py +746 -0
  36. intentkit/models/redis.py +132 -0
  37. intentkit/models/skill.py +466 -0
  38. intentkit/models/user.py +243 -0
  39. intentkit/skills/__init__.py +12 -0
  40. intentkit/skills/acolyt/__init__.py +83 -0
  41. intentkit/skills/acolyt/acolyt.jpg +0 -0
  42. intentkit/skills/acolyt/ask.py +128 -0
  43. intentkit/skills/acolyt/base.py +28 -0
  44. intentkit/skills/acolyt/schema.json +89 -0
  45. intentkit/skills/aixbt/README.md +71 -0
  46. intentkit/skills/aixbt/__init__.py +73 -0
  47. intentkit/skills/aixbt/aixbt.jpg +0 -0
  48. intentkit/skills/aixbt/base.py +21 -0
  49. intentkit/skills/aixbt/projects.py +153 -0
  50. intentkit/skills/aixbt/schema.json +99 -0
  51. intentkit/skills/allora/__init__.py +83 -0
  52. intentkit/skills/allora/allora.jpeg +0 -0
  53. intentkit/skills/allora/base.py +28 -0
  54. intentkit/skills/allora/price.py +130 -0
  55. intentkit/skills/allora/schema.json +89 -0
  56. intentkit/skills/base.py +174 -0
  57. intentkit/skills/carv/README.md +95 -0
  58. intentkit/skills/carv/__init__.py +121 -0
  59. intentkit/skills/carv/base.py +183 -0
  60. intentkit/skills/carv/carv.webp +0 -0
  61. intentkit/skills/carv/fetch_news.py +92 -0
  62. intentkit/skills/carv/onchain_query.py +164 -0
  63. intentkit/skills/carv/schema.json +137 -0
  64. intentkit/skills/carv/token_info_and_price.py +110 -0
  65. intentkit/skills/cdp/__init__.py +137 -0
  66. intentkit/skills/cdp/base.py +21 -0
  67. intentkit/skills/cdp/cdp.png +0 -0
  68. intentkit/skills/cdp/get_balance.py +81 -0
  69. intentkit/skills/cdp/schema.json +473 -0
  70. intentkit/skills/chainlist/README.md +38 -0
  71. intentkit/skills/chainlist/__init__.py +54 -0
  72. intentkit/skills/chainlist/base.py +21 -0
  73. intentkit/skills/chainlist/chain_lookup.py +208 -0
  74. intentkit/skills/chainlist/chainlist.png +0 -0
  75. intentkit/skills/chainlist/schema.json +47 -0
  76. intentkit/skills/common/__init__.py +82 -0
  77. intentkit/skills/common/base.py +21 -0
  78. intentkit/skills/common/common.jpg +0 -0
  79. intentkit/skills/common/current_time.py +84 -0
  80. intentkit/skills/common/schema.json +57 -0
  81. intentkit/skills/cookiefun/README.md +121 -0
  82. intentkit/skills/cookiefun/__init__.py +78 -0
  83. intentkit/skills/cookiefun/base.py +41 -0
  84. intentkit/skills/cookiefun/constants.py +18 -0
  85. intentkit/skills/cookiefun/cookiefun.png +0 -0
  86. intentkit/skills/cookiefun/get_account_details.py +171 -0
  87. intentkit/skills/cookiefun/get_account_feed.py +282 -0
  88. intentkit/skills/cookiefun/get_account_smart_followers.py +181 -0
  89. intentkit/skills/cookiefun/get_sectors.py +128 -0
  90. intentkit/skills/cookiefun/schema.json +155 -0
  91. intentkit/skills/cookiefun/search_accounts.py +225 -0
  92. intentkit/skills/cryptocompare/__init__.py +130 -0
  93. intentkit/skills/cryptocompare/api.py +159 -0
  94. intentkit/skills/cryptocompare/base.py +303 -0
  95. intentkit/skills/cryptocompare/cryptocompare.png +0 -0
  96. intentkit/skills/cryptocompare/fetch_news.py +96 -0
  97. intentkit/skills/cryptocompare/fetch_price.py +99 -0
  98. intentkit/skills/cryptocompare/fetch_top_exchanges.py +113 -0
  99. intentkit/skills/cryptocompare/fetch_top_market_cap.py +109 -0
  100. intentkit/skills/cryptocompare/fetch_top_volume.py +108 -0
  101. intentkit/skills/cryptocompare/fetch_trading_signals.py +107 -0
  102. intentkit/skills/cryptocompare/schema.json +168 -0
  103. intentkit/skills/cryptopanic/__init__.py +108 -0
  104. intentkit/skills/cryptopanic/base.py +51 -0
  105. intentkit/skills/cryptopanic/cryptopanic.png +0 -0
  106. intentkit/skills/cryptopanic/fetch_crypto_news.py +153 -0
  107. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +136 -0
  108. intentkit/skills/cryptopanic/schema.json +103 -0
  109. intentkit/skills/dapplooker/README.md +92 -0
  110. intentkit/skills/dapplooker/__init__.py +83 -0
  111. intentkit/skills/dapplooker/base.py +26 -0
  112. intentkit/skills/dapplooker/dapplooker.jpg +0 -0
  113. intentkit/skills/dapplooker/dapplooker_token_data.py +476 -0
  114. intentkit/skills/dapplooker/schema.json +91 -0
  115. intentkit/skills/defillama/__init__.py +323 -0
  116. intentkit/skills/defillama/api.py +315 -0
  117. intentkit/skills/defillama/base.py +135 -0
  118. intentkit/skills/defillama/coins/__init__.py +0 -0
  119. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +116 -0
  120. intentkit/skills/defillama/coins/fetch_block.py +98 -0
  121. intentkit/skills/defillama/coins/fetch_current_prices.py +105 -0
  122. intentkit/skills/defillama/coins/fetch_first_price.py +100 -0
  123. intentkit/skills/defillama/coins/fetch_historical_prices.py +110 -0
  124. intentkit/skills/defillama/coins/fetch_price_chart.py +109 -0
  125. intentkit/skills/defillama/coins/fetch_price_percentage.py +93 -0
  126. intentkit/skills/defillama/config/__init__.py +0 -0
  127. intentkit/skills/defillama/config/chains.py +433 -0
  128. intentkit/skills/defillama/defillama.jpeg +0 -0
  129. intentkit/skills/defillama/fees/__init__.py +0 -0
  130. intentkit/skills/defillama/fees/fetch_fees_overview.py +130 -0
  131. intentkit/skills/defillama/schema.json +383 -0
  132. intentkit/skills/defillama/stablecoins/__init__.py +0 -0
  133. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +100 -0
  134. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +129 -0
  135. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +83 -0
  136. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +126 -0
  137. intentkit/skills/defillama/tests/__init__.py +0 -0
  138. intentkit/skills/defillama/tests/api_integration.test.py +192 -0
  139. intentkit/skills/defillama/tests/api_unit.test.py +583 -0
  140. intentkit/skills/defillama/tvl/__init__.py +0 -0
  141. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +106 -0
  142. intentkit/skills/defillama/tvl/fetch_chains.py +107 -0
  143. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +91 -0
  144. intentkit/skills/defillama/tvl/fetch_protocol.py +207 -0
  145. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +93 -0
  146. intentkit/skills/defillama/tvl/fetch_protocols.py +196 -0
  147. intentkit/skills/defillama/volumes/__init__.py +0 -0
  148. intentkit/skills/defillama/volumes/fetch_dex_overview.py +157 -0
  149. intentkit/skills/defillama/volumes/fetch_dex_summary.py +123 -0
  150. intentkit/skills/defillama/volumes/fetch_options_overview.py +131 -0
  151. intentkit/skills/defillama/yields/__init__.py +0 -0
  152. intentkit/skills/defillama/yields/fetch_pool_chart.py +100 -0
  153. intentkit/skills/defillama/yields/fetch_pools.py +126 -0
  154. intentkit/skills/dexscreener/__init__.py +93 -0
  155. intentkit/skills/dexscreener/base.py +133 -0
  156. intentkit/skills/dexscreener/dexscreener.png +0 -0
  157. intentkit/skills/dexscreener/model/__init__.py +0 -0
  158. intentkit/skills/dexscreener/model/search_token_response.py +82 -0
  159. intentkit/skills/dexscreener/schema.json +48 -0
  160. intentkit/skills/dexscreener/search_token.py +321 -0
  161. intentkit/skills/dune_analytics/__init__.py +103 -0
  162. intentkit/skills/dune_analytics/base.py +46 -0
  163. intentkit/skills/dune_analytics/dune.png +0 -0
  164. intentkit/skills/dune_analytics/fetch_kol_buys.py +128 -0
  165. intentkit/skills/dune_analytics/fetch_nation_metrics.py +237 -0
  166. intentkit/skills/dune_analytics/schema.json +99 -0
  167. intentkit/skills/elfa/README.md +100 -0
  168. intentkit/skills/elfa/__init__.py +123 -0
  169. intentkit/skills/elfa/base.py +28 -0
  170. intentkit/skills/elfa/elfa.jpg +0 -0
  171. intentkit/skills/elfa/mention.py +504 -0
  172. intentkit/skills/elfa/schema.json +153 -0
  173. intentkit/skills/elfa/stats.py +118 -0
  174. intentkit/skills/elfa/tokens.py +126 -0
  175. intentkit/skills/enso/README.md +75 -0
  176. intentkit/skills/enso/__init__.py +114 -0
  177. intentkit/skills/enso/abi/__init__.py +0 -0
  178. intentkit/skills/enso/abi/approval.py +279 -0
  179. intentkit/skills/enso/abi/erc20.py +14 -0
  180. intentkit/skills/enso/abi/route.py +129 -0
  181. intentkit/skills/enso/base.py +44 -0
  182. intentkit/skills/enso/best_yield.py +286 -0
  183. intentkit/skills/enso/enso.jpg +0 -0
  184. intentkit/skills/enso/networks.py +105 -0
  185. intentkit/skills/enso/prices.py +93 -0
  186. intentkit/skills/enso/route.py +300 -0
  187. intentkit/skills/enso/schema.json +212 -0
  188. intentkit/skills/enso/tokens.py +223 -0
  189. intentkit/skills/enso/wallet.py +381 -0
  190. intentkit/skills/github/README.md +63 -0
  191. intentkit/skills/github/__init__.py +54 -0
  192. intentkit/skills/github/base.py +21 -0
  193. intentkit/skills/github/github.jpg +0 -0
  194. intentkit/skills/github/github_search.py +183 -0
  195. intentkit/skills/github/schema.json +59 -0
  196. intentkit/skills/heurist/__init__.py +143 -0
  197. intentkit/skills/heurist/base.py +26 -0
  198. intentkit/skills/heurist/heurist.png +0 -0
  199. intentkit/skills/heurist/image_generation_animagine_xl.py +162 -0
  200. intentkit/skills/heurist/image_generation_arthemy_comics.py +162 -0
  201. intentkit/skills/heurist/image_generation_arthemy_real.py +162 -0
  202. intentkit/skills/heurist/image_generation_braindance.py +162 -0
  203. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +162 -0
  204. intentkit/skills/heurist/image_generation_flux_1_dev.py +162 -0
  205. intentkit/skills/heurist/image_generation_sdxl.py +161 -0
  206. intentkit/skills/heurist/schema.json +196 -0
  207. intentkit/skills/lifi/README.md +294 -0
  208. intentkit/skills/lifi/__init__.py +141 -0
  209. intentkit/skills/lifi/base.py +21 -0
  210. intentkit/skills/lifi/lifi.png +0 -0
  211. intentkit/skills/lifi/schema.json +89 -0
  212. intentkit/skills/lifi/token_execute.py +472 -0
  213. intentkit/skills/lifi/token_quote.py +190 -0
  214. intentkit/skills/lifi/utils.py +656 -0
  215. intentkit/skills/moralis/README.md +490 -0
  216. intentkit/skills/moralis/__init__.py +110 -0
  217. intentkit/skills/moralis/api.py +281 -0
  218. intentkit/skills/moralis/base.py +55 -0
  219. intentkit/skills/moralis/fetch_chain_portfolio.py +191 -0
  220. intentkit/skills/moralis/fetch_nft_portfolio.py +284 -0
  221. intentkit/skills/moralis/fetch_solana_portfolio.py +331 -0
  222. intentkit/skills/moralis/fetch_wallet_portfolio.py +301 -0
  223. intentkit/skills/moralis/moralis.png +0 -0
  224. intentkit/skills/moralis/schema.json +156 -0
  225. intentkit/skills/moralis/tests/__init__.py +0 -0
  226. intentkit/skills/moralis/tests/test_wallet.py +511 -0
  227. intentkit/skills/nation/__init__.py +62 -0
  228. intentkit/skills/nation/base.py +31 -0
  229. intentkit/skills/nation/nation.png +0 -0
  230. intentkit/skills/nation/nft_check.py +106 -0
  231. intentkit/skills/nation/schema.json +58 -0
  232. intentkit/skills/openai/__init__.py +107 -0
  233. intentkit/skills/openai/base.py +32 -0
  234. intentkit/skills/openai/dalle_image_generation.py +128 -0
  235. intentkit/skills/openai/gpt_image_generation.py +152 -0
  236. intentkit/skills/openai/gpt_image_to_image.py +186 -0
  237. intentkit/skills/openai/image_to_text.py +126 -0
  238. intentkit/skills/openai/openai.png +0 -0
  239. intentkit/skills/openai/schema.json +139 -0
  240. intentkit/skills/portfolio/README.md +55 -0
  241. intentkit/skills/portfolio/__init__.py +151 -0
  242. intentkit/skills/portfolio/base.py +107 -0
  243. intentkit/skills/portfolio/constants.py +9 -0
  244. intentkit/skills/portfolio/moralis.png +0 -0
  245. intentkit/skills/portfolio/schema.json +237 -0
  246. intentkit/skills/portfolio/token_balances.py +155 -0
  247. intentkit/skills/portfolio/wallet_approvals.py +102 -0
  248. intentkit/skills/portfolio/wallet_defi_positions.py +80 -0
  249. intentkit/skills/portfolio/wallet_history.py +155 -0
  250. intentkit/skills/portfolio/wallet_net_worth.py +112 -0
  251. intentkit/skills/portfolio/wallet_nfts.py +139 -0
  252. intentkit/skills/portfolio/wallet_profitability.py +101 -0
  253. intentkit/skills/portfolio/wallet_profitability_summary.py +91 -0
  254. intentkit/skills/portfolio/wallet_stats.py +79 -0
  255. intentkit/skills/portfolio/wallet_swaps.py +147 -0
  256. intentkit/skills/skills.toml +103 -0
  257. intentkit/skills/slack/__init__.py +98 -0
  258. intentkit/skills/slack/base.py +55 -0
  259. intentkit/skills/slack/get_channel.py +109 -0
  260. intentkit/skills/slack/get_message.py +136 -0
  261. intentkit/skills/slack/schedule_message.py +92 -0
  262. intentkit/skills/slack/schema.json +135 -0
  263. intentkit/skills/slack/send_message.py +81 -0
  264. intentkit/skills/slack/slack.jpg +0 -0
  265. intentkit/skills/system/__init__.py +90 -0
  266. intentkit/skills/system/base.py +22 -0
  267. intentkit/skills/system/read_agent_api_key.py +87 -0
  268. intentkit/skills/system/regenerate_agent_api_key.py +77 -0
  269. intentkit/skills/system/schema.json +53 -0
  270. intentkit/skills/system/system.svg +76 -0
  271. intentkit/skills/tavily/README.md +86 -0
  272. intentkit/skills/tavily/__init__.py +91 -0
  273. intentkit/skills/tavily/base.py +27 -0
  274. intentkit/skills/tavily/schema.json +119 -0
  275. intentkit/skills/tavily/tavily.jpg +0 -0
  276. intentkit/skills/tavily/tavily_extract.py +147 -0
  277. intentkit/skills/tavily/tavily_search.py +139 -0
  278. intentkit/skills/token/README.md +89 -0
  279. intentkit/skills/token/__init__.py +107 -0
  280. intentkit/skills/token/base.py +154 -0
  281. intentkit/skills/token/constants.py +9 -0
  282. intentkit/skills/token/erc20_transfers.py +145 -0
  283. intentkit/skills/token/moralis.png +0 -0
  284. intentkit/skills/token/schema.json +141 -0
  285. intentkit/skills/token/token_analytics.py +81 -0
  286. intentkit/skills/token/token_price.py +132 -0
  287. intentkit/skills/token/token_search.py +121 -0
  288. intentkit/skills/twitter/__init__.py +146 -0
  289. intentkit/skills/twitter/base.py +68 -0
  290. intentkit/skills/twitter/follow_user.py +69 -0
  291. intentkit/skills/twitter/get_mentions.py +124 -0
  292. intentkit/skills/twitter/get_timeline.py +111 -0
  293. intentkit/skills/twitter/get_user_by_username.py +84 -0
  294. intentkit/skills/twitter/get_user_tweets.py +123 -0
  295. intentkit/skills/twitter/like_tweet.py +65 -0
  296. intentkit/skills/twitter/post_tweet.py +90 -0
  297. intentkit/skills/twitter/reply_tweet.py +98 -0
  298. intentkit/skills/twitter/retweet.py +76 -0
  299. intentkit/skills/twitter/schema.json +258 -0
  300. intentkit/skills/twitter/search_tweets.py +115 -0
  301. intentkit/skills/twitter/twitter.png +0 -0
  302. intentkit/skills/unrealspeech/__init__.py +55 -0
  303. intentkit/skills/unrealspeech/base.py +21 -0
  304. intentkit/skills/unrealspeech/schema.json +100 -0
  305. intentkit/skills/unrealspeech/text_to_speech.py +177 -0
  306. intentkit/skills/unrealspeech/unrealspeech.jpg +0 -0
  307. intentkit/skills/venice_audio/__init__.py +106 -0
  308. intentkit/skills/venice_audio/base.py +119 -0
  309. intentkit/skills/venice_audio/input.py +41 -0
  310. intentkit/skills/venice_audio/schema.json +152 -0
  311. intentkit/skills/venice_audio/venice_audio.py +240 -0
  312. intentkit/skills/venice_audio/venice_logo.jpg +0 -0
  313. intentkit/skills/venice_image/README.md +119 -0
  314. intentkit/skills/venice_image/__init__.py +154 -0
  315. intentkit/skills/venice_image/api.py +138 -0
  316. intentkit/skills/venice_image/base.py +188 -0
  317. intentkit/skills/venice_image/config.py +35 -0
  318. intentkit/skills/venice_image/image_enhance/README.md +119 -0
  319. intentkit/skills/venice_image/image_enhance/__init__.py +0 -0
  320. intentkit/skills/venice_image/image_enhance/image_enhance.py +80 -0
  321. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +23 -0
  322. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +40 -0
  323. intentkit/skills/venice_image/image_generation/README.md +144 -0
  324. intentkit/skills/venice_image/image_generation/__init__.py +0 -0
  325. intentkit/skills/venice_image/image_generation/image_generation_base.py +117 -0
  326. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -0
  327. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -0
  328. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -0
  329. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -0
  330. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -0
  331. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -0
  332. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -0
  333. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -0
  334. intentkit/skills/venice_image/image_upscale/README.md +111 -0
  335. intentkit/skills/venice_image/image_upscale/__init__.py +0 -0
  336. intentkit/skills/venice_image/image_upscale/image_upscale.py +90 -0
  337. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +23 -0
  338. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -0
  339. intentkit/skills/venice_image/image_vision/README.md +112 -0
  340. intentkit/skills/venice_image/image_vision/__init__.py +0 -0
  341. intentkit/skills/venice_image/image_vision/image_vision.py +100 -0
  342. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -0
  343. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -0
  344. intentkit/skills/venice_image/schema.json +267 -0
  345. intentkit/skills/venice_image/utils.py +78 -0
  346. intentkit/skills/venice_image/venice_image.jpg +0 -0
  347. intentkit/skills/web_scraper/README.md +82 -0
  348. intentkit/skills/web_scraper/__init__.py +92 -0
  349. intentkit/skills/web_scraper/base.py +21 -0
  350. intentkit/skills/web_scraper/langchain.png +0 -0
  351. intentkit/skills/web_scraper/schema.json +115 -0
  352. intentkit/skills/web_scraper/scrape_and_index.py +327 -0
  353. intentkit/utils/__init__.py +1 -0
  354. intentkit/utils/chain.py +436 -0
  355. intentkit/utils/error.py +134 -0
  356. intentkit/utils/logging.py +70 -0
  357. intentkit/utils/middleware.py +61 -0
  358. intentkit/utils/random.py +16 -0
  359. intentkit/utils/s3.py +267 -0
  360. intentkit/utils/slack_alert.py +79 -0
  361. intentkit/utils/tx.py +37 -0
  362. {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/METADATA +1 -1
  363. intentkit-0.5.2.dist-info/RECORD +365 -0
  364. intentkit-0.5.0.dist-info/RECORD +0 -4
  365. {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/WHEEL +0 -0
  366. {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,223 @@
1
+ from typing import Type
2
+
3
+ import httpx
4
+ from langchain.tools.base import ToolException
5
+ from langchain_core.runnables import RunnableConfig
6
+ from pydantic import BaseModel, Field
7
+
8
+ from intentkit.skills.base import SkillContext
9
+ from intentkit.skills.enso.base import (
10
+ EnsoBaseTool,
11
+ base_url,
12
+ default_chain_id,
13
+ )
14
+
15
+ # Actual Enso output types
16
+ # class UnderlyingToken(BaseModel):
17
+ # address: str | None = Field(None, description="The address of the token")
18
+ # chainId: int | None = Field(None, description="The blockchain chain ID")
19
+ # type: str | None = Field(None, description="The type of the token (e.g., base token)")
20
+ # decimals: int | None = Field(None, description="The number of decimals for the token")
21
+ # name: str | None = Field(None, description="The name of the token")
22
+ # symbol: str | None = Field(None, description="The symbol of the token")
23
+ # logosUri: list[HttpUrl] | None = Field(None, description="List of URLs to token's logos")
24
+ #
25
+ #
26
+ # class TokenData(BaseModel):
27
+ # chainId: int | None = Field(None, description="The blockchain chain ID")
28
+ # address: str | None = Field(None, description="The address of the token")
29
+ # decimals: int | None = Field(None, description="The number of decimals for the token")
30
+ # name: str | None = Field(None, description="The name of the token")
31
+ # symbol: str | None = Field(None, description="The symbol of the token")
32
+ # logosUri: list[HttpUrl] | None = Field(None, description="List of URLs to token's logos")
33
+ # type: str | None = Field(None, description="The type of the token (e.g., defi, base, etc.)")
34
+ # protocolSlug: str | None = Field(None, description="The protocol slug associated with the token")
35
+ # underlyingTokens: list[UnderlyingToken] | None = Field(None, description="List of underlying tokens")
36
+ # primaryAddress: str | None = Field(None, description="The primary address associated with the token")
37
+ # apy: float | None = Field(None, description="The annual percentage yield (APY) for the token")
38
+ #
39
+ #
40
+ # class MetaData(BaseModel):
41
+ # total: int | None = Field(None, description="Total number of records")
42
+ # lastPage: int | None = Field(None, description="Last page of the data")
43
+ # currentPage: int | None = Field(None, description="Current page of the data")
44
+ # perPage: int | None = Field(None, description="Number of records per page")
45
+ # prev: int | None = Field(None, description="Previous page number, if applicable")
46
+ # next: int | None = Field(None, description="Next page number, if applicable")
47
+ #
48
+ #
49
+ # class TokenResponse(BaseModel):
50
+ # data: list[TokenData] | None = Field(None, description="List of token data")
51
+ # meta: MetaData | None = Field(None, description="Metadata regarding pagination")
52
+
53
+
54
+ class EnsoGetTokensInput(BaseModel):
55
+ chainId: int = Field(
56
+ default_chain_id,
57
+ description="The blockchain chain ID",
58
+ )
59
+ protocolSlug: str | None = Field(
60
+ None,
61
+ description="The protocol slug (e.g., 'aave-v2', 'aave-v3', 'compound-v2')",
62
+ )
63
+ # address: str | None = Field(
64
+ # None,
65
+ # description="Ethereum address of the token",
66
+ # )
67
+ # underlyingTokens: str | list[str] | None = Field(
68
+ # None,
69
+ # description="Underlying tokens (e.g. 0xdAC17F958D2ee523a2206206994597C13D831ec7)",
70
+ # )
71
+ # primaryAddress: str | None = Field(
72
+ # None,
73
+ # description="Ethereum address for contract interaction of defi token",
74
+ # )
75
+ # type: Literal["defi", "base"] | None = Field(
76
+ # None,
77
+ # description="The type of the token (e.g., 'defi', 'base'). Note: Base Network also exists, it should not be confused with type.",
78
+ # )
79
+
80
+
81
+ class UnderlyingTokenCompact(BaseModel):
82
+ address: str | None = Field(None, description="The address of the token")
83
+ type: str | None = Field(
84
+ None, description="The type of the token (e.g., base token)"
85
+ )
86
+ name: str | None = Field(None, description="The name of the token")
87
+ symbol: str | None = Field(None, description="The symbol of the token")
88
+ decimals: int | None = Field(
89
+ None, description="The number of decimals for the token"
90
+ )
91
+
92
+
93
+ class TokenResponseCompact(BaseModel):
94
+ name: str | None = Field(None, description="The name of the token")
95
+ symbol: str | None = Field(None, description="The symbol of the token")
96
+ address: str | None = Field(None, description="The address of the token")
97
+ primaryAddress: str | None = Field(
98
+ None, description="The primary address associated with the token"
99
+ )
100
+ type: str | None = Field(
101
+ None, description="The type of the token (e.g., defi, base, etc.)"
102
+ )
103
+ apy: float | None = Field(
104
+ None, description="The annual percentage yield (APY) for the token"
105
+ )
106
+ underlyingTokens: list[UnderlyingTokenCompact] | None = Field(
107
+ None, description="List of underlying tokens"
108
+ )
109
+ decimals: int | None = Field(
110
+ None, description="The number of decimals for the token"
111
+ )
112
+
113
+
114
+ class EnsoGetTokensOutput(BaseModel):
115
+ res: list[TokenResponseCompact] | None
116
+
117
+
118
+ class EnsoGetTokens(EnsoBaseTool):
119
+ """
120
+ Tool for interacting with the Enso API to retrieve cryptocurrency token information, including APY, symbol, address,
121
+ protocol slug, token type, and underlying tokens.
122
+
123
+ This class is designed to provide detailed insights into tokens managed by the Enso platform.
124
+ It integrates with the Enso API and offers various options for filtering tokens based on optional inputs such as
125
+ chain ID, protocol slug, token type, and underlying tokens. The main objective is to retrieve APY data
126
+ and relevant information for the specified tokens, delivering structured output for further processing.
127
+
128
+ Attributes:
129
+ name (str): Name of the tool, specifically "enso_get_tokens".
130
+ description (str): Comprehensive description of the tool's purpose and functionality.
131
+ args_schema (Type[BaseModel]): Schema for input arguments, specifying expected parameters.
132
+ """
133
+
134
+ name: str = "enso_get_tokens"
135
+ description: str = (
136
+ "Enso Finance Token Information Tool: Retrieves detailed token information from the Enso Finance API, "
137
+ "including APY, symbol, address, protocol slug, token type, and underlying tokens."
138
+ )
139
+ args_schema: Type[BaseModel] = EnsoGetTokensInput
140
+
141
+ async def _arun(
142
+ self,
143
+ config: RunnableConfig,
144
+ chainId: int = default_chain_id,
145
+ protocolSlug: str | None = None,
146
+ **kwargs,
147
+ ) -> EnsoGetTokensOutput:
148
+ """Run the tool to get Tokens and APY.
149
+ Args:
150
+ chainId (int): The chain id of the network.
151
+ protocolSlug (str): The protocol slug (e.g., 'aave-v2', 'aave-v3', 'compound-v2').
152
+ Returns:
153
+ EnsoGetTokensOutput: A structured output containing the tokens APY data.
154
+
155
+ Raises:
156
+ Exception: If there's an error accessing the Enso API.
157
+ """
158
+ url = f"{base_url}/api/v1/tokens"
159
+
160
+ context: SkillContext = self.context_from_config(config)
161
+ agent_id = context.agent.id
162
+ api_token = self.get_api_token(context)
163
+ main_tokens = self.get_main_tokens(context)
164
+ headers = {
165
+ "accept": "application/json",
166
+ "Authorization": f"Bearer {api_token}",
167
+ }
168
+
169
+ params = EnsoGetTokensInput(
170
+ chainId=chainId,
171
+ protocolSlug=protocolSlug,
172
+ ).model_dump(exclude_none=True)
173
+
174
+ params["page"] = 1
175
+ params["includeMetadata"] = "true"
176
+
177
+ async with httpx.AsyncClient() as client:
178
+ try:
179
+ response = await client.get(url, headers=headers, params=params)
180
+ response.raise_for_status()
181
+ json_dict = response.json()
182
+
183
+ token_decimals = await self.skill_store.get_agent_skill_data(
184
+ agent_id,
185
+ "enso_get_tokens",
186
+ "decimals",
187
+ )
188
+ if not token_decimals:
189
+ token_decimals = {}
190
+
191
+ # filter the main tokens from config or the ones that have apy assigned.
192
+ res = EnsoGetTokensOutput(res=list[TokenResponseCompact]())
193
+ for item in json_dict["data"]:
194
+ main_tokens = [item.upper() for item in main_tokens]
195
+ if item.get("apy") or (item.get("symbol").upper() in main_tokens):
196
+ token_response = TokenResponseCompact(**item)
197
+ res.res.append(token_response)
198
+ token_decimals[token_response.address] = token_response.decimals
199
+ if (
200
+ token_response.underlyingTokens
201
+ and len(token_response.underlyingTokens) > 0
202
+ ):
203
+ for u_token in token_response.underlyingTokens:
204
+ token_decimals[u_token.address] = u_token.decimals
205
+
206
+ await self.skill_store.save_agent_skill_data(
207
+ agent_id,
208
+ "enso_get_tokens",
209
+ "decimals",
210
+ token_decimals,
211
+ )
212
+
213
+ return res
214
+ except httpx.RequestError as req_err:
215
+ raise ToolException(
216
+ f"request error from Enso API: {req_err}"
217
+ ) from req_err
218
+ except httpx.HTTPStatusError as http_err:
219
+ raise ToolException(
220
+ f"http error from Enso API: {http_err}"
221
+ ) from http_err
222
+ except Exception as e:
223
+ raise ToolException(f"error from Enso API: {e}") from e
@@ -0,0 +1,381 @@
1
+ from typing import Literal, Tuple, Type
2
+
3
+ import httpx
4
+ from langchain.tools.base import ToolException
5
+ from langchain_core.runnables import RunnableConfig
6
+ from pydantic import BaseModel, Field
7
+
8
+ from intentkit.skills.base import SkillContext
9
+ from intentkit.utils.tx import EvmContractWrapper
10
+
11
+ from .abi.erc20 import ABI_ERC20
12
+ from .base import EnsoBaseTool, base_url, default_chain_id
13
+
14
+
15
+ class EnsoGetBalancesInput(BaseModel):
16
+ """
17
+ Input model for retrieving wallet balances.
18
+ """
19
+
20
+ chainId: int = Field(
21
+ default_chain_id, description="Chain ID of the blockchain network"
22
+ )
23
+ # eoaAddress: str = Field(
24
+ # description="Address of the eoa with which to associate the ensoWallet for balances"
25
+ # )
26
+ # useEoa: bool = Field(
27
+ # description="If true returns balances for the provided eoaAddress, instead of the associated ensoWallet"
28
+ # )
29
+
30
+
31
+ class WalletBalance(BaseModel):
32
+ token: str | None = Field(None, description="The address of the token")
33
+ amount: str | None = Field(None, description="The unformatted balance of the token")
34
+ decimals: int | None = Field(None, ge=0, description="The number of decimals")
35
+ price: float | None = Field(None, description="Price of the token in usd")
36
+
37
+
38
+ class EnsoGetBalancesOutput(BaseModel):
39
+ """
40
+ Output model for retrieving wallet balances.
41
+ """
42
+
43
+ res: list[WalletBalance] | None = Field(
44
+ None, description="The wallet's balances along with token details."
45
+ )
46
+
47
+
48
+ class EnsoGetWalletBalances(EnsoBaseTool):
49
+ """
50
+ This tool allows querying for first 20 token balances of a specific wallet
51
+ and blockchain network.
52
+
53
+ Attributes:
54
+ name (str): Name of the tool, specifically "enso_get_wallet_balances".
55
+ description (str): Comprehensive description of the tool's purpose and functionality.
56
+ args_schema (Type[BaseModel]): Schema for input arguments, specifying expected parameters.
57
+ """
58
+
59
+ name: str = "enso_get_wallet_balances"
60
+ description: str = (
61
+ "Retrieve token balances of a wallet on a specified blockchain network."
62
+ )
63
+ args_schema: Type[BaseModel] = EnsoGetBalancesInput
64
+
65
+ async def _arun(
66
+ self,
67
+ config: RunnableConfig,
68
+ chainId: int = default_chain_id,
69
+ **kwargs,
70
+ ) -> EnsoGetBalancesOutput:
71
+ """
72
+ Run the tool to get token balances of a wallet.
73
+
74
+ Args:
75
+ chainId (int): Chain ID of the blockchain network.
76
+
77
+ Returns:
78
+ EnsoGetBalancesOutput: The list of balances or an error message.
79
+ """
80
+ url = f"{base_url}/api/v1/wallet/balances"
81
+
82
+ context: SkillContext = self.context_from_config(config)
83
+ api_token = self.get_api_token(context)
84
+ wallet = await self.get_wallet(context)
85
+ headers = {
86
+ "accept": "application/json",
87
+ "Authorization": f"Bearer {api_token}",
88
+ }
89
+
90
+ params = EnsoGetBalancesInput(chainId=chainId).model_dump(exclude_none=True)
91
+ params["eoaAddress"] = wallet.addresses[0].address_id
92
+ params["useEoa"] = True
93
+
94
+ async with httpx.AsyncClient() as client:
95
+ try:
96
+ # Send the GET request
97
+ response = await client.get(url, headers=headers, params=params)
98
+ response.raise_for_status()
99
+
100
+ # Map the response JSON into the WalletBalance model
101
+ json_dict = response.json()[:20]
102
+ res = [WalletBalance(**item) for item in json_dict]
103
+
104
+ # Return the parsed response
105
+ return EnsoGetBalancesOutput(res=res)
106
+ except httpx.RequestError as req_err:
107
+ raise ToolException("request error from Enso API") from req_err
108
+ except httpx.HTTPStatusError as http_err:
109
+ raise ToolException("http error from Enso API") from http_err
110
+ except Exception as e:
111
+ raise ToolException(f"error from Enso API: {e}") from e
112
+
113
+
114
+ class EnsoGetApprovalsInput(BaseModel):
115
+ """
116
+ Input model for retrieving wallet approvals.
117
+ """
118
+
119
+ chainId: int = Field(
120
+ default_chain_id, description="Chain ID of the blockchain network"
121
+ )
122
+ fromAddress: str = Field(description="Address of the wallet")
123
+ routingStrategy: Literal["ensowallet", "router", "delegate"] | None = Field(
124
+ None, description="Routing strategy to use"
125
+ )
126
+
127
+
128
+ class WalletAllowance(BaseModel):
129
+ token: str | None = Field(None, description="The token address")
130
+ allowance: str | None = Field(None, description="The amount of tokens approved")
131
+ spender: str | None = Field(None, description="The spender address")
132
+
133
+
134
+ class EnsoGetApprovalsOutput(BaseModel):
135
+ """
136
+ Output model for retrieving wallet approvals.
137
+ """
138
+
139
+ res: list[WalletAllowance] | None = Field(
140
+ None, description="Response containing the list of token approvals."
141
+ )
142
+
143
+
144
+ class EnsoGetWalletApprovals(EnsoBaseTool):
145
+ """
146
+ This tool allows querying for first 50 token spend approvals associated with a specific wallet
147
+ and blockchain network.
148
+
149
+ Attributes:
150
+ name (str): Name of the tool, specifically "enso_get_wallet_approvals".
151
+ description (str): Comprehensive description of the tool's purpose and functionality.
152
+ args_schema (Type[BaseModel]): Schema for input arguments, specifying expected parameters.
153
+ """
154
+
155
+ name: str = "enso_get_wallet_approvals"
156
+ description: str = (
157
+ "Retrieve token spend approvals for a wallet on a specified blockchain network."
158
+ )
159
+ args_schema: Type[BaseModel] = EnsoGetApprovalsOutput
160
+
161
+ async def _arun(
162
+ self,
163
+ config: RunnableConfig,
164
+ chainId: int = default_chain_id,
165
+ **kwargs,
166
+ ) -> EnsoGetApprovalsOutput:
167
+ """
168
+ Run the tool to get token approvals for a wallet.
169
+
170
+ Args:
171
+ chainId (int): Chain ID of the blockchain network.
172
+ **kwargs: optional kwargs for the tool with args schema defined in EnsoGetApprovalsInput.
173
+
174
+ Returns:
175
+ EnsoGetApprovalsOutput: The list of approvals or an error message.
176
+ """
177
+ url = f"{base_url}/api/v1/wallet/approvals"
178
+
179
+ context: SkillContext = self.context_from_config(config)
180
+ api_token = self.get_api_token(context)
181
+ wallet = await self.get_wallet(context)
182
+
183
+ headers = {
184
+ "accept": "application/json",
185
+ "Authorization": f"Bearer {api_token}",
186
+ }
187
+
188
+ params = EnsoGetApprovalsInput(
189
+ chainId=chainId,
190
+ fromAddress=wallet.addresses[0].address_id,
191
+ )
192
+
193
+ if kwargs.get("routingStrategy"):
194
+ params.routingStrategy = kwargs["routingStrategy"]
195
+
196
+ async with httpx.AsyncClient() as client:
197
+ try:
198
+ # Send the GET request
199
+ response = await client.get(
200
+ url, headers=headers, params=params.model_dump(exclude_none=True)
201
+ )
202
+ response.raise_for_status()
203
+
204
+ # Map the response JSON into the ApprovalsResponse model
205
+ json_dict = response.json()[:50]
206
+ res = [WalletAllowance(**item) for item in json_dict]
207
+
208
+ # Return the parsed response
209
+ return EnsoGetApprovalsOutput(res=res)
210
+ except httpx.RequestError as req_err:
211
+ raise ToolException(
212
+ f"request error from Enso API: {req_err}"
213
+ ) from req_err
214
+ except httpx.HTTPStatusError as http_err:
215
+ raise ToolException(
216
+ f"http error from Enso API: {http_err}"
217
+ ) from http_err
218
+ except Exception as e:
219
+ raise ToolException(f"error from Enso API: {e}") from e
220
+
221
+
222
+ class EnsoWalletApproveInput(BaseModel):
223
+ """
224
+ Input model for approve the wallet.
225
+ """
226
+
227
+ tokenAddress: str = Field(description="ERC20 token address of the token to approve")
228
+ amount: int = Field(description="Amount of tokens to approve in wei")
229
+ chainId: int = Field(
230
+ default_chain_id, description="Chain ID of the blockchain network"
231
+ )
232
+ routingStrategy: Literal["ensowallet", "router", "delegate"] | None = Field(
233
+ None, description="Routing strategy to use"
234
+ )
235
+
236
+
237
+ class EnsoWalletApproveOutput(BaseModel):
238
+ """
239
+ Output model for approve token for the wallet.
240
+ """
241
+
242
+ gas: str | None = Field(None, description="The gas estimate for the transaction")
243
+ token: str | None = Field(None, description="The token address to approve")
244
+ amount: str | None = Field(None, description="The amount of tokens to approve")
245
+ spender: str | None = Field(None, description="The spender address to approve")
246
+
247
+
248
+ class EnsoWalletApproveArtifact(BaseModel):
249
+ """
250
+ Output model for approve token for the wallet.
251
+ """
252
+
253
+ tx: object | None = Field(None, description="The tx object to use in `ethers`")
254
+ txHash: str | None = Field(None, description="The transaction hash")
255
+
256
+
257
+ class EnsoWalletApprove(EnsoBaseTool):
258
+ """
259
+ This tool is used specifically for broadcasting a ERC20 token spending approval transaction to the network.
260
+ It should only be used when the user explicitly requests to broadcast an approval transaction with a specific amount for a certain token.
261
+
262
+ **Example Usage:**
263
+
264
+ "Broadcast an approval transaction for 10 USDC to the wallet."
265
+
266
+ **Important:**
267
+ - This tool should be used with extreme caution.
268
+ - Approving token spending grants another account permission to spend your tokens.
269
+
270
+ Attributes:
271
+ name (str): Name of the tool, specifically "enso_wallet_approve".
272
+ description (str): Comprehensive description of the tool's purpose and functionality.
273
+ args_schema (Type[BaseModel]): Schema for input arguments, specifying expected parameters.
274
+ """
275
+
276
+ name: str = "enso_wallet_approve"
277
+ description: str = "This tool is used specifically for broadcasting a ERC20 token spending approval transaction to the network. It should only be used when the user explicitly requests to broadcast an approval transaction with a specific amount for a certain token."
278
+ args_schema: Type[BaseModel] = EnsoWalletApproveInput
279
+ response_format: str = "content_and_artifact"
280
+
281
+ # def _run(
282
+ # self,
283
+ # tokenAddress: str,
284
+ # amount: int,
285
+ # chainId: int = default_chain_id,
286
+ # **kwargs,
287
+ # ) -> Tuple[EnsoBroadcastWalletApproveOutput, EnsoBroadcastWalletApproveArtifact]:
288
+ # """Run the tool to approve enso router for a wallet.
289
+
290
+ # Returns:
291
+ # Tuple[EnsoBroadcastWalletApproveOutput, EnsoBroadcastWalletApproveArtifact]: A structured output containing the result of token approval.
292
+
293
+ # Raises:
294
+ # Exception: If there's an error accessing the Enso API.
295
+ # """
296
+ # raise NotImplementedError("Use _arun instead")
297
+
298
+ async def _arun(
299
+ self,
300
+ tokenAddress: str,
301
+ amount: int,
302
+ config: RunnableConfig,
303
+ chainId: int = default_chain_id,
304
+ **kwargs,
305
+ ) -> Tuple[EnsoWalletApproveOutput, EnsoWalletApproveArtifact]:
306
+ """
307
+ Run the tool to approve enso router for a wallet.
308
+
309
+ Args:
310
+ tokenAddress (str): ERC20 token address of the token to approve.
311
+ amount (int): Amount of tokens to approve in wei.
312
+ chainId (int): Chain ID of the blockchain network.
313
+ **kwargs: optional kwargs for the tool with args schema defined in EnsoGetApproveInput.
314
+
315
+ Returns:
316
+ Tuple[EnsoBroadcastWalletApproveOutput, EnsoBroadcastWalletApproveArtifact]: The list of approve transaction output or an error message.
317
+ """
318
+ url = f"{base_url}/api/v1/wallet/approve"
319
+ context: SkillContext = self.context_from_config(config)
320
+ api_token = self.get_api_token(context)
321
+ chain_provider = self.get_chain_provider(context)
322
+ wallet = await self.get_wallet(context)
323
+
324
+ headers = {
325
+ "accept": "application/json",
326
+ "Authorization": f"Bearer {api_token}",
327
+ }
328
+
329
+ from_address = wallet.addresses[0].address_id
330
+
331
+ params = EnsoWalletApproveInput(
332
+ tokenAddress=tokenAddress,
333
+ amount=amount,
334
+ chainId=chainId,
335
+ )
336
+
337
+ if kwargs.get("routingStrategy"):
338
+ params.routingStrategy = kwargs["routingStrategy"]
339
+
340
+ params = params.model_dump(exclude_none=True)
341
+
342
+ params["fromAddress"] = from_address
343
+
344
+ with httpx.Client() as client:
345
+ try:
346
+ # Send the GET request
347
+ response = client.get(url, headers=headers, params=params)
348
+ response.raise_for_status()
349
+
350
+ # Map the response JSON into the WalletApproveTransaction model
351
+ json_dict = response.json()
352
+ content = EnsoWalletApproveOutput(**json_dict)
353
+ artifact = EnsoWalletApproveArtifact(**json_dict)
354
+
355
+ rpc_url = chain_provider.get_chain_config_by_id(chainId).rpc_url
356
+ contract = EvmContractWrapper(rpc_url, ABI_ERC20, artifact.tx)
357
+
358
+ fn, fn_args = contract.fn_and_args
359
+ fn_args["value"] = str(fn_args["value"])
360
+
361
+ invocation = wallet.invoke_contract(
362
+ contract_address=contract.dst_addr,
363
+ method=fn.fn_name,
364
+ abi=ABI_ERC20,
365
+ args=fn_args,
366
+ ).wait()
367
+
368
+ artifact.txHash = invocation.transaction.transaction_hash
369
+
370
+ # Return the parsed response
371
+ return (content, artifact)
372
+ except httpx.RequestError as req_err:
373
+ raise ToolException(
374
+ f"request error from Enso API: {req_err}"
375
+ ) from req_err
376
+ except httpx.HTTPStatusError as http_err:
377
+ raise ToolException(
378
+ f"http error from Enso API: {http_err}"
379
+ ) from http_err
380
+ except Exception as e:
381
+ raise ToolException(f"error from Enso API: {e}") from e
@@ -0,0 +1,63 @@
1
+ # GitHub Skill
2
+
3
+ This skill enables agents to search GitHub for repositories, users, and code using GitHub's public API endpoints.
4
+
5
+ ## Features
6
+
7
+ - Search GitHub repositories by name, description, or topics
8
+ - Search GitHub users by username or real name
9
+ - Search code snippets across GitHub repositories
10
+ - No authentication required (uses public API endpoints)
11
+ - Rate limit aware (respects GitHub's public API limits)
12
+
13
+ ## Configuration
14
+
15
+ Add the GitHub skill to your agent's configuration:
16
+
17
+ ```yaml
18
+ skills:
19
+ github:
20
+ states:
21
+ github_search: public # or private if you want to restrict access
22
+ ```
23
+
24
+ ## Usage Examples
25
+
26
+ The agent can use the GitHub skill to answer questions like:
27
+
28
+ - "Find repositories about blockchain development"
29
+ - "Search for users who work on web3 projects"
30
+ - "Find code examples of smart contracts in Solidity"
31
+ - "Show me popular Python machine learning repositories"
32
+ - "Find developers who contribute to Ethereum"
33
+
34
+ ## Rate Limits
35
+
36
+ The skill uses GitHub's public API which has the following rate limits:
37
+ - 60 requests per hour per IP address
38
+ - No authentication required
39
+ - Results are limited to public repositories and users
40
+
41
+ ## Implementation Details
42
+
43
+ The skill uses the following GitHub API endpoints:
44
+ - `/search/repositories` - For searching repositories
45
+ - `/search/users` - For searching users
46
+ - `/search/code` - For searching code
47
+
48
+ Each search result includes:
49
+ - For repositories: name, description, language, stars count, and URL
50
+ - For users: username, name, bio, and profile URL
51
+ - For code: repository name, file path, and URL
52
+
53
+ ## Error Handling
54
+
55
+ The skill handles various error cases:
56
+ - API rate limits
57
+ - Network errors
58
+ - Invalid queries
59
+ - No results found
60
+
61
+ ## Logging
62
+
63
+ All operations are logged with the prefix `github_search.py:` for easy debugging and monitoring.