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,746 @@
1
+ import json
2
+ import logging
3
+ from datetime import datetime, timezone
4
+ from decimal import Decimal
5
+ from enum import Enum
6
+ from typing import Annotated, Any, Optional
7
+
8
+ from intentkit.models.app_setting import AppSetting
9
+ from intentkit.models.base import Base
10
+ from intentkit.models.db import get_session
11
+ from intentkit.models.redis import get_redis
12
+ from intentkit.utils.error import IntentKitLookUpError
13
+ from langchain_core.language_models import LanguageModelLike
14
+ from pydantic import BaseModel, ConfigDict, Field
15
+ from sqlalchemy import Boolean, Column, DateTime, Integer, Numeric, String, func, select
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ _credit_per_usdc = None
20
+
21
+
22
+ class LLMProvider(str, Enum):
23
+ OPENAI = "openai"
24
+ DEEPSEEK = "deepseek"
25
+ XAI = "xai"
26
+ ETERNAL = "eternal"
27
+ REIGENT = "reigent"
28
+ VENICE = "venice"
29
+
30
+ def display_name(self) -> str:
31
+ """Return user-friendly display name for the provider."""
32
+ display_names = {
33
+ self.OPENAI: "OpenAI",
34
+ self.DEEPSEEK: "DeepSeek",
35
+ self.XAI: "xAI",
36
+ self.ETERNAL: "Others",
37
+ self.REIGENT: "Others",
38
+ self.VENICE: "Others",
39
+ }
40
+ return display_names.get(self, self.value)
41
+
42
+
43
+ class LLMModelInfoTable(Base):
44
+ """Database table model for LLM model information."""
45
+
46
+ __tablename__ = "llm_models"
47
+
48
+ id = Column(String, primary_key=True)
49
+ name = Column(String, nullable=False)
50
+ provider = Column(String, nullable=False) # Stored as string enum value
51
+ enabled = Column(Boolean, nullable=False, default=True)
52
+ input_price = Column(
53
+ Numeric(22, 4), nullable=False
54
+ ) # Price per 1M input tokens in USD
55
+ output_price = Column(
56
+ Numeric(22, 4), nullable=False
57
+ ) # Price per 1M output tokens in USD
58
+ price_level = Column(Integer, nullable=True) # Price level rating from 1-5
59
+ context_length = Column(Integer, nullable=False) # Maximum context length in tokens
60
+ output_length = Column(Integer, nullable=False) # Maximum output length in tokens
61
+ intelligence = Column(Integer, nullable=False) # Intelligence rating from 1-5
62
+ speed = Column(Integer, nullable=False) # Speed rating from 1-5
63
+ supports_image_input = Column(Boolean, nullable=False, default=False)
64
+ supports_skill_calls = Column(Boolean, nullable=False, default=False)
65
+ supports_structured_output = Column(Boolean, nullable=False, default=False)
66
+ has_reasoning = Column(Boolean, nullable=False, default=False)
67
+ supports_search = Column(Boolean, nullable=False, default=False)
68
+ supports_temperature = Column(Boolean, nullable=False, default=True)
69
+ supports_frequency_penalty = Column(Boolean, nullable=False, default=True)
70
+ supports_presence_penalty = Column(Boolean, nullable=False, default=True)
71
+ api_base = Column(String, nullable=True) # Custom API base URL
72
+ timeout = Column(Integer, nullable=False, default=180) # Default timeout in seconds
73
+ created_at = Column(
74
+ DateTime(timezone=True),
75
+ nullable=False,
76
+ server_default=func.now(),
77
+ )
78
+ updated_at = Column(
79
+ DateTime(timezone=True),
80
+ nullable=False,
81
+ server_default=func.now(),
82
+ onupdate=lambda: datetime.now(timezone.utc),
83
+ )
84
+
85
+
86
+ class LLMModelInfo(BaseModel):
87
+ """Information about an LLM model."""
88
+
89
+ model_config = ConfigDict(
90
+ from_attributes=True,
91
+ use_enum_values=True,
92
+ json_encoders={datetime: lambda v: v.isoformat(timespec="milliseconds")},
93
+ )
94
+
95
+ id: str
96
+ name: str
97
+ provider: LLMProvider
98
+ enabled: bool = Field(default=True)
99
+ input_price: Decimal # Price per 1M input tokens in USD
100
+ output_price: Decimal # Price per 1M output tokens in USD
101
+ price_level: Optional[int] = Field(
102
+ default=None, ge=1, le=5
103
+ ) # Price level rating from 1-5
104
+ context_length: int # Maximum context length in tokens
105
+ output_length: int # Maximum output length in tokens
106
+ intelligence: int = Field(ge=1, le=5) # Intelligence rating from 1-5
107
+ speed: int = Field(ge=1, le=5) # Speed rating from 1-5
108
+ supports_image_input: bool = False # Whether the model supports image inputs
109
+ supports_skill_calls: bool = False # Whether the model supports skill/tool calls
110
+ supports_structured_output: bool = (
111
+ False # Whether the model supports structured output
112
+ )
113
+ has_reasoning: bool = False # Whether the model has strong reasoning capabilities
114
+ supports_search: bool = (
115
+ False # Whether the model supports native search functionality
116
+ )
117
+ supports_temperature: bool = (
118
+ True # Whether the model supports temperature parameter
119
+ )
120
+ supports_frequency_penalty: bool = (
121
+ True # Whether the model supports frequency_penalty parameter
122
+ )
123
+ supports_presence_penalty: bool = (
124
+ True # Whether the model supports presence_penalty parameter
125
+ )
126
+ api_base: Optional[str] = (
127
+ None # Custom API base URL if not using provider's default
128
+ )
129
+ timeout: int = 180 # Default timeout in seconds
130
+ created_at: Annotated[
131
+ datetime,
132
+ Field(
133
+ description="Timestamp when this data was created",
134
+ default=datetime.now(timezone.utc),
135
+ ),
136
+ ]
137
+ updated_at: Annotated[
138
+ datetime,
139
+ Field(
140
+ description="Timestamp when this data was updated",
141
+ default=datetime.now(timezone.utc),
142
+ ),
143
+ ]
144
+
145
+ @staticmethod
146
+ async def get(model_id: str) -> "LLMModelInfo":
147
+ """Get a model by ID with Redis caching.
148
+
149
+ The model info is cached in Redis for 3 minutes.
150
+
151
+ Args:
152
+ model_id: ID of the model to retrieve
153
+
154
+ Returns:
155
+ LLMModelInfo: The model info if found, None otherwise
156
+ """
157
+ try:
158
+ has_redis = True
159
+ # Redis cache key for model info
160
+ cache_key = f"intentkit:llm_model:{model_id}"
161
+ cache_ttl = 180 # 3 minutes in seconds
162
+
163
+ # Try to get from Redis cache first
164
+ redis = get_redis()
165
+ cached_data = await redis.get(cache_key)
166
+
167
+ if cached_data:
168
+ # If found in cache, deserialize and return
169
+ try:
170
+ return LLMModelInfo.model_validate_json(cached_data)
171
+ except (json.JSONDecodeError, TypeError):
172
+ # If cache is corrupted, invalidate it
173
+ await redis.delete(cache_key)
174
+ except Exception:
175
+ has_redis = False
176
+ logger.debug("No redis when get model info")
177
+
178
+ # If not in cache or cache is invalid, get from database
179
+ async with get_session() as session:
180
+ # Query the database for the model
181
+ stmt = select(LLMModelInfoTable).where(LLMModelInfoTable.id == model_id)
182
+ model = await session.scalar(stmt)
183
+
184
+ # If model exists in database, convert to LLMModelInfo model and cache it
185
+ if model:
186
+ # Convert provider string to enum
187
+ model_info = LLMModelInfo.model_validate(model)
188
+
189
+ # Cache the model in Redis
190
+ if has_redis:
191
+ await redis.set(
192
+ cache_key,
193
+ model_info.model_dump_json(),
194
+ ex=cache_ttl,
195
+ )
196
+
197
+ return model_info
198
+
199
+ # If not found in database, check AVAILABLE_MODELS
200
+ if model_id in AVAILABLE_MODELS:
201
+ model_info = AVAILABLE_MODELS[model_id]
202
+
203
+ # Cache the model in Redis
204
+ if has_redis:
205
+ await redis.set(cache_key, model_info.model_dump_json(), ex=cache_ttl)
206
+
207
+ return model_info
208
+
209
+ # Not found anywhere
210
+ raise IntentKitLookUpError(f"Model {model_id} not found")
211
+
212
+ async def calculate_cost(self, input_tokens: int, output_tokens: int) -> Decimal:
213
+ global _credit_per_usdc
214
+ if not _credit_per_usdc:
215
+ _credit_per_usdc = (await AppSetting.payment()).credit_per_usdc
216
+ """Calculate the cost for a given number of tokens."""
217
+ input_cost = (
218
+ _credit_per_usdc
219
+ * Decimal(input_tokens)
220
+ * self.input_price
221
+ / Decimal(1000000)
222
+ )
223
+ output_cost = (
224
+ _credit_per_usdc
225
+ * Decimal(output_tokens)
226
+ * self.output_price
227
+ / Decimal(1000000)
228
+ )
229
+ return input_cost + output_cost
230
+
231
+
232
+ # Define all available models
233
+ AVAILABLE_MODELS = {
234
+ # OpenAI models
235
+ "gpt-4o": LLMModelInfo(
236
+ id="gpt-4o",
237
+ name="GPT-4o",
238
+ provider=LLMProvider.OPENAI,
239
+ input_price=Decimal("2.50"), # per 1M input tokens
240
+ output_price=Decimal("10.00"), # per 1M output tokens
241
+ context_length=128000,
242
+ output_length=4096,
243
+ intelligence=4,
244
+ speed=3,
245
+ supports_image_input=True,
246
+ supports_skill_calls=True,
247
+ supports_structured_output=True,
248
+ supports_search=True,
249
+ supports_frequency_penalty=False,
250
+ supports_presence_penalty=False,
251
+ ),
252
+ "gpt-4o-mini": LLMModelInfo(
253
+ id="gpt-4o-mini",
254
+ name="GPT-4o Mini",
255
+ provider=LLMProvider.OPENAI,
256
+ input_price=Decimal("0.15"), # per 1M input tokens
257
+ output_price=Decimal("0.60"), # per 1M output tokens
258
+ context_length=128000,
259
+ output_length=4096,
260
+ intelligence=3,
261
+ speed=4,
262
+ supports_image_input=False,
263
+ supports_skill_calls=True,
264
+ supports_structured_output=True,
265
+ supports_search=True,
266
+ supports_frequency_penalty=False,
267
+ supports_presence_penalty=False,
268
+ ),
269
+ "gpt-4.1-nano": LLMModelInfo(
270
+ id="gpt-4.1-nano",
271
+ name="GPT-4.1 Nano",
272
+ provider=LLMProvider.OPENAI,
273
+ input_price=Decimal("0.1"), # per 1M input tokens
274
+ output_price=Decimal("0.4"), # per 1M output tokens
275
+ context_length=128000,
276
+ output_length=4096,
277
+ intelligence=3,
278
+ speed=5,
279
+ supports_image_input=False,
280
+ supports_skill_calls=True,
281
+ supports_structured_output=True,
282
+ supports_frequency_penalty=False,
283
+ supports_presence_penalty=False,
284
+ ),
285
+ "gpt-4.1-mini": LLMModelInfo(
286
+ id="gpt-4.1-mini",
287
+ name="GPT-4.1 Mini",
288
+ provider=LLMProvider.OPENAI,
289
+ input_price=Decimal("0.4"), # per 1M input tokens
290
+ output_price=Decimal("1.6"), # per 1M output tokens
291
+ context_length=128000,
292
+ output_length=4096,
293
+ intelligence=4,
294
+ speed=4,
295
+ supports_image_input=False,
296
+ supports_skill_calls=True,
297
+ supports_structured_output=True,
298
+ supports_search=True,
299
+ supports_frequency_penalty=False,
300
+ supports_presence_penalty=False,
301
+ ),
302
+ "gpt-4.1": LLMModelInfo(
303
+ id="gpt-4.1",
304
+ name="GPT-4.1",
305
+ provider=LLMProvider.OPENAI,
306
+ input_price=Decimal("2.00"), # per 1M input tokens
307
+ output_price=Decimal("8.00"), # per 1M output tokens
308
+ context_length=128000,
309
+ output_length=4096,
310
+ intelligence=5,
311
+ speed=3,
312
+ supports_image_input=True,
313
+ supports_skill_calls=True,
314
+ supports_structured_output=True,
315
+ supports_search=True,
316
+ supports_frequency_penalty=False,
317
+ supports_presence_penalty=False,
318
+ ),
319
+ "o4-mini": LLMModelInfo(
320
+ id="o4-mini",
321
+ name="OpenAI o4-mini",
322
+ provider=LLMProvider.OPENAI,
323
+ input_price=Decimal("1.10"), # per 1M input tokens
324
+ output_price=Decimal("4.40"), # per 1M output tokens
325
+ context_length=128000,
326
+ output_length=4096,
327
+ intelligence=4,
328
+ speed=3,
329
+ supports_image_input=False,
330
+ supports_skill_calls=True,
331
+ supports_structured_output=True,
332
+ has_reasoning=True, # Has strong reasoning capabilities
333
+ supports_temperature=False,
334
+ supports_frequency_penalty=False,
335
+ supports_presence_penalty=False,
336
+ ),
337
+ # Deepseek models
338
+ "deepseek-chat": LLMModelInfo(
339
+ id="deepseek-chat",
340
+ name="Deepseek V3 (0324)",
341
+ provider=LLMProvider.DEEPSEEK,
342
+ input_price=Decimal("0.27"),
343
+ output_price=Decimal("1.10"),
344
+ context_length=60000,
345
+ output_length=4096,
346
+ intelligence=4,
347
+ speed=3,
348
+ supports_image_input=False,
349
+ supports_skill_calls=True,
350
+ supports_structured_output=True,
351
+ api_base="https://api.deepseek.com",
352
+ timeout=300,
353
+ ),
354
+ "deepseek-reasoner": LLMModelInfo(
355
+ id="deepseek-reasoner",
356
+ name="Deepseek R1",
357
+ provider=LLMProvider.DEEPSEEK,
358
+ input_price=Decimal("0.55"),
359
+ output_price=Decimal("2.19"),
360
+ context_length=60000,
361
+ output_length=4096,
362
+ intelligence=4,
363
+ speed=2,
364
+ supports_image_input=False,
365
+ supports_skill_calls=True,
366
+ supports_structured_output=True,
367
+ has_reasoning=True, # Has strong reasoning capabilities
368
+ api_base="https://api.deepseek.com",
369
+ timeout=300,
370
+ ),
371
+ # XAI models
372
+ "grok-2": LLMModelInfo(
373
+ id="grok-2",
374
+ name="Grok 2",
375
+ provider=LLMProvider.XAI,
376
+ input_price=Decimal("2"),
377
+ output_price=Decimal("10"),
378
+ context_length=120000,
379
+ output_length=4096,
380
+ intelligence=3,
381
+ speed=3,
382
+ supports_image_input=False,
383
+ supports_skill_calls=True,
384
+ supports_structured_output=True,
385
+ timeout=180,
386
+ ),
387
+ "grok-3": LLMModelInfo(
388
+ id="grok-3",
389
+ name="Grok 3",
390
+ provider=LLMProvider.XAI,
391
+ input_price=Decimal("3"),
392
+ output_price=Decimal("15"),
393
+ context_length=131072,
394
+ output_length=4096,
395
+ intelligence=5,
396
+ speed=3,
397
+ supports_image_input=False,
398
+ supports_skill_calls=True,
399
+ supports_structured_output=True,
400
+ supports_search=True,
401
+ timeout=180,
402
+ ),
403
+ "grok-3-mini": LLMModelInfo(
404
+ id="grok-3-mini",
405
+ name="Grok 3 Mini",
406
+ provider=LLMProvider.XAI,
407
+ input_price=Decimal("0.3"),
408
+ output_price=Decimal("0.5"),
409
+ context_length=131072,
410
+ output_length=4096,
411
+ intelligence=5,
412
+ speed=3,
413
+ supports_image_input=False,
414
+ supports_skill_calls=True,
415
+ supports_structured_output=True,
416
+ has_reasoning=True, # Has strong reasoning capabilities
417
+ supports_frequency_penalty=False,
418
+ supports_presence_penalty=False, # Grok-3-mini doesn't support presence_penalty
419
+ timeout=180,
420
+ ),
421
+ # Eternal AI models
422
+ "eternalai": LLMModelInfo(
423
+ id="eternalai",
424
+ name="Eternal AI (Llama-3.3-70B)",
425
+ provider=LLMProvider.ETERNAL,
426
+ input_price=Decimal("0.25"),
427
+ output_price=Decimal("0.75"),
428
+ context_length=60000,
429
+ output_length=4096,
430
+ intelligence=4,
431
+ speed=3,
432
+ supports_image_input=False,
433
+ supports_skill_calls=True,
434
+ supports_structured_output=True,
435
+ api_base="https://api.eternalai.org/v1",
436
+ timeout=300,
437
+ ),
438
+ # Reigent models
439
+ "reigent": LLMModelInfo(
440
+ id="reigent",
441
+ name="REI Network",
442
+ provider=LLMProvider.REIGENT,
443
+ input_price=Decimal("0.50"), # Placeholder price, update with actual pricing
444
+ output_price=Decimal("1.50"), # Placeholder price, update with actual pricing
445
+ context_length=32000,
446
+ output_length=4096,
447
+ intelligence=4,
448
+ speed=3,
449
+ supports_image_input=False,
450
+ supports_skill_calls=True,
451
+ supports_structured_output=True,
452
+ supports_temperature=False,
453
+ supports_frequency_penalty=False,
454
+ supports_presence_penalty=False,
455
+ api_base="https://api.reisearch.box/v1",
456
+ timeout=300,
457
+ ),
458
+ # Venice models
459
+ "venice-uncensored": LLMModelInfo(
460
+ id="venice-uncensored",
461
+ name="Venice Uncensored",
462
+ provider=LLMProvider.VENICE,
463
+ input_price=Decimal("0.50"), # Placeholder price, update with actual pricing
464
+ output_price=Decimal("2.00"), # Placeholder price, update with actual pricing
465
+ context_length=32000,
466
+ output_length=4096,
467
+ intelligence=3,
468
+ speed=3,
469
+ supports_image_input=False,
470
+ supports_skill_calls=True,
471
+ supports_structured_output=True,
472
+ supports_temperature=True,
473
+ supports_frequency_penalty=False,
474
+ supports_presence_penalty=False,
475
+ api_base="https://api.venice.ai/api/v1",
476
+ timeout=300,
477
+ ),
478
+ "venice-llama-4-maverick-17b": LLMModelInfo(
479
+ id="venice-llama-4-maverick-17b",
480
+ name="Venice Llama-4 Maverick 17B",
481
+ provider=LLMProvider.VENICE,
482
+ input_price=Decimal("1.50"),
483
+ output_price=Decimal("6.00"),
484
+ context_length=32000,
485
+ output_length=4096,
486
+ intelligence=3,
487
+ speed=3,
488
+ supports_image_input=False,
489
+ supports_skill_calls=True,
490
+ supports_structured_output=True,
491
+ supports_temperature=True,
492
+ supports_frequency_penalty=False,
493
+ supports_presence_penalty=False,
494
+ api_base="https://api.venice.ai/api/v1",
495
+ timeout=300,
496
+ ),
497
+ }
498
+
499
+
500
+ class LLMModel(BaseModel):
501
+ """Base model for LLM configuration."""
502
+
503
+ model_name: str
504
+ temperature: float = 0.7
505
+ frequency_penalty: float = 0.0
506
+ presence_penalty: float = 0.0
507
+ info: LLMModelInfo
508
+
509
+ async def model_info(self) -> LLMModelInfo:
510
+ """Get the model information with caching.
511
+
512
+ First tries to get from cache, then database, then AVAILABLE_MODELS.
513
+ Raises ValueError if model is not found anywhere.
514
+ """
515
+ model_info = await LLMModelInfo.get(self.model_name)
516
+ return model_info
517
+
518
+ # This will be implemented by subclasses to return the appropriate LLM instance
519
+ async def create_instance(self, config: Any) -> LanguageModelLike:
520
+ """Create and return the LLM instance based on the configuration."""
521
+ raise NotImplementedError("Subclasses must implement create_instance")
522
+
523
+ async def get_token_limit(self) -> int:
524
+ """Get the token limit for this model."""
525
+ info = await self.model_info()
526
+ return info.context_length
527
+
528
+ async def calculate_cost(self, input_tokens: int, output_tokens: int) -> Decimal:
529
+ """Calculate the cost for a given number of tokens."""
530
+ info = await self.model_info()
531
+ return await info.calculate_cost(input_tokens, output_tokens)
532
+
533
+
534
+ class OpenAILLM(LLMModel):
535
+ """OpenAI LLM configuration."""
536
+
537
+ async def create_instance(self, config: Any) -> LanguageModelLike:
538
+ """Create and return a ChatOpenAI instance."""
539
+ from langchain_openai import ChatOpenAI
540
+
541
+ info = await self.model_info()
542
+
543
+ kwargs = {
544
+ "model_name": self.model_name,
545
+ "openai_api_key": config.openai_api_key,
546
+ "timeout": info.timeout,
547
+ }
548
+
549
+ # Add optional parameters based on model support
550
+ if info.supports_temperature:
551
+ kwargs["temperature"] = self.temperature
552
+
553
+ if info.supports_frequency_penalty:
554
+ kwargs["frequency_penalty"] = self.frequency_penalty
555
+
556
+ if info.supports_presence_penalty:
557
+ kwargs["presence_penalty"] = self.presence_penalty
558
+
559
+ if info.api_base:
560
+ kwargs["openai_api_base"] = info.api_base
561
+
562
+ logger.debug(f"Creating ChatOpenAI instance with kwargs: {kwargs}")
563
+
564
+ return ChatOpenAI(**kwargs)
565
+
566
+
567
+ class DeepseekLLM(LLMModel):
568
+ """Deepseek LLM configuration."""
569
+
570
+ async def create_instance(self, config: Any) -> LanguageModelLike:
571
+ """Create and return a ChatDeepseek instance."""
572
+
573
+ from langchain_openai import ChatOpenAI
574
+
575
+ info = await self.model_info()
576
+
577
+ kwargs = {
578
+ "model_name": self.model_name,
579
+ "openai_api_key": config.deepseek_api_key,
580
+ "timeout": info.timeout,
581
+ }
582
+
583
+ # Add optional parameters based on model support
584
+ if info.supports_temperature:
585
+ kwargs["temperature"] = self.temperature
586
+
587
+ if info.supports_frequency_penalty:
588
+ kwargs["frequency_penalty"] = self.frequency_penalty
589
+
590
+ if info.supports_presence_penalty:
591
+ kwargs["presence_penalty"] = self.presence_penalty
592
+
593
+ if info.api_base:
594
+ kwargs["openai_api_base"] = info.api_base
595
+
596
+ return ChatOpenAI(**kwargs)
597
+
598
+
599
+ class XAILLM(LLMModel):
600
+ """XAI (Grok) LLM configuration."""
601
+
602
+ async def create_instance(self, config: Any) -> LanguageModelLike:
603
+ """Create and return a ChatXAI instance."""
604
+
605
+ from langchain_xai import ChatXAI
606
+
607
+ info = await self.model_info()
608
+
609
+ kwargs = {
610
+ "model_name": self.model_name,
611
+ "xai_api_key": config.xai_api_key,
612
+ "timeout": info.timeout,
613
+ }
614
+
615
+ # Add optional parameters based on model support
616
+ if info.supports_temperature:
617
+ kwargs["temperature"] = self.temperature
618
+
619
+ if info.supports_frequency_penalty:
620
+ kwargs["frequency_penalty"] = self.frequency_penalty
621
+
622
+ if info.supports_presence_penalty:
623
+ kwargs["presence_penalty"] = self.presence_penalty
624
+
625
+ if self.model_name in ["grok-3", "grok-3-mini"]:
626
+ kwargs["search_parameters"] = {"mode": "auto"}
627
+
628
+ return ChatXAI(**kwargs)
629
+
630
+
631
+ class EternalLLM(LLMModel):
632
+ """Eternal AI LLM configuration."""
633
+
634
+ async def create_instance(self, config: Any) -> LanguageModelLike:
635
+ """Create and return a ChatOpenAI instance configured for Eternal AI."""
636
+ from langchain_openai import ChatOpenAI
637
+
638
+ info = await self.model_info()
639
+
640
+ # Override model name for Eternal AI
641
+ actual_model = "unsloth/Llama-3.3-70B-Instruct-bnb-4bit"
642
+
643
+ kwargs = {
644
+ "model_name": actual_model,
645
+ "openai_api_key": config.eternal_api_key,
646
+ "openai_api_base": info.api_base,
647
+ "timeout": info.timeout,
648
+ }
649
+
650
+ # Add optional parameters based on model support
651
+ if info.supports_temperature:
652
+ kwargs["temperature"] = self.temperature
653
+
654
+ if info.supports_frequency_penalty:
655
+ kwargs["frequency_penalty"] = self.frequency_penalty
656
+
657
+ if info.supports_presence_penalty:
658
+ kwargs["presence_penalty"] = self.presence_penalty
659
+
660
+ return ChatOpenAI(**kwargs)
661
+
662
+
663
+ class ReigentLLM(LLMModel):
664
+ """Reigent LLM configuration."""
665
+
666
+ async def create_instance(self, config: Any) -> LanguageModelLike:
667
+ """Create and return a ChatOpenAI instance configured for Reigent."""
668
+ from langchain_openai import ChatOpenAI
669
+
670
+ info = await self.model_info()
671
+
672
+ kwargs = {
673
+ "openai_api_key": config.reigent_api_key,
674
+ "openai_api_base": info.api_base,
675
+ "timeout": info.timeout,
676
+ "model_kwargs": {
677
+ # Override any specific parameters required for Reigent API
678
+ # The Reigent API requires 'tools' instead of 'functions' and might have some specific formatting requirements
679
+ },
680
+ }
681
+
682
+ return ChatOpenAI(**kwargs)
683
+
684
+
685
+ class VeniceLLM(LLMModel):
686
+ """Venice LLM configuration."""
687
+
688
+ async def create_instance(self, config: Any) -> LanguageModelLike:
689
+ """Create and return a ChatOpenAI instance configured for Venice."""
690
+ from langchain_openai import ChatOpenAI
691
+
692
+ info = await self.model_info()
693
+
694
+ kwargs = {
695
+ "openai_api_key": config.venice_api_key,
696
+ "openai_api_base": info.api_base,
697
+ "timeout": info.timeout,
698
+ }
699
+
700
+ return ChatOpenAI(**kwargs)
701
+
702
+
703
+ # Factory function to create the appropriate LLM model based on the model name
704
+ async def create_llm_model(
705
+ model_name: str,
706
+ temperature: float = 0.7,
707
+ frequency_penalty: float = 0.0,
708
+ presence_penalty: float = 0.0,
709
+ ) -> LLMModel:
710
+ """
711
+ Create an LLM model instance based on the model name.
712
+
713
+ Args:
714
+ model_name: The name of the model to use
715
+ temperature: The temperature parameter for the model
716
+ frequency_penalty: The frequency penalty parameter for the model
717
+ presence_penalty: The presence penalty parameter for the model
718
+
719
+ Returns:
720
+ An instance of a subclass of LLMModel
721
+ """
722
+ info = await LLMModelInfo.get(model_name)
723
+
724
+ base_params = {
725
+ "model_name": model_name,
726
+ "temperature": temperature,
727
+ "frequency_penalty": frequency_penalty,
728
+ "presence_penalty": presence_penalty,
729
+ "info": info,
730
+ }
731
+
732
+ provider = info.provider
733
+
734
+ if provider == LLMProvider.DEEPSEEK:
735
+ return DeepseekLLM(**base_params)
736
+ elif provider == LLMProvider.XAI:
737
+ return XAILLM(**base_params)
738
+ elif provider == LLMProvider.ETERNAL:
739
+ return EternalLLM(**base_params)
740
+ elif provider == LLMProvider.REIGENT:
741
+ return ReigentLLM(**base_params)
742
+ elif provider == LLMProvider.VENICE:
743
+ return VeniceLLM(**base_params)
744
+ else:
745
+ # Default to OpenAI
746
+ return OpenAILLM(**base_params)