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,135 @@
1
+ """Base class for all DeFi Llama tools."""
2
+
3
+ from datetime import datetime, timedelta, timezone
4
+ from typing import Type
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+ from intentkit.abstracts.skill import SkillStoreABC
9
+ from intentkit.skills.base import IntentKitSkill, SkillContext
10
+ from intentkit.skills.defillama.config.chains import (
11
+ get_chain_from_alias,
12
+ )
13
+
14
+ DEFILLAMA_BASE_URL = "https://api.llama.fi"
15
+
16
+
17
+ class DefiLlamaBaseTool(IntentKitSkill):
18
+ """Base class for DeFi Llama tools.
19
+
20
+ This class provides common functionality for all DeFi Llama API tools:
21
+ - Rate limiting
22
+ - State management
23
+ - Chain validation
24
+ - Error handling
25
+ """
26
+
27
+ name: str = Field(description="The name of the tool")
28
+ description: str = Field(description="A description of what the tool does")
29
+ args_schema: Type[BaseModel]
30
+ skill_store: SkillStoreABC = Field(
31
+ description="The skill store for persisting data"
32
+ )
33
+ base_url: str = Field(
34
+ default=DEFILLAMA_BASE_URL, description="Base URL for DeFi Llama API"
35
+ )
36
+
37
+ @property
38
+ def category(self) -> str:
39
+ return "defillama"
40
+
41
+ async def check_rate_limit(
42
+ self, context: SkillContext, max_requests: int = 30, interval: int = 5
43
+ ) -> tuple[bool, str | None]:
44
+ """Check if the rate limit has been exceeded.
45
+
46
+ Args:
47
+ context: Skill context
48
+ max_requests: Maximum requests allowed in the interval (default: 30)
49
+ interval: Time interval in minutes (default: 5)
50
+
51
+ Returns:
52
+ Rate limit status and error message if limited
53
+ """
54
+ rate_limit = await self.skill_store.get_agent_skill_data(
55
+ context.agent.id, self.name, "rate_limit"
56
+ )
57
+ current_time = datetime.now(tz=timezone.utc)
58
+
59
+ if (
60
+ rate_limit
61
+ and rate_limit.get("reset_time")
62
+ and rate_limit.get("count") is not None
63
+ and datetime.fromisoformat(rate_limit["reset_time"]) > current_time
64
+ ):
65
+ if rate_limit["count"] >= max_requests:
66
+ return True, "Rate limit exceeded"
67
+
68
+ rate_limit["count"] += 1
69
+ await self.skill_store.save_agent_skill_data(
70
+ context.agent.id, self.name, "rate_limit", rate_limit
71
+ )
72
+ return False, None
73
+
74
+ new_rate_limit = {
75
+ "count": 1,
76
+ "reset_time": (current_time + timedelta(minutes=interval)).isoformat(),
77
+ }
78
+ await self.skill_store.save_agent_skill_data(
79
+ context.agent.id, self.name, "rate_limit", new_rate_limit
80
+ )
81
+ return False, None
82
+
83
+ async def validate_chain(self, chain: str | None) -> tuple[bool, str | None]:
84
+ """Validate and normalize chain parameter.
85
+
86
+ Args:
87
+ chain: Chain name to validate
88
+
89
+ Returns:
90
+ Tuple of (is_valid, normalized_chain_name)
91
+ """
92
+ if chain is None:
93
+ return True, None
94
+
95
+ normalized_chain = get_chain_from_alias(chain)
96
+ if normalized_chain is None:
97
+ return False, None
98
+
99
+ return True, normalized_chain
100
+
101
+ def get_endpoint_url(self, endpoint: str) -> str:
102
+ """Construct full endpoint URL.
103
+
104
+ Args:
105
+ endpoint: API endpoint path
106
+
107
+ Returns:
108
+ Complete URL for the endpoint
109
+ """
110
+ return f"{self.base_url}/{endpoint.lstrip('/')}"
111
+
112
+ def format_error_response(self, status_code: int, message: str) -> dict:
113
+ """Format error responses consistently.
114
+
115
+ Args:
116
+ status_code: HTTP status code
117
+ message: Error message
118
+
119
+ Returns:
120
+ Formatted error response dictionary
121
+ """
122
+ return {
123
+ "error": True,
124
+ "status_code": status_code,
125
+ "message": message,
126
+ "timestamp": datetime.now(tz=timezone.utc).isoformat(),
127
+ }
128
+
129
+ def get_current_timestamp(self) -> int:
130
+ """Get current timestamp in UTC.
131
+
132
+ Returns:
133
+ Current Unix timestamp
134
+ """
135
+ return int(datetime.now(tz=timezone.utc).timestamp())
File without changes
@@ -0,0 +1,116 @@
1
+ """Tool for fetching batch historical token prices via DeFi Llama API."""
2
+
3
+ from typing import Dict, List, Optional, Type
4
+
5
+ from langchain.schema.runnable import RunnableConfig
6
+ from pydantic import BaseModel, Field
7
+
8
+ from intentkit.skills.defillama.api import fetch_batch_historical_prices
9
+ from intentkit.skills.defillama.base import DefiLlamaBaseTool
10
+
11
+ FETCH_BATCH_HISTORICAL_PRICES_PROMPT = """
12
+ This tool fetches historical token prices from DeFi Llama for multiple tokens at multiple timestamps.
13
+ Provide a dictionary mapping token identifiers to lists of timestamps in the format:
14
+ - Ethereum tokens: {"ethereum:0x...": [timestamp1, timestamp2]}
15
+ - Other chains: {"chainname:0x...": [timestamp1, timestamp2]}
16
+ - CoinGecko IDs: {"coingecko:bitcoin": [timestamp1, timestamp2]}
17
+ Returns historical price data including:
18
+ - Prices in USD at each timestamp
19
+ - Token symbols
20
+ - Confidence scores for price data
21
+ Uses a 4-hour search window around each specified timestamp.
22
+ """
23
+
24
+
25
+ class HistoricalPricePoint(BaseModel):
26
+ """Model representing a single historical price point."""
27
+
28
+ timestamp: int = Field(..., description="Unix timestamp of the price data")
29
+ price: float = Field(..., description="Token price in USD at the timestamp")
30
+ confidence: float = Field(..., description="Confidence score for the price data")
31
+
32
+
33
+ class TokenPriceHistory(BaseModel):
34
+ """Model representing historical price data for a single token."""
35
+
36
+ symbol: str = Field(..., description="Token symbol")
37
+ prices: List[HistoricalPricePoint] = Field(
38
+ ..., description="List of historical price points"
39
+ )
40
+
41
+
42
+ class FetchBatchHistoricalPricesInput(BaseModel):
43
+ """Input schema for fetching batch historical token prices."""
44
+
45
+ coins_timestamps: Dict[str, List[int]] = Field(
46
+ ..., description="Dictionary mapping token identifiers to lists of timestamps"
47
+ )
48
+
49
+
50
+ class FetchBatchHistoricalPricesResponse(BaseModel):
51
+ """Response schema for batch historical token prices."""
52
+
53
+ coins: Dict[str, TokenPriceHistory] = Field(
54
+ default_factory=dict,
55
+ description="Historical token prices keyed by token identifier",
56
+ )
57
+ error: Optional[str] = Field(None, description="Error message if any")
58
+
59
+
60
+ class DefiLlamaFetchBatchHistoricalPrices(DefiLlamaBaseTool):
61
+ """Tool for fetching batch historical token prices from DeFi Llama.
62
+
63
+ This tool retrieves historical prices for multiple tokens at multiple
64
+ timestamps, using a 4-hour search window around each requested time.
65
+
66
+ Example:
67
+ prices_tool = DefiLlamaFetchBatchHistoricalPrices(
68
+ skill_store=store,
69
+ agent_id="agent_123",
70
+ agent_store=agent_store
71
+ )
72
+ result = await prices_tool._arun(
73
+ coins_timestamps={
74
+ "ethereum:0x...": [1640995200, 1641081600], # Jan 1-2, 2022
75
+ "coingecko:bitcoin": [1640995200, 1641081600]
76
+ }
77
+ )
78
+ """
79
+
80
+ name: str = "defillama_fetch_batch_historical_prices"
81
+ description: str = FETCH_BATCH_HISTORICAL_PRICES_PROMPT
82
+ args_schema: Type[BaseModel] = FetchBatchHistoricalPricesInput
83
+
84
+ async def _arun(
85
+ self, config: RunnableConfig, coins_timestamps: Dict[str, List[int]]
86
+ ) -> FetchBatchHistoricalPricesResponse:
87
+ """Fetch historical prices for the given tokens at specified timestamps.
88
+
89
+ Args:
90
+ config: Runnable configuration
91
+ coins_timestamps: Dictionary mapping token identifiers to lists of timestamps
92
+
93
+ Returns:
94
+ FetchBatchHistoricalPricesResponse containing historical token prices or error
95
+ """
96
+ try:
97
+ # Check rate limiting
98
+ context = self.context_from_config(config)
99
+ is_rate_limited, error_msg = await self.check_rate_limit(context)
100
+ if is_rate_limited:
101
+ return FetchBatchHistoricalPricesResponse(error=error_msg)
102
+
103
+ # Fetch batch historical prices from API
104
+ result = await fetch_batch_historical_prices(
105
+ coins_timestamps=coins_timestamps
106
+ )
107
+
108
+ # Check for API errors
109
+ if isinstance(result, dict) and "error" in result:
110
+ return FetchBatchHistoricalPricesResponse(error=result["error"])
111
+
112
+ # Return the response matching the API structure
113
+ return FetchBatchHistoricalPricesResponse(coins=result["coins"])
114
+
115
+ except Exception as e:
116
+ return FetchBatchHistoricalPricesResponse(error=str(e))
@@ -0,0 +1,98 @@
1
+ """Tool for fetching current block data via DeFi Llama API."""
2
+
3
+ from typing import Optional, Type
4
+
5
+ from langchain.schema.runnable import RunnableConfig
6
+ from pydantic import BaseModel, Field
7
+
8
+ from intentkit.skills.defillama.api import fetch_block
9
+ from intentkit.skills.defillama.base import DefiLlamaBaseTool
10
+
11
+ FETCH_BLOCK_PROMPT = """
12
+ This tool fetches current block data from DeFi Llama for a specific chain.
13
+ Provide:
14
+ - Chain name (e.g. "ethereum", "bsc", "solana")
15
+ Returns:
16
+ - Block height
17
+ - Block timestamp
18
+ """
19
+
20
+
21
+ class BlockData(BaseModel):
22
+ """Model representing block data."""
23
+
24
+ height: int = Field(..., description="Block height number")
25
+ timestamp: int = Field(..., description="Unix timestamp of the block")
26
+
27
+
28
+ class FetchBlockInput(BaseModel):
29
+ """Input schema for fetching block data."""
30
+
31
+ chain: str = Field(..., description="Chain name to fetch block data for")
32
+
33
+
34
+ class FetchBlockResponse(BaseModel):
35
+ """Response schema for block data."""
36
+
37
+ chain: str = Field(..., description="Normalized chain name")
38
+ height: Optional[int] = Field(None, description="Block height number")
39
+ timestamp: Optional[int] = Field(None, description="Unix timestamp of the block")
40
+ error: Optional[str] = Field(None, description="Error message if any")
41
+
42
+
43
+ class DefiLlamaFetchBlock(DefiLlamaBaseTool):
44
+ """Tool for fetching current block data from DeFi Llama.
45
+
46
+ This tool retrieves current block data for a specific chain.
47
+
48
+ Example:
49
+ block_tool = DefiLlamaFetchBlock(
50
+ skill_store=store,
51
+ agent_id="agent_123",
52
+ agent_store=agent_store
53
+ )
54
+ result = await block_tool._arun(chain="ethereum")
55
+ """
56
+
57
+ name: str = "defillama_fetch_block"
58
+ description: str = FETCH_BLOCK_PROMPT
59
+ args_schema: Type[BaseModel] = FetchBlockInput
60
+
61
+ async def _arun(self, config: RunnableConfig, chain: str) -> FetchBlockResponse:
62
+ """Fetch current block data for the given chain.
63
+
64
+ Args:
65
+ config: Runnable configuration
66
+ chain: Chain name to fetch block data for
67
+
68
+ Returns:
69
+ FetchBlockResponse containing block data or error
70
+ """
71
+ try:
72
+ # Validate chain parameter
73
+ is_valid, normalized_chain = await self.validate_chain(chain)
74
+ if not is_valid or normalized_chain is None:
75
+ return FetchBlockResponse(chain=chain, error=f"Invalid chain: {chain}")
76
+
77
+ # Check rate limiting
78
+ context = self.context_from_config(config)
79
+ is_rate_limited, error_msg = await self.check_rate_limit(context)
80
+ if is_rate_limited:
81
+ return FetchBlockResponse(chain=normalized_chain, error=error_msg)
82
+
83
+ # Fetch block data from API
84
+ result = await fetch_block(chain=normalized_chain)
85
+
86
+ # Check for API errors
87
+ if isinstance(result, dict) and "error" in result:
88
+ return FetchBlockResponse(chain=normalized_chain, error=result["error"])
89
+
90
+ # Return the response matching the API structure
91
+ return FetchBlockResponse(
92
+ chain=normalized_chain,
93
+ height=result["height"],
94
+ timestamp=result["timestamp"],
95
+ )
96
+
97
+ except Exception as e:
98
+ return FetchBlockResponse(chain=chain, error=str(e))
@@ -0,0 +1,105 @@
1
+ """Tool for fetching token prices via DeFi Llama API."""
2
+
3
+ from typing import Dict, List, Optional, Type
4
+
5
+ from langchain.schema.runnable import RunnableConfig
6
+ from pydantic import BaseModel, Field
7
+
8
+ from intentkit.skills.defillama.api import fetch_current_prices
9
+ from intentkit.skills.defillama.base import DefiLlamaBaseTool
10
+
11
+ FETCH_PRICES_PROMPT = """
12
+ This tool fetches current token prices from DeFi Llama with a 4-hour search window.
13
+ Provide a list of token identifiers in the format:
14
+ - Ethereum tokens: 'ethereum:0x...'
15
+ - Other chains: 'chainname:0x...'
16
+ - CoinGecko IDs: 'coingecko:bitcoin'
17
+ Returns price data including:
18
+ - Current price in USD
19
+ - Token symbol
20
+ - Price confidence score
21
+ - Token decimals (if available)
22
+ - Last update timestamp
23
+ """
24
+
25
+
26
+ class TokenPrice(BaseModel):
27
+ """Model representing token price data."""
28
+
29
+ price: float = Field(..., description="Current token price in USD")
30
+ symbol: str = Field(..., description="Token symbol")
31
+ timestamp: int = Field(..., description="Unix timestamp of last price update")
32
+ confidence: float = Field(..., description="Confidence score for the price data")
33
+ decimals: Optional[int] = Field(None, description="Token decimals, if available")
34
+
35
+
36
+ class FetchCurrentPricesInput(BaseModel):
37
+ """Input schema for fetching current token prices with a 4-hour search window."""
38
+
39
+ coins: List[str] = Field(
40
+ ...,
41
+ description="List of token identifiers (e.g. 'ethereum:0x...', 'coingecko:ethereum')",
42
+ )
43
+
44
+
45
+ class FetchCurrentPricesResponse(BaseModel):
46
+ """Response schema for current token prices."""
47
+
48
+ coins: Dict[str, TokenPrice] = Field(
49
+ default_factory=dict, description="Token prices keyed by token identifier"
50
+ )
51
+ error: Optional[str] = Field(None, description="Error message if any")
52
+
53
+
54
+ class DefiLlamaFetchCurrentPrices(DefiLlamaBaseTool):
55
+ """Tool for fetching current token prices from DeFi Llama.
56
+
57
+ This tool retrieves current prices for multiple tokens in a single request,
58
+ using a 4-hour search window to ensure fresh data.
59
+
60
+ Example:
61
+ prices_tool = DefiLlamaFetchCurrentPrices(
62
+ skill_store=store,
63
+ agent_id="agent_123",
64
+ agent_store=agent_store
65
+ )
66
+ result = await prices_tool._arun(
67
+ coins=["ethereum:0x...", "coingecko:bitcoin"]
68
+ )
69
+ """
70
+
71
+ name: str = "defillama_fetch_current_prices"
72
+ description: str = FETCH_PRICES_PROMPT
73
+ args_schema: Type[BaseModel] = FetchCurrentPricesInput
74
+
75
+ async def _arun(
76
+ self, config: RunnableConfig, coins: List[str]
77
+ ) -> FetchCurrentPricesResponse:
78
+ """Fetch current prices for the given tokens.
79
+
80
+ Args:
81
+ config: Runnable configuration
82
+ coins: List of token identifiers to fetch prices for
83
+
84
+ Returns:
85
+ FetchCurrentPricesResponse containing token prices or error
86
+ """
87
+ try:
88
+ # Check rate limiting
89
+ context = self.context_from_config(config)
90
+ is_rate_limited, error_msg = await self.check_rate_limit(context)
91
+ if is_rate_limited:
92
+ return FetchCurrentPricesResponse(error=error_msg)
93
+
94
+ # Fetch prices from API
95
+ result = await fetch_current_prices(coins=coins)
96
+
97
+ # Check for API errors
98
+ if isinstance(result, dict) and "error" in result:
99
+ return FetchCurrentPricesResponse(error=result["error"])
100
+
101
+ # Return the response matching the API structure
102
+ return FetchCurrentPricesResponse(coins=result["coins"])
103
+
104
+ except Exception as e:
105
+ return FetchCurrentPricesResponse(error=str(e))
@@ -0,0 +1,100 @@
1
+ """Tool for fetching first recorded token prices via DeFi Llama API."""
2
+
3
+ from typing import Dict, List, Optional, Type
4
+
5
+ from langchain.schema.runnable import RunnableConfig
6
+ from pydantic import BaseModel, Field
7
+
8
+ from intentkit.skills.defillama.api import fetch_first_price
9
+ from intentkit.skills.defillama.base import DefiLlamaBaseTool
10
+
11
+ FETCH_FIRST_PRICE_PROMPT = """
12
+ This tool fetches the first recorded price data from DeFi Llama for multiple tokens.
13
+ Provide a list of token identifiers in the format:
14
+ - Ethereum tokens: 'ethereum:0x...'
15
+ - Other chains: 'chainname:0x...'
16
+ - CoinGecko IDs: 'coingecko:bitcoin'
17
+ Returns first price data including:
18
+ - Initial price in USD
19
+ - Token symbol
20
+ - Timestamp of first recorded price
21
+ """
22
+
23
+
24
+ class FirstPriceData(BaseModel):
25
+ """Model representing first price data for a single token."""
26
+
27
+ symbol: str = Field(..., description="Token symbol")
28
+ price: float = Field(..., description="First recorded price in USD")
29
+ timestamp: int = Field(..., description="Unix timestamp of first recorded price")
30
+
31
+
32
+ class FetchFirstPriceInput(BaseModel):
33
+ """Input schema for fetching first token prices."""
34
+
35
+ coins: List[str] = Field(
36
+ ..., description="List of token identifiers to fetch first prices for"
37
+ )
38
+
39
+
40
+ class FetchFirstPriceResponse(BaseModel):
41
+ """Response schema for first token prices."""
42
+
43
+ coins: Dict[str, FirstPriceData] = Field(
44
+ default_factory=dict, description="First price data keyed by token identifier"
45
+ )
46
+ error: Optional[str] = Field(None, description="Error message if any")
47
+
48
+
49
+ class DefiLlamaFetchFirstPrice(DefiLlamaBaseTool):
50
+ """Tool for fetching first recorded token prices from DeFi Llama.
51
+
52
+ This tool retrieves the first price data recorded for multiple tokens,
53
+ including the initial price, symbol, and timestamp.
54
+
55
+ Example:
56
+ first_price_tool = DefiLlamaFetchFirstPrice(
57
+ skill_store=store,
58
+ agent_id="agent_123",
59
+ agent_store=agent_store
60
+ )
61
+ result = await first_price_tool._arun(
62
+ coins=["ethereum:0x...", "coingecko:ethereum"]
63
+ )
64
+ """
65
+
66
+ name: str = "defillama_fetch_first_price"
67
+ description: str = FETCH_FIRST_PRICE_PROMPT
68
+ args_schema: Type[BaseModel] = FetchFirstPriceInput
69
+
70
+ async def _arun(
71
+ self, config: RunnableConfig, coins: List[str]
72
+ ) -> FetchFirstPriceResponse:
73
+ """Fetch first recorded prices for the given tokens.
74
+
75
+ Args:
76
+ config: Runnable configuration
77
+ coins: List of token identifiers to fetch first prices for
78
+
79
+ Returns:
80
+ FetchFirstPriceResponse containing first price data or error
81
+ """
82
+ try:
83
+ # Check rate limiting
84
+ context = self.context_from_config(config)
85
+ is_rate_limited, error_msg = await self.check_rate_limit(context)
86
+ if is_rate_limited:
87
+ return FetchFirstPriceResponse(error=error_msg)
88
+
89
+ # Fetch first price data from API
90
+ result = await fetch_first_price(coins=coins)
91
+
92
+ # Check for API errors
93
+ if isinstance(result, dict) and "error" in result:
94
+ return FetchFirstPriceResponse(error=result["error"])
95
+
96
+ # Return the response matching the API structure
97
+ return FetchFirstPriceResponse(coins=result["coins"])
98
+
99
+ except Exception as e:
100
+ return FetchFirstPriceResponse(error=str(e))
@@ -0,0 +1,110 @@
1
+ """Tool for fetching historical token prices via DeFi Llama API."""
2
+
3
+ from typing import Dict, List, Optional, Type
4
+
5
+ from langchain.schema.runnable import RunnableConfig
6
+ from pydantic import BaseModel, Field
7
+
8
+ from intentkit.skills.defillama.api import fetch_historical_prices
9
+ from intentkit.skills.defillama.base import DefiLlamaBaseTool
10
+
11
+ FETCH_HISTORICAL_PRICES_PROMPT = """
12
+ This tool fetches historical token prices from DeFi Llama for a specific timestamp.
13
+ Provide a timestamp and list of token identifiers in the format:
14
+ - Ethereum tokens: 'ethereum:0x...'
15
+ - Other chains: 'chainname:0x...'
16
+ - CoinGecko IDs: 'coingecko:bitcoin'
17
+ Returns historical price data including:
18
+ - Price in USD at the specified time
19
+ - Token symbol
20
+ - Token decimals (if available)
21
+ - Actual timestamp of the price data
22
+ Uses a 4-hour search window around the specified timestamp.
23
+ """
24
+
25
+
26
+ class HistoricalTokenPrice(BaseModel):
27
+ """Model representing historical token price data."""
28
+
29
+ price: float = Field(..., description="Token price in USD at the specified time")
30
+ symbol: Optional[str] = Field(None, description="Token symbol")
31
+ timestamp: int = Field(..., description="Unix timestamp of the price data")
32
+ decimals: Optional[int] = Field(None, description="Token decimals, if available")
33
+
34
+
35
+ class FetchHistoricalPricesInput(BaseModel):
36
+ """Input schema for fetching historical token prices."""
37
+
38
+ timestamp: int = Field(
39
+ ..., description="Unix timestamp for historical price lookup"
40
+ )
41
+ coins: List[str] = Field(
42
+ ...,
43
+ description="List of token identifiers (e.g. 'ethereum:0x...', 'coingecko:ethereum')",
44
+ )
45
+
46
+
47
+ class FetchHistoricalPricesResponse(BaseModel):
48
+ """Response schema for historical token prices."""
49
+
50
+ coins: Dict[str, HistoricalTokenPrice] = Field(
51
+ default_factory=dict,
52
+ description="Historical token prices keyed by token identifier",
53
+ )
54
+ error: Optional[str] = Field(None, description="Error message if any")
55
+
56
+
57
+ class DefiLlamaFetchHistoricalPrices(DefiLlamaBaseTool):
58
+ """Tool for fetching historical token prices from DeFi Llama.
59
+
60
+ This tool retrieves historical prices for multiple tokens at a specific
61
+ timestamp, using a 4-hour search window around the requested time.
62
+
63
+ Example:
64
+ prices_tool = DefiLlamaFetchHistoricalPrices(
65
+ skill_store=store,
66
+ agent_id="agent_123",
67
+ agent_store=agent_store
68
+ )
69
+ result = await prices_tool._arun(
70
+ timestamp=1640995200, # Jan 1, 2022
71
+ coins=["ethereum:0x...", "coingecko:bitcoin"]
72
+ )
73
+ """
74
+
75
+ name: str = "defillama_fetch_historical_prices"
76
+ description: str = FETCH_HISTORICAL_PRICES_PROMPT
77
+ args_schema: Type[BaseModel] = FetchHistoricalPricesInput
78
+
79
+ async def _arun(
80
+ self, config: RunnableConfig, timestamp: int, coins: List[str]
81
+ ) -> FetchHistoricalPricesResponse:
82
+ """Fetch historical prices for the given tokens at the specified time.
83
+
84
+ Args:
85
+ config: Runnable configuration
86
+ timestamp: Unix timestamp for historical price lookup
87
+ coins: List of token identifiers to fetch prices for
88
+
89
+ Returns:
90
+ FetchHistoricalPricesResponse containing historical token prices or error
91
+ """
92
+ try:
93
+ # Check rate limiting
94
+ context = self.context_from_config(config)
95
+ is_rate_limited, error_msg = await self.check_rate_limit(context)
96
+ if is_rate_limited:
97
+ return FetchHistoricalPricesResponse(error=error_msg)
98
+
99
+ # Fetch historical prices from API
100
+ result = await fetch_historical_prices(timestamp=timestamp, coins=coins)
101
+
102
+ # Check for API errors
103
+ if isinstance(result, dict) and "error" in result:
104
+ return FetchHistoricalPricesResponse(error=result["error"])
105
+
106
+ # Return the response matching the API structure
107
+ return FetchHistoricalPricesResponse(coins=result["coins"])
108
+
109
+ except Exception as e:
110
+ return FetchHistoricalPricesResponse(error=str(e))