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,581 @@
1
+ from datetime import datetime, timezone
2
+ from decimal import Decimal
3
+ from enum import Enum
4
+ from typing import Annotated, List, NotRequired, Optional, TypedDict
5
+
6
+ from epyxid import XID
7
+ from intentkit.models.base import Base
8
+ from intentkit.models.db import get_session
9
+ from pydantic import BaseModel, ConfigDict, Field
10
+ from sqlalchemy import (
11
+ Column,
12
+ DateTime,
13
+ Float,
14
+ Index,
15
+ Integer,
16
+ Numeric,
17
+ String,
18
+ desc,
19
+ func,
20
+ select,
21
+ update,
22
+ )
23
+ from sqlalchemy.dialects.postgresql import JSON, JSONB
24
+ from sqlalchemy.ext.asyncio import AsyncSession
25
+
26
+
27
+ class ChatMessageAttachmentType(str, Enum):
28
+ """Type of chat message attachment."""
29
+
30
+ LINK = "link"
31
+ IMAGE = "image"
32
+ FILE = "file"
33
+
34
+
35
+ class AuthorType(str, Enum):
36
+ """Type of message author."""
37
+
38
+ AGENT = "agent"
39
+ TRIGGER = "trigger"
40
+ SKILL = "skill"
41
+ TELEGRAM = "telegram"
42
+ TWITTER = "twitter"
43
+ WEB = "web"
44
+ SYSTEM = "system"
45
+ API = "api"
46
+
47
+
48
+ class ChatMessageAttachment(TypedDict):
49
+ """Chat message attachment model.
50
+
51
+ An attachment can be a link, image, or file that is associated with a chat message.
52
+ """
53
+
54
+ type: Annotated[
55
+ ChatMessageAttachmentType,
56
+ Field(
57
+ ...,
58
+ description="Type of the attachment (link, image, or file)",
59
+ examples=["link"],
60
+ ),
61
+ ]
62
+ url: Annotated[
63
+ str,
64
+ Field(
65
+ ...,
66
+ description="URL of the attachment",
67
+ examples=["https://example.com/image.jpg"],
68
+ ),
69
+ ]
70
+
71
+
72
+ class ChatMessageSkillCall(TypedDict):
73
+ """TypedDict for skill call details."""
74
+
75
+ id: NotRequired[str]
76
+ name: str
77
+ parameters: dict
78
+ success: bool
79
+ response: NotRequired[
80
+ str
81
+ ] # Optional response from the skill call, trimmed to 100 characters
82
+ error_message: NotRequired[str] # Optional error message from the skill call
83
+ credit_event_id: NotRequired[str] # ID of the credit event for this skill call
84
+ credit_cost: NotRequired[Decimal] # Credit cost for the skill call
85
+
86
+
87
+ class ChatMessageRequest(BaseModel):
88
+ """Request model for chat messages.
89
+
90
+ This model represents the request body for creating a new chat message.
91
+ It contains the necessary fields to identify the chat context, user,
92
+ and message content, along with optional attachments.
93
+ """
94
+
95
+ chat_id: Annotated[
96
+ str,
97
+ Field(
98
+ ...,
99
+ description="Unique identifier for the chat thread",
100
+ examples=["chat-123"],
101
+ min_length=1,
102
+ ),
103
+ ]
104
+ user_id: Annotated[
105
+ str,
106
+ Field(
107
+ ...,
108
+ description="Unique identifier of the user sending the message",
109
+ examples=["user-456"],
110
+ min_length=1,
111
+ ),
112
+ ]
113
+ message: Annotated[
114
+ str,
115
+ Field(
116
+ ...,
117
+ description="Content of the message",
118
+ examples=["Hello, how can you help me today?"],
119
+ min_length=1,
120
+ max_length=65535,
121
+ ),
122
+ ]
123
+ attachments: Annotated[
124
+ Optional[List[ChatMessageAttachment]],
125
+ Field(
126
+ None,
127
+ description="Optional list of attachments (links, images, or files)",
128
+ examples=[[{"type": "link", "url": "https://example.com"}]],
129
+ ),
130
+ ]
131
+
132
+ model_config = ConfigDict(
133
+ use_enum_values=True,
134
+ json_schema_extra={
135
+ "example": {
136
+ "chat_id": "chat-123",
137
+ "user_id": "user-456",
138
+ "message": "Hello, how can you help me today?",
139
+ "attachments": [
140
+ {
141
+ "type": "link",
142
+ "url": "https://example.com",
143
+ }
144
+ ],
145
+ }
146
+ },
147
+ )
148
+
149
+
150
+ class ChatMessageTable(Base):
151
+ """Chat message database table model."""
152
+
153
+ __tablename__ = "chat_messages"
154
+ __table_args__ = (
155
+ Index("ix_chat_messages_chat_id", "chat_id"),
156
+ Index("ix_chat_messages_agent_id_author_type", "agent_id", "author_type"),
157
+ Index("ix_chat_messages_agent_id_chat_id", "agent_id", "chat_id"),
158
+ )
159
+
160
+ id = Column(
161
+ String,
162
+ primary_key=True,
163
+ )
164
+ agent_id = Column(
165
+ String,
166
+ nullable=False,
167
+ )
168
+ chat_id = Column(
169
+ String,
170
+ nullable=False,
171
+ )
172
+ user_id = Column(
173
+ String,
174
+ nullable=True,
175
+ )
176
+ author_id = Column(
177
+ String,
178
+ nullable=False,
179
+ )
180
+ author_type = Column(
181
+ String,
182
+ nullable=False,
183
+ )
184
+ model = Column(
185
+ String,
186
+ nullable=True,
187
+ )
188
+ thread_type = Column(
189
+ String,
190
+ nullable=True,
191
+ )
192
+ reply_to = Column(
193
+ String,
194
+ nullable=True,
195
+ )
196
+ message = Column(
197
+ String,
198
+ nullable=False,
199
+ )
200
+ attachments = Column(
201
+ JSON().with_variant(JSONB(), "postgresql"),
202
+ nullable=True,
203
+ )
204
+ skill_calls = Column(
205
+ JSON().with_variant(JSONB(), "postgresql"),
206
+ nullable=True,
207
+ )
208
+ input_tokens = Column(
209
+ Integer,
210
+ default=0,
211
+ )
212
+ output_tokens = Column(
213
+ Integer,
214
+ default=0,
215
+ )
216
+ time_cost = Column(
217
+ Float,
218
+ default=0,
219
+ )
220
+ credit_event_id = Column(
221
+ String,
222
+ nullable=True,
223
+ )
224
+ credit_cost = Column(
225
+ Numeric(22, 4),
226
+ nullable=True,
227
+ )
228
+ cold_start_cost = Column(
229
+ Float,
230
+ default=0,
231
+ )
232
+ created_at = Column(
233
+ DateTime(timezone=True),
234
+ nullable=False,
235
+ server_default=func.now(),
236
+ )
237
+
238
+
239
+ class ChatMessageCreate(BaseModel):
240
+ """Base model for creating chat messages with fields needed for creation."""
241
+
242
+ model_config = ConfigDict(
243
+ use_enum_values=True,
244
+ from_attributes=True,
245
+ )
246
+
247
+ id: Annotated[
248
+ str,
249
+ Field(
250
+ default_factory=lambda: str(XID()),
251
+ description="Unique identifier for the chat message",
252
+ ),
253
+ ]
254
+ agent_id: Annotated[
255
+ str, Field(description="ID of the agent this message belongs to")
256
+ ]
257
+ chat_id: Annotated[str, Field(description="ID of the chat this message belongs to")]
258
+ user_id: Annotated[
259
+ Optional[str],
260
+ Field(description="ID of the user this message belongs to or reply to"),
261
+ ]
262
+ author_id: Annotated[str, Field(description="ID of the message author")]
263
+ author_type: Annotated[AuthorType, Field(description="Type of the message author")]
264
+ model: Annotated[
265
+ Optional[str], Field(None, description="LLM model used if applicable")
266
+ ]
267
+ thread_type: Annotated[
268
+ Optional[AuthorType],
269
+ Field(None, description="Author Type of the message thread start"),
270
+ ]
271
+ reply_to: Annotated[
272
+ Optional[str],
273
+ Field(None, description="ID of the message this message is a reply to"),
274
+ ]
275
+ message: Annotated[str, Field(description="Content of the message")]
276
+ attachments: Annotated[
277
+ Optional[List[ChatMessageAttachment]],
278
+ Field(None, description="List of attachments in the message"),
279
+ ]
280
+ skill_calls: Annotated[
281
+ Optional[List[ChatMessageSkillCall]],
282
+ Field(None, description="Skill call details"),
283
+ ]
284
+ input_tokens: Annotated[
285
+ int, Field(0, description="Number of tokens in the input message")
286
+ ]
287
+ output_tokens: Annotated[
288
+ int, Field(0, description="Number of tokens in the output message")
289
+ ]
290
+ time_cost: Annotated[
291
+ float, Field(0.0, description="Time cost for the message in seconds")
292
+ ]
293
+ credit_event_id: Annotated[
294
+ Optional[str],
295
+ Field(None, description="ID of the credit event for this message"),
296
+ ]
297
+ credit_cost: Annotated[
298
+ Optional[Decimal],
299
+ Field(None, description="Credit cost for the message in credits"),
300
+ ]
301
+ cold_start_cost: Annotated[
302
+ float,
303
+ Field(0.0, description="Cost for the cold start of the message in seconds"),
304
+ ]
305
+
306
+ async def save_in_session(self, db: AsyncSession) -> "ChatMessage":
307
+ """Save the chat message to the database.
308
+
309
+ Returns:
310
+ ChatMessage: The saved chat message with all fields populated
311
+ """
312
+ message_record = ChatMessageTable(**self.model_dump(mode="json"))
313
+ db.add(message_record)
314
+ await db.flush()
315
+ await db.refresh(message_record)
316
+ return ChatMessage.model_validate(message_record)
317
+
318
+ async def save(self) -> "ChatMessage":
319
+ """Save the chat message to the database.
320
+
321
+ Returns:
322
+ ChatMessage: The saved chat message with all fields populated
323
+ """
324
+ async with get_session() as db:
325
+ resp = await self.save_in_session(db)
326
+ await db.commit()
327
+ return resp
328
+
329
+
330
+ class ChatMessage(ChatMessageCreate):
331
+ """Chat message model with all fields including server-generated ones."""
332
+
333
+ model_config = ConfigDict(
334
+ use_enum_values=True,
335
+ json_encoders={
336
+ datetime: lambda v: v.isoformat(timespec="milliseconds"),
337
+ },
338
+ from_attributes=True,
339
+ )
340
+
341
+ created_at: Annotated[
342
+ datetime, Field(description="Timestamp when this message was created")
343
+ ]
344
+
345
+ def __str__(self):
346
+ resp = ""
347
+ if self.skill_calls:
348
+ for call in self.skill_calls:
349
+ resp += f"{call['name']} {call['parameters']}: {call['response'] if call['success'] else call['error_message']}\n"
350
+ resp += "\n"
351
+ resp += self.message
352
+ return resp
353
+
354
+ def debug_format(self) -> str:
355
+ """Format this ChatMessage for debug output.
356
+
357
+ Returns:
358
+ str: Formatted debug string for the message
359
+ """
360
+ resp = ""
361
+
362
+ if self.cold_start_cost:
363
+ resp += "[ Agent cold start ... ]\n"
364
+ resp += f"\n------------------- start cost: {self.cold_start_cost:.3f} seconds\n\n"
365
+
366
+ if self.author_type == AuthorType.SKILL:
367
+ resp += f"[ Skill Calls: ] ({self.created_at.strftime('%Y-%m-%d %H:%M:%S')} UTC)\n\n"
368
+ for skill_call in self.skill_calls:
369
+ resp += f" {skill_call['name']}: {skill_call['parameters']}\n"
370
+ if skill_call["success"]:
371
+ resp += f" Success: {skill_call.get('response', '')}\n"
372
+ else:
373
+ resp += f" Failed: {skill_call.get('error_message', '')}\n"
374
+ resp += (
375
+ f"\n------------------- skill cost: {self.time_cost:.3f} seconds\n\n"
376
+ )
377
+ elif self.author_type == AuthorType.AGENT:
378
+ resp += (
379
+ f"[ Agent: ] ({self.created_at.strftime('%Y-%m-%d %H:%M:%S')} UTC)\n\n"
380
+ )
381
+ resp += f" {self.message}\n"
382
+ resp += (
383
+ f"\n------------------- agent cost: {self.time_cost:.3f} seconds\n\n"
384
+ )
385
+ elif self.author_type == AuthorType.SYSTEM:
386
+ resp += (
387
+ f"[ System: ] ({self.created_at.strftime('%Y-%m-%d %H:%M:%S')} UTC)\n\n"
388
+ )
389
+ resp += f" {self.message}\n"
390
+ resp += (
391
+ f"\n------------------- system cost: {self.time_cost:.3f} seconds\n\n"
392
+ )
393
+ else:
394
+ resp += f"[ User: ] ({self.created_at.strftime('%Y-%m-%d %H:%M:%S')} UTC) by {self.author_id}\n\n"
395
+ resp += f" {self.message}\n"
396
+ resp += f"\n------------------- user cost: {self.time_cost:.3f} seconds\n\n"
397
+
398
+ return resp
399
+
400
+ @classmethod
401
+ async def get(cls, chat_id: str) -> Optional["ChatMessage"]:
402
+ async with get_session() as db:
403
+ raw = await db.get(ChatMessageTable, chat_id)
404
+ if raw:
405
+ return ChatMessage.model_validate(raw)
406
+ return None
407
+
408
+
409
+ class ChatTable(Base):
410
+ """Chat database table model."""
411
+
412
+ __tablename__ = "chats"
413
+ __table_args__ = (Index("ix_chats_agent_user", "agent_id", "user_id"),)
414
+
415
+ id = Column(
416
+ String,
417
+ primary_key=True,
418
+ )
419
+ agent_id = Column(
420
+ String,
421
+ nullable=False,
422
+ )
423
+ user_id = Column(
424
+ String,
425
+ nullable=False,
426
+ )
427
+ summary = Column(
428
+ String,
429
+ default="",
430
+ )
431
+ rounds = Column(
432
+ Integer,
433
+ default=0,
434
+ )
435
+ created_at = Column(
436
+ DateTime(timezone=True),
437
+ nullable=False,
438
+ server_default=func.now(),
439
+ )
440
+ updated_at = Column(
441
+ DateTime(timezone=True),
442
+ nullable=False,
443
+ server_default=func.now(),
444
+ onupdate=lambda: datetime.now(timezone.utc),
445
+ )
446
+
447
+
448
+ class ChatCreate(BaseModel):
449
+ """Base model for creating chats with fields needed for creation."""
450
+
451
+ model_config = ConfigDict(from_attributes=True)
452
+
453
+ id: Annotated[
454
+ str,
455
+ Field(
456
+ default_factory=lambda: str(XID()),
457
+ description="Unique identifier for the chat",
458
+ ),
459
+ ]
460
+ agent_id: Annotated[str, Field(description="ID of the agent this chat belongs to")]
461
+ user_id: Annotated[str, Field(description="User ID of the chat")]
462
+ summary: Annotated[str, Field("", description="Summary of the chat")]
463
+ rounds: Annotated[int, Field(0, description="Number of rounds in the chat")]
464
+
465
+ async def save(self) -> "Chat":
466
+ """Create a new chat in the database.
467
+
468
+ Returns:
469
+ Chat: The saved chat with all fields populated
470
+ """
471
+ # Set timestamps
472
+ chat_record = ChatTable(**self.model_dump(exclude_unset=True))
473
+
474
+ async with get_session() as db:
475
+ db.add(chat_record)
476
+ await db.commit()
477
+ await db.refresh(chat_record)
478
+
479
+ # Create and return a full Chat instance
480
+ return Chat.model_validate(chat_record)
481
+
482
+
483
+ class Chat(ChatCreate):
484
+ """Chat model with all fields including server-generated ones."""
485
+
486
+ model_config = ConfigDict(
487
+ from_attributes=True,
488
+ json_encoders={datetime: lambda v: v.isoformat(timespec="milliseconds")},
489
+ )
490
+
491
+ created_at: Annotated[
492
+ datetime, Field(description="Timestamp when this chat was created")
493
+ ]
494
+ updated_at: Annotated[
495
+ datetime, Field(description="Timestamp when this chat was updated")
496
+ ]
497
+
498
+ @classmethod
499
+ async def get(cls, id: str) -> Optional["Chat"]:
500
+ """Get a chat by its ID.
501
+
502
+ Args:
503
+ id: ID of the chat to get
504
+
505
+ Returns:
506
+ Chat if found, None otherwise
507
+ """
508
+ async with get_session() as db:
509
+ chat_record = await db.get(ChatTable, id)
510
+ if chat_record:
511
+ return cls.model_validate(chat_record)
512
+ return None
513
+
514
+ async def delete(self):
515
+ """Delete the chat from the database."""
516
+ async with get_session() as db:
517
+ chat_record = await db.get(ChatTable, self.id)
518
+ if chat_record:
519
+ await db.delete(chat_record)
520
+ await db.commit()
521
+
522
+ async def add_round(self):
523
+ """Increment the number of rounds in the chat on the database server.
524
+
525
+ Uses a direct SQL UPDATE statement to increment the rounds counter
526
+ on the server side, avoiding potential race conditions.
527
+ """
528
+ async with get_session() as db:
529
+ stmt = (
530
+ update(ChatTable)
531
+ .where(ChatTable.id == self.id)
532
+ .values(rounds=ChatTable.rounds + 1)
533
+ )
534
+ await db.execute(stmt)
535
+ await db.commit()
536
+
537
+ # Update local object
538
+ self.rounds += 1
539
+
540
+ async def update_summary(self, summary: str) -> "Chat":
541
+ """Update the chat summary in the database.
542
+
543
+ Uses a direct SQL UPDATE statement to set the summary field.
544
+
545
+ Args:
546
+ summary: New summary text for the chat
547
+
548
+ Returns:
549
+ Chat: The updated chat instance
550
+ """
551
+ async with get_session() as db:
552
+ stmt = (
553
+ update(ChatTable).where(ChatTable.id == self.id).values(summary=summary)
554
+ )
555
+ await db.execute(stmt)
556
+ await db.commit()
557
+
558
+ # Update local object
559
+ self.summary = summary
560
+ return self
561
+
562
+ @classmethod
563
+ async def get_by_agent_user(cls, agent_id: str, user_id: str) -> List["Chat"]:
564
+ """Get all chats for a specific agent and user.
565
+
566
+ Args:
567
+ agent_id: ID of the agent
568
+ user_id: ID of the user
569
+
570
+ Returns:
571
+ List of chats
572
+ """
573
+ async with get_session() as db:
574
+ results = await db.scalars(
575
+ select(ChatTable)
576
+ .order_by(desc(ChatTable.updated_at))
577
+ .limit(10)
578
+ .where(ChatTable.agent_id == agent_id, ChatTable.user_id == user_id)
579
+ )
580
+
581
+ return [cls.model_validate(chat) for chat in results]