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.
- intentkit/__init__.py +17 -0
- intentkit/abstracts/__init__.py +0 -0
- intentkit/abstracts/agent.py +60 -0
- intentkit/abstracts/api.py +4 -0
- intentkit/abstracts/engine.py +38 -0
- intentkit/abstracts/exception.py +9 -0
- intentkit/abstracts/graph.py +25 -0
- intentkit/abstracts/skill.py +129 -0
- intentkit/abstracts/twitter.py +54 -0
- intentkit/clients/__init__.py +14 -0
- intentkit/clients/cdp.py +53 -0
- intentkit/clients/twitter.py +445 -0
- intentkit/config/__init__.py +0 -0
- intentkit/config/config.py +164 -0
- intentkit/core/__init__.py +0 -0
- intentkit/core/agent.py +191 -0
- intentkit/core/api.py +40 -0
- intentkit/core/client.py +45 -0
- intentkit/core/credit.py +1767 -0
- intentkit/core/engine.py +1018 -0
- intentkit/core/node.py +223 -0
- intentkit/core/prompt.py +58 -0
- intentkit/core/skill.py +124 -0
- intentkit/models/agent.py +1689 -0
- intentkit/models/agent_data.py +810 -0
- intentkit/models/agent_schema.json +733 -0
- intentkit/models/app_setting.py +156 -0
- intentkit/models/base.py +9 -0
- intentkit/models/chat.py +581 -0
- intentkit/models/conversation.py +286 -0
- intentkit/models/credit.py +1406 -0
- intentkit/models/db.py +120 -0
- intentkit/models/db_mig.py +102 -0
- intentkit/models/generator.py +347 -0
- intentkit/models/llm.py +746 -0
- intentkit/models/redis.py +132 -0
- intentkit/models/skill.py +466 -0
- intentkit/models/user.py +243 -0
- intentkit/skills/__init__.py +12 -0
- intentkit/skills/acolyt/__init__.py +83 -0
- intentkit/skills/acolyt/acolyt.jpg +0 -0
- intentkit/skills/acolyt/ask.py +128 -0
- intentkit/skills/acolyt/base.py +28 -0
- intentkit/skills/acolyt/schema.json +89 -0
- intentkit/skills/aixbt/README.md +71 -0
- intentkit/skills/aixbt/__init__.py +73 -0
- intentkit/skills/aixbt/aixbt.jpg +0 -0
- intentkit/skills/aixbt/base.py +21 -0
- intentkit/skills/aixbt/projects.py +153 -0
- intentkit/skills/aixbt/schema.json +99 -0
- intentkit/skills/allora/__init__.py +83 -0
- intentkit/skills/allora/allora.jpeg +0 -0
- intentkit/skills/allora/base.py +28 -0
- intentkit/skills/allora/price.py +130 -0
- intentkit/skills/allora/schema.json +89 -0
- intentkit/skills/base.py +174 -0
- intentkit/skills/carv/README.md +95 -0
- intentkit/skills/carv/__init__.py +121 -0
- intentkit/skills/carv/base.py +183 -0
- intentkit/skills/carv/carv.webp +0 -0
- intentkit/skills/carv/fetch_news.py +92 -0
- intentkit/skills/carv/onchain_query.py +164 -0
- intentkit/skills/carv/schema.json +137 -0
- intentkit/skills/carv/token_info_and_price.py +110 -0
- intentkit/skills/cdp/__init__.py +137 -0
- intentkit/skills/cdp/base.py +21 -0
- intentkit/skills/cdp/cdp.png +0 -0
- intentkit/skills/cdp/get_balance.py +81 -0
- intentkit/skills/cdp/schema.json +473 -0
- intentkit/skills/chainlist/README.md +38 -0
- intentkit/skills/chainlist/__init__.py +54 -0
- intentkit/skills/chainlist/base.py +21 -0
- intentkit/skills/chainlist/chain_lookup.py +208 -0
- intentkit/skills/chainlist/chainlist.png +0 -0
- intentkit/skills/chainlist/schema.json +47 -0
- intentkit/skills/common/__init__.py +82 -0
- intentkit/skills/common/base.py +21 -0
- intentkit/skills/common/common.jpg +0 -0
- intentkit/skills/common/current_time.py +84 -0
- intentkit/skills/common/schema.json +57 -0
- intentkit/skills/cookiefun/README.md +121 -0
- intentkit/skills/cookiefun/__init__.py +78 -0
- intentkit/skills/cookiefun/base.py +41 -0
- intentkit/skills/cookiefun/constants.py +18 -0
- intentkit/skills/cookiefun/cookiefun.png +0 -0
- intentkit/skills/cookiefun/get_account_details.py +171 -0
- intentkit/skills/cookiefun/get_account_feed.py +282 -0
- intentkit/skills/cookiefun/get_account_smart_followers.py +181 -0
- intentkit/skills/cookiefun/get_sectors.py +128 -0
- intentkit/skills/cookiefun/schema.json +155 -0
- intentkit/skills/cookiefun/search_accounts.py +225 -0
- intentkit/skills/cryptocompare/__init__.py +130 -0
- intentkit/skills/cryptocompare/api.py +159 -0
- intentkit/skills/cryptocompare/base.py +303 -0
- intentkit/skills/cryptocompare/cryptocompare.png +0 -0
- intentkit/skills/cryptocompare/fetch_news.py +96 -0
- intentkit/skills/cryptocompare/fetch_price.py +99 -0
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +113 -0
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +109 -0
- intentkit/skills/cryptocompare/fetch_top_volume.py +108 -0
- intentkit/skills/cryptocompare/fetch_trading_signals.py +107 -0
- intentkit/skills/cryptocompare/schema.json +168 -0
- intentkit/skills/cryptopanic/__init__.py +108 -0
- intentkit/skills/cryptopanic/base.py +51 -0
- intentkit/skills/cryptopanic/cryptopanic.png +0 -0
- intentkit/skills/cryptopanic/fetch_crypto_news.py +153 -0
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +136 -0
- intentkit/skills/cryptopanic/schema.json +103 -0
- intentkit/skills/dapplooker/README.md +92 -0
- intentkit/skills/dapplooker/__init__.py +83 -0
- intentkit/skills/dapplooker/base.py +26 -0
- intentkit/skills/dapplooker/dapplooker.jpg +0 -0
- intentkit/skills/dapplooker/dapplooker_token_data.py +476 -0
- intentkit/skills/dapplooker/schema.json +91 -0
- intentkit/skills/defillama/__init__.py +323 -0
- intentkit/skills/defillama/api.py +315 -0
- intentkit/skills/defillama/base.py +135 -0
- intentkit/skills/defillama/coins/__init__.py +0 -0
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +116 -0
- intentkit/skills/defillama/coins/fetch_block.py +98 -0
- intentkit/skills/defillama/coins/fetch_current_prices.py +105 -0
- intentkit/skills/defillama/coins/fetch_first_price.py +100 -0
- intentkit/skills/defillama/coins/fetch_historical_prices.py +110 -0
- intentkit/skills/defillama/coins/fetch_price_chart.py +109 -0
- intentkit/skills/defillama/coins/fetch_price_percentage.py +93 -0
- intentkit/skills/defillama/config/__init__.py +0 -0
- intentkit/skills/defillama/config/chains.py +433 -0
- intentkit/skills/defillama/defillama.jpeg +0 -0
- intentkit/skills/defillama/fees/__init__.py +0 -0
- intentkit/skills/defillama/fees/fetch_fees_overview.py +130 -0
- intentkit/skills/defillama/schema.json +383 -0
- intentkit/skills/defillama/stablecoins/__init__.py +0 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +100 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +129 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +83 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +126 -0
- intentkit/skills/defillama/tests/__init__.py +0 -0
- intentkit/skills/defillama/tests/api_integration.test.py +192 -0
- intentkit/skills/defillama/tests/api_unit.test.py +583 -0
- intentkit/skills/defillama/tvl/__init__.py +0 -0
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +106 -0
- intentkit/skills/defillama/tvl/fetch_chains.py +107 -0
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +91 -0
- intentkit/skills/defillama/tvl/fetch_protocol.py +207 -0
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +93 -0
- intentkit/skills/defillama/tvl/fetch_protocols.py +196 -0
- intentkit/skills/defillama/volumes/__init__.py +0 -0
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +157 -0
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +123 -0
- intentkit/skills/defillama/volumes/fetch_options_overview.py +131 -0
- intentkit/skills/defillama/yields/__init__.py +0 -0
- intentkit/skills/defillama/yields/fetch_pool_chart.py +100 -0
- intentkit/skills/defillama/yields/fetch_pools.py +126 -0
- intentkit/skills/dexscreener/__init__.py +93 -0
- intentkit/skills/dexscreener/base.py +133 -0
- intentkit/skills/dexscreener/dexscreener.png +0 -0
- intentkit/skills/dexscreener/model/__init__.py +0 -0
- intentkit/skills/dexscreener/model/search_token_response.py +82 -0
- intentkit/skills/dexscreener/schema.json +48 -0
- intentkit/skills/dexscreener/search_token.py +321 -0
- intentkit/skills/dune_analytics/__init__.py +103 -0
- intentkit/skills/dune_analytics/base.py +46 -0
- intentkit/skills/dune_analytics/dune.png +0 -0
- intentkit/skills/dune_analytics/fetch_kol_buys.py +128 -0
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +237 -0
- intentkit/skills/dune_analytics/schema.json +99 -0
- intentkit/skills/elfa/README.md +100 -0
- intentkit/skills/elfa/__init__.py +123 -0
- intentkit/skills/elfa/base.py +28 -0
- intentkit/skills/elfa/elfa.jpg +0 -0
- intentkit/skills/elfa/mention.py +504 -0
- intentkit/skills/elfa/schema.json +153 -0
- intentkit/skills/elfa/stats.py +118 -0
- intentkit/skills/elfa/tokens.py +126 -0
- intentkit/skills/enso/README.md +75 -0
- intentkit/skills/enso/__init__.py +114 -0
- intentkit/skills/enso/abi/__init__.py +0 -0
- intentkit/skills/enso/abi/approval.py +279 -0
- intentkit/skills/enso/abi/erc20.py +14 -0
- intentkit/skills/enso/abi/route.py +129 -0
- intentkit/skills/enso/base.py +44 -0
- intentkit/skills/enso/best_yield.py +286 -0
- intentkit/skills/enso/enso.jpg +0 -0
- intentkit/skills/enso/networks.py +105 -0
- intentkit/skills/enso/prices.py +93 -0
- intentkit/skills/enso/route.py +300 -0
- intentkit/skills/enso/schema.json +212 -0
- intentkit/skills/enso/tokens.py +223 -0
- intentkit/skills/enso/wallet.py +381 -0
- intentkit/skills/github/README.md +63 -0
- intentkit/skills/github/__init__.py +54 -0
- intentkit/skills/github/base.py +21 -0
- intentkit/skills/github/github.jpg +0 -0
- intentkit/skills/github/github_search.py +183 -0
- intentkit/skills/github/schema.json +59 -0
- intentkit/skills/heurist/__init__.py +143 -0
- intentkit/skills/heurist/base.py +26 -0
- intentkit/skills/heurist/heurist.png +0 -0
- intentkit/skills/heurist/image_generation_animagine_xl.py +162 -0
- intentkit/skills/heurist/image_generation_arthemy_comics.py +162 -0
- intentkit/skills/heurist/image_generation_arthemy_real.py +162 -0
- intentkit/skills/heurist/image_generation_braindance.py +162 -0
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +162 -0
- intentkit/skills/heurist/image_generation_flux_1_dev.py +162 -0
- intentkit/skills/heurist/image_generation_sdxl.py +161 -0
- intentkit/skills/heurist/schema.json +196 -0
- intentkit/skills/lifi/README.md +294 -0
- intentkit/skills/lifi/__init__.py +141 -0
- intentkit/skills/lifi/base.py +21 -0
- intentkit/skills/lifi/lifi.png +0 -0
- intentkit/skills/lifi/schema.json +89 -0
- intentkit/skills/lifi/token_execute.py +472 -0
- intentkit/skills/lifi/token_quote.py +190 -0
- intentkit/skills/lifi/utils.py +656 -0
- intentkit/skills/moralis/README.md +490 -0
- intentkit/skills/moralis/__init__.py +110 -0
- intentkit/skills/moralis/api.py +281 -0
- intentkit/skills/moralis/base.py +55 -0
- intentkit/skills/moralis/fetch_chain_portfolio.py +191 -0
- intentkit/skills/moralis/fetch_nft_portfolio.py +284 -0
- intentkit/skills/moralis/fetch_solana_portfolio.py +331 -0
- intentkit/skills/moralis/fetch_wallet_portfolio.py +301 -0
- intentkit/skills/moralis/moralis.png +0 -0
- intentkit/skills/moralis/schema.json +156 -0
- intentkit/skills/moralis/tests/__init__.py +0 -0
- intentkit/skills/moralis/tests/test_wallet.py +511 -0
- intentkit/skills/nation/__init__.py +62 -0
- intentkit/skills/nation/base.py +31 -0
- intentkit/skills/nation/nation.png +0 -0
- intentkit/skills/nation/nft_check.py +106 -0
- intentkit/skills/nation/schema.json +58 -0
- intentkit/skills/openai/__init__.py +107 -0
- intentkit/skills/openai/base.py +32 -0
- intentkit/skills/openai/dalle_image_generation.py +128 -0
- intentkit/skills/openai/gpt_image_generation.py +152 -0
- intentkit/skills/openai/gpt_image_to_image.py +186 -0
- intentkit/skills/openai/image_to_text.py +126 -0
- intentkit/skills/openai/openai.png +0 -0
- intentkit/skills/openai/schema.json +139 -0
- intentkit/skills/portfolio/README.md +55 -0
- intentkit/skills/portfolio/__init__.py +151 -0
- intentkit/skills/portfolio/base.py +107 -0
- intentkit/skills/portfolio/constants.py +9 -0
- intentkit/skills/portfolio/moralis.png +0 -0
- intentkit/skills/portfolio/schema.json +237 -0
- intentkit/skills/portfolio/token_balances.py +155 -0
- intentkit/skills/portfolio/wallet_approvals.py +102 -0
- intentkit/skills/portfolio/wallet_defi_positions.py +80 -0
- intentkit/skills/portfolio/wallet_history.py +155 -0
- intentkit/skills/portfolio/wallet_net_worth.py +112 -0
- intentkit/skills/portfolio/wallet_nfts.py +139 -0
- intentkit/skills/portfolio/wallet_profitability.py +101 -0
- intentkit/skills/portfolio/wallet_profitability_summary.py +91 -0
- intentkit/skills/portfolio/wallet_stats.py +79 -0
- intentkit/skills/portfolio/wallet_swaps.py +147 -0
- intentkit/skills/skills.toml +103 -0
- intentkit/skills/slack/__init__.py +98 -0
- intentkit/skills/slack/base.py +55 -0
- intentkit/skills/slack/get_channel.py +109 -0
- intentkit/skills/slack/get_message.py +136 -0
- intentkit/skills/slack/schedule_message.py +92 -0
- intentkit/skills/slack/schema.json +135 -0
- intentkit/skills/slack/send_message.py +81 -0
- intentkit/skills/slack/slack.jpg +0 -0
- intentkit/skills/system/__init__.py +90 -0
- intentkit/skills/system/base.py +22 -0
- intentkit/skills/system/read_agent_api_key.py +87 -0
- intentkit/skills/system/regenerate_agent_api_key.py +77 -0
- intentkit/skills/system/schema.json +53 -0
- intentkit/skills/system/system.svg +76 -0
- intentkit/skills/tavily/README.md +86 -0
- intentkit/skills/tavily/__init__.py +91 -0
- intentkit/skills/tavily/base.py +27 -0
- intentkit/skills/tavily/schema.json +119 -0
- intentkit/skills/tavily/tavily.jpg +0 -0
- intentkit/skills/tavily/tavily_extract.py +147 -0
- intentkit/skills/tavily/tavily_search.py +139 -0
- intentkit/skills/token/README.md +89 -0
- intentkit/skills/token/__init__.py +107 -0
- intentkit/skills/token/base.py +154 -0
- intentkit/skills/token/constants.py +9 -0
- intentkit/skills/token/erc20_transfers.py +145 -0
- intentkit/skills/token/moralis.png +0 -0
- intentkit/skills/token/schema.json +141 -0
- intentkit/skills/token/token_analytics.py +81 -0
- intentkit/skills/token/token_price.py +132 -0
- intentkit/skills/token/token_search.py +121 -0
- intentkit/skills/twitter/__init__.py +146 -0
- intentkit/skills/twitter/base.py +68 -0
- intentkit/skills/twitter/follow_user.py +69 -0
- intentkit/skills/twitter/get_mentions.py +124 -0
- intentkit/skills/twitter/get_timeline.py +111 -0
- intentkit/skills/twitter/get_user_by_username.py +84 -0
- intentkit/skills/twitter/get_user_tweets.py +123 -0
- intentkit/skills/twitter/like_tweet.py +65 -0
- intentkit/skills/twitter/post_tweet.py +90 -0
- intentkit/skills/twitter/reply_tweet.py +98 -0
- intentkit/skills/twitter/retweet.py +76 -0
- intentkit/skills/twitter/schema.json +258 -0
- intentkit/skills/twitter/search_tweets.py +115 -0
- intentkit/skills/twitter/twitter.png +0 -0
- intentkit/skills/unrealspeech/__init__.py +55 -0
- intentkit/skills/unrealspeech/base.py +21 -0
- intentkit/skills/unrealspeech/schema.json +100 -0
- intentkit/skills/unrealspeech/text_to_speech.py +177 -0
- intentkit/skills/unrealspeech/unrealspeech.jpg +0 -0
- intentkit/skills/venice_audio/__init__.py +106 -0
- intentkit/skills/venice_audio/base.py +119 -0
- intentkit/skills/venice_audio/input.py +41 -0
- intentkit/skills/venice_audio/schema.json +152 -0
- intentkit/skills/venice_audio/venice_audio.py +240 -0
- intentkit/skills/venice_audio/venice_logo.jpg +0 -0
- intentkit/skills/venice_image/README.md +119 -0
- intentkit/skills/venice_image/__init__.py +154 -0
- intentkit/skills/venice_image/api.py +138 -0
- intentkit/skills/venice_image/base.py +188 -0
- intentkit/skills/venice_image/config.py +35 -0
- intentkit/skills/venice_image/image_enhance/README.md +119 -0
- intentkit/skills/venice_image/image_enhance/__init__.py +0 -0
- intentkit/skills/venice_image/image_enhance/image_enhance.py +80 -0
- intentkit/skills/venice_image/image_enhance/image_enhance_base.py +23 -0
- intentkit/skills/venice_image/image_enhance/image_enhance_input.py +40 -0
- intentkit/skills/venice_image/image_generation/README.md +144 -0
- intentkit/skills/venice_image/image_generation/__init__.py +0 -0
- intentkit/skills/venice_image/image_generation/image_generation_base.py +117 -0
- intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -0
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -0
- intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -0
- intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -0
- intentkit/skills/venice_image/image_upscale/README.md +111 -0
- intentkit/skills/venice_image/image_upscale/__init__.py +0 -0
- intentkit/skills/venice_image/image_upscale/image_upscale.py +90 -0
- intentkit/skills/venice_image/image_upscale/image_upscale_base.py +23 -0
- intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -0
- intentkit/skills/venice_image/image_vision/README.md +112 -0
- intentkit/skills/venice_image/image_vision/__init__.py +0 -0
- intentkit/skills/venice_image/image_vision/image_vision.py +100 -0
- intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -0
- intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -0
- intentkit/skills/venice_image/schema.json +267 -0
- intentkit/skills/venice_image/utils.py +78 -0
- intentkit/skills/venice_image/venice_image.jpg +0 -0
- intentkit/skills/web_scraper/README.md +82 -0
- intentkit/skills/web_scraper/__init__.py +92 -0
- intentkit/skills/web_scraper/base.py +21 -0
- intentkit/skills/web_scraper/langchain.png +0 -0
- intentkit/skills/web_scraper/schema.json +115 -0
- intentkit/skills/web_scraper/scrape_and_index.py +327 -0
- intentkit/utils/__init__.py +1 -0
- intentkit/utils/chain.py +436 -0
- intentkit/utils/error.py +134 -0
- intentkit/utils/logging.py +70 -0
- intentkit/utils/middleware.py +61 -0
- intentkit/utils/random.py +16 -0
- intentkit/utils/s3.py +267 -0
- intentkit/utils/slack_alert.py +79 -0
- intentkit/utils/tx.py +37 -0
- {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/METADATA +1 -1
- intentkit-0.5.2.dist-info/RECORD +365 -0
- intentkit-0.5.0.dist-info/RECORD +0 -4
- {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/WHEEL +0 -0
- {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from typing import Any, Dict, Literal, Optional, Type
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
from langchain_core.callbacks.manager import CallbackManagerForToolRun
|
|
7
|
+
from langchain_core.runnables import RunnableConfig
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
from intentkit.skills.unrealspeech.base import UnrealSpeechBaseTool
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TextToSpeechInput(BaseModel):
|
|
16
|
+
"""Input for TextToSpeech tool."""
|
|
17
|
+
|
|
18
|
+
text: str = Field(description="The text to convert to speech. Required.")
|
|
19
|
+
|
|
20
|
+
voice_id: str = Field(
|
|
21
|
+
description="The voice ID to use for speech synthesis. Options include: 'af_bella', 'af_sarah', 'af_nicole', 'af_sky', 'am_adam', 'am_michael', 'bf_emma', 'bf_isabella', 'bm_george', 'bm_lewis'.",
|
|
22
|
+
default="af_sarah",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
bitrate: str = Field(
|
|
26
|
+
description="The audio bitrate. Higher values provide better quality but larger file sizes. Options: '64k', '96k', '128k', '192k', '256k', '320k'.",
|
|
27
|
+
default="192k",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
speed: float = Field(
|
|
31
|
+
description="The speech speed adjustment. Range: -1.0 (slower) to 1.0 (faster), with 0.0 being the normal speed.",
|
|
32
|
+
default=0.0,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
timestamp_type: Optional[Literal["word", "sentence"]] = Field(
|
|
36
|
+
description="The type of timestamps to include in the response. 'word' for word-level timestamps, 'sentence' for sentence-level, or None for no timestamps.",
|
|
37
|
+
default="word",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class TextToSpeech(UnrealSpeechBaseTool):
|
|
42
|
+
"""Tool for converting text to speech using UnrealSpeech's API.
|
|
43
|
+
|
|
44
|
+
This tool converts text to natural-sounding speech in various voices.
|
|
45
|
+
It can generate speech with different voices, speeds, and qualities.
|
|
46
|
+
The response includes URLs to the audio file and optional word-level timestamps.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
name: str = "text_to_speech"
|
|
50
|
+
description: str = (
|
|
51
|
+
"Converts text to natural-sounding speech using UnrealSpeech.\n"
|
|
52
|
+
"Use this tool when you need to generate spoken audio from text.\n"
|
|
53
|
+
"Returns URLs to the generated audio file and word-level timestamps.\n"
|
|
54
|
+
"Provides various voice options and speech customization parameters."
|
|
55
|
+
)
|
|
56
|
+
args_schema: Type[BaseModel] = TextToSpeechInput
|
|
57
|
+
|
|
58
|
+
def get_env_var(self, env_var_name: str) -> Optional[str]:
|
|
59
|
+
"""Helper method to get environment variables."""
|
|
60
|
+
return os.environ.get(env_var_name)
|
|
61
|
+
|
|
62
|
+
async def _arun(
|
|
63
|
+
self,
|
|
64
|
+
text: str,
|
|
65
|
+
voice_id: str = "af_sarah",
|
|
66
|
+
bitrate: str = "192k",
|
|
67
|
+
speed: float = 0.0,
|
|
68
|
+
timestamp_type: Optional[Literal["word", "sentence"]] = "word",
|
|
69
|
+
config: Optional[RunnableConfig] = None,
|
|
70
|
+
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
71
|
+
**kwargs,
|
|
72
|
+
) -> Dict[str, Any]:
|
|
73
|
+
"""Run the tool to convert text to speech."""
|
|
74
|
+
|
|
75
|
+
# Get the API key from context config if available
|
|
76
|
+
context = self.context_from_config(config) if config else None
|
|
77
|
+
api_key = (
|
|
78
|
+
context.config.get("api_key", None) if context and context.config else None
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# If no API key in config, try to get it from skill store
|
|
82
|
+
if not api_key:
|
|
83
|
+
try:
|
|
84
|
+
agent_id = context.agent.id if context and context.agent else "default"
|
|
85
|
+
api_key_data = await self.skill_store.get_agent_data(
|
|
86
|
+
agent_id, "unrealspeech_api_key"
|
|
87
|
+
)
|
|
88
|
+
api_key = api_key_data.get("api_key") if api_key_data else None
|
|
89
|
+
except Exception as e:
|
|
90
|
+
logger.warning(f"Failed to get API key from skill store: {e}")
|
|
91
|
+
|
|
92
|
+
# If still no API key, check environment variables (handled by UnrealSpeech client)
|
|
93
|
+
if not api_key:
|
|
94
|
+
env_key = self.get_env_var("UNREALSPEECH_API_KEY")
|
|
95
|
+
if not env_key:
|
|
96
|
+
return {
|
|
97
|
+
"success": False,
|
|
98
|
+
"error": "No UnrealSpeech API key found. Please set the UNREALSPEECH_API_KEY environment variable or provide it in the agent configuration.",
|
|
99
|
+
}
|
|
100
|
+
api_key = env_key
|
|
101
|
+
|
|
102
|
+
# Clean up and validate input
|
|
103
|
+
if not text:
|
|
104
|
+
return {"success": False, "error": "Text cannot be empty."}
|
|
105
|
+
|
|
106
|
+
# Validate bitrate
|
|
107
|
+
valid_bitrates = ["64k", "96k", "128k", "192k", "256k", "320k"]
|
|
108
|
+
if bitrate not in valid_bitrates:
|
|
109
|
+
logger.warning(f"Invalid bitrate '{bitrate}'. Using default '192k'.")
|
|
110
|
+
bitrate = "192k"
|
|
111
|
+
|
|
112
|
+
# Validate speed
|
|
113
|
+
if not -1.0 <= speed <= 1.0:
|
|
114
|
+
logger.warning(
|
|
115
|
+
f"Speed value {speed} is outside valid range (-1.0 to 1.0). Clamping to valid range."
|
|
116
|
+
)
|
|
117
|
+
speed = max(-1.0, min(1.0, speed))
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
# For longer text, use the /speech endpoint for better handling
|
|
121
|
+
endpoint = "https://api.v8.unrealspeech.com/speech"
|
|
122
|
+
|
|
123
|
+
# Prepare the request payload
|
|
124
|
+
payload = {
|
|
125
|
+
"Text": text,
|
|
126
|
+
"VoiceId": voice_id,
|
|
127
|
+
"Bitrate": bitrate,
|
|
128
|
+
"Speed": str(speed),
|
|
129
|
+
"Pitch": "1",
|
|
130
|
+
"OutputFormat": "uri",
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
# Add timestamp type if specified
|
|
134
|
+
if timestamp_type:
|
|
135
|
+
payload["TimestampType"] = timestamp_type
|
|
136
|
+
|
|
137
|
+
# Send the request to UnrealSpeech API
|
|
138
|
+
async with httpx.AsyncClient(timeout=60.0) as client:
|
|
139
|
+
headers = {
|
|
140
|
+
"Authorization": f"Bearer {api_key}",
|
|
141
|
+
"Content-Type": "application/json",
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
response = await client.post(endpoint, json=payload, headers=headers)
|
|
145
|
+
|
|
146
|
+
# Check response status
|
|
147
|
+
if response.status_code != 200:
|
|
148
|
+
logger.error(f"UnrealSpeech API error: {response.text}")
|
|
149
|
+
return {
|
|
150
|
+
"success": False,
|
|
151
|
+
"error": f"API error: {response.status_code} - {response.text}",
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
# Parse response
|
|
155
|
+
result = response.json()
|
|
156
|
+
|
|
157
|
+
# Format the response
|
|
158
|
+
return {
|
|
159
|
+
"success": True,
|
|
160
|
+
"task_id": result.get("TaskId"),
|
|
161
|
+
"audio_url": result.get("OutputUri"),
|
|
162
|
+
"timestamps_url": result.get("TimestampsUri")
|
|
163
|
+
if timestamp_type
|
|
164
|
+
else None,
|
|
165
|
+
"status": result.get("TaskStatus"),
|
|
166
|
+
"voice_id": result.get("VoiceId"),
|
|
167
|
+
"character_count": result.get("RequestCharacters"),
|
|
168
|
+
"word_count": result.get("RequestCharacters", 0)
|
|
169
|
+
// 5, # Rough estimate
|
|
170
|
+
"duration_seconds": result.get("RequestCharacters", 0)
|
|
171
|
+
// 15, # Rough estimate (15 chars/sec)
|
|
172
|
+
"created_at": result.get("CreationTime"),
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
except Exception as e:
|
|
176
|
+
logger.error(f"Failed to generate speech: {e}", exc_info=True)
|
|
177
|
+
return {"success": False, "error": f"Failed to generate speech: {str(e)}"}
|
|
Binary file
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import List, Literal, Optional, TypedDict
|
|
3
|
+
|
|
4
|
+
from intentkit.abstracts.skill import SkillStoreABC
|
|
5
|
+
from intentkit.skills.base import SkillConfig, SkillState
|
|
6
|
+
from intentkit.skills.venice_audio.base import VeniceAudioBaseTool
|
|
7
|
+
from intentkit.skills.venice_audio.venice_audio import VeniceAudioTool
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
_cache: dict[str, VeniceAudioBaseTool] = {}
|
|
13
|
+
|
|
14
|
+
_SKILL_NAME_TO_CLASS_MAP = {
|
|
15
|
+
"text_to_speech": VeniceAudioTool,
|
|
16
|
+
# Add new mappings here: "skill_name": SkillClassName
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SkillStates(TypedDict):
|
|
21
|
+
text_to_speech: SkillState
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Config(SkillConfig):
|
|
25
|
+
enabled: bool
|
|
26
|
+
voice_model: Literal["af_heart", "bm_lewis", "custom"]
|
|
27
|
+
states: SkillStates # type: ignore
|
|
28
|
+
api_key_provider: Optional[Literal["agent_owner"]]
|
|
29
|
+
|
|
30
|
+
# conditionally required
|
|
31
|
+
api_key: Optional[str]
|
|
32
|
+
voice_model_custom: Optional[list[str]]
|
|
33
|
+
|
|
34
|
+
# optional
|
|
35
|
+
rate_limit_number: Optional[int]
|
|
36
|
+
rate_limit_minutes: Optional[int]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
async def get_skills(
|
|
40
|
+
config: "Config",
|
|
41
|
+
is_private: bool,
|
|
42
|
+
store: SkillStoreABC,
|
|
43
|
+
**_, # Allow for extra arguments if the loader passes them
|
|
44
|
+
) -> list[VeniceAudioBaseTool]:
|
|
45
|
+
"""
|
|
46
|
+
Factory function to create and return Venice Audio skill tools.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
config: The configuration dictionary for the Venice Audio skill.
|
|
50
|
+
skill_store: The skill store instance.
|
|
51
|
+
agent_id: The ID of the agent requesting the skills.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
A list of VeniceAudioBaseTool instances for the Venice Audio skill.
|
|
55
|
+
"""
|
|
56
|
+
# Check if the entire category is disabled first
|
|
57
|
+
if not config.get("enabled", False):
|
|
58
|
+
return []
|
|
59
|
+
|
|
60
|
+
available_skills: List[VeniceAudioBaseTool] = []
|
|
61
|
+
skill_states = config.get("states", {})
|
|
62
|
+
|
|
63
|
+
# Iterate through all known skills defined in the map
|
|
64
|
+
for skill_name in _SKILL_NAME_TO_CLASS_MAP:
|
|
65
|
+
state = skill_states.get(
|
|
66
|
+
skill_name, "disabled"
|
|
67
|
+
) # Default to disabled if not in config
|
|
68
|
+
|
|
69
|
+
if state == "disabled":
|
|
70
|
+
continue
|
|
71
|
+
elif state == "public" or (state == "private" and is_private):
|
|
72
|
+
# If enabled, get the skill instance using the factory function
|
|
73
|
+
skill_instance = get_venice_audio_skill(skill_name, store)
|
|
74
|
+
if skill_instance:
|
|
75
|
+
available_skills.append(skill_instance)
|
|
76
|
+
else:
|
|
77
|
+
# This case should ideally not happen if the map is correct
|
|
78
|
+
logger.warning(f"Could not instantiate known skill: {skill_name}")
|
|
79
|
+
|
|
80
|
+
return available_skills
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def get_venice_audio_skill(
|
|
84
|
+
name: str,
|
|
85
|
+
store: SkillStoreABC,
|
|
86
|
+
) -> Optional[VeniceAudioBaseTool]:
|
|
87
|
+
"""
|
|
88
|
+
Factory function to get a cached Venice Audio skill instance by name.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
name: The name of voice model.
|
|
92
|
+
store: The skill store, passed to the skill constructor.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
The requested Venice Audio skill instance, or None if the name is unknown.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
# Return from cache immediately if already exists
|
|
99
|
+
if name in _cache:
|
|
100
|
+
return _cache[name]
|
|
101
|
+
|
|
102
|
+
# Cache and return the newly created instance
|
|
103
|
+
_cache[name] = VeniceAudioTool(
|
|
104
|
+
skill_store=store,
|
|
105
|
+
)
|
|
106
|
+
return _cache[name]
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Dict, List, Optional, Tuple, Type
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
from intentkit.abstracts.skill import SkillStoreABC
|
|
7
|
+
from intentkit.skills.base import IntentKitSkill, SkillContext, ToolException
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class VeniceAudioBaseTool(IntentKitSkill):
|
|
13
|
+
"""Base class for Venice Audio tools."""
|
|
14
|
+
|
|
15
|
+
name: str = Field(default="venice_base_tool", description="The name of the tool")
|
|
16
|
+
description: str = Field(description="A description of what the tool does")
|
|
17
|
+
args_schema: Type[BaseModel] # type: ignore
|
|
18
|
+
skill_store: SkillStoreABC = Field(
|
|
19
|
+
description="The skill store for persisting data"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def category(self) -> str:
|
|
24
|
+
return "venice_audio"
|
|
25
|
+
|
|
26
|
+
def validate_voice_model(
|
|
27
|
+
self, context: SkillContext, voice_model: str
|
|
28
|
+
) -> Tuple[bool, Optional[Dict[str, object]]]:
|
|
29
|
+
config = context.config
|
|
30
|
+
|
|
31
|
+
selected_model = config.get("voice_model")
|
|
32
|
+
custom_models = config.get("voice_model_custom", [])
|
|
33
|
+
|
|
34
|
+
allowed_voice_models: List[str] = []
|
|
35
|
+
|
|
36
|
+
if selected_model == "custom":
|
|
37
|
+
allowed_voice_models = custom_models or []
|
|
38
|
+
else:
|
|
39
|
+
allowed_voice_models = [selected_model] if selected_model else []
|
|
40
|
+
|
|
41
|
+
if voice_model not in allowed_voice_models:
|
|
42
|
+
return False, {
|
|
43
|
+
"error": f'"{voice_model}" is not allowed',
|
|
44
|
+
"allowed": allowed_voice_models,
|
|
45
|
+
"suggestion": "please try again with allowed voice model",
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return True, None
|
|
49
|
+
|
|
50
|
+
def get_api_key(self, context: SkillContext) -> str:
|
|
51
|
+
"""
|
|
52
|
+
Retrieves the Venice AI API key based on the api_key_provider setting.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
The API key if found.
|
|
56
|
+
|
|
57
|
+
Raises:
|
|
58
|
+
ToolException: If the API key is not found or provider is invalid.
|
|
59
|
+
"""
|
|
60
|
+
try:
|
|
61
|
+
skillConfig = context.config
|
|
62
|
+
api_key_provider = skillConfig.get("api_key_provider")
|
|
63
|
+
if api_key_provider == "agent_owner":
|
|
64
|
+
agent_api_key = context.config.get("api_key")
|
|
65
|
+
if agent_api_key:
|
|
66
|
+
logger.debug(
|
|
67
|
+
f"Using agent-specific Venice API key for skill {self.name} in category {self.category}"
|
|
68
|
+
)
|
|
69
|
+
return agent_api_key
|
|
70
|
+
raise ToolException(
|
|
71
|
+
f"No agent-owned Venice API key found for skill '{self.name}' in category '{self.category}'."
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
elif api_key_provider == "platform":
|
|
75
|
+
system_api_key = self.skill_store.get_system_config("venice_api_key")
|
|
76
|
+
if system_api_key:
|
|
77
|
+
logger.debug(
|
|
78
|
+
f"Using system Venice API key for skill {self.name} in category {self.category}"
|
|
79
|
+
)
|
|
80
|
+
return system_api_key
|
|
81
|
+
raise ToolException(
|
|
82
|
+
f"No platform-hosted Venice API key found for skill '{self.name}' in category '{self.category}'."
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
else:
|
|
86
|
+
raise ToolException(
|
|
87
|
+
f"Invalid API key provider '{api_key_provider}' for skill '{self.name}'"
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
except Exception as e:
|
|
91
|
+
raise ToolException(f"Failed to retrieve Venice API key: {str(e)}") from e
|
|
92
|
+
|
|
93
|
+
async def apply_rate_limit(self, context: SkillContext) -> None:
|
|
94
|
+
"""
|
|
95
|
+
Applies rate limiting ONLY if specified in the agent's config ('skill_config').
|
|
96
|
+
Checks for 'rate_limit_number' and 'rate_limit_minutes'.
|
|
97
|
+
If not configured, NO rate limiting is applied.
|
|
98
|
+
Raises ConnectionAbortedError if the configured limit is exceeded.
|
|
99
|
+
"""
|
|
100
|
+
skill_config = context.config
|
|
101
|
+
user_id = context.user_id
|
|
102
|
+
|
|
103
|
+
# Get agent-specific limits safely
|
|
104
|
+
limit_num = skill_config.get("rate_limit_number")
|
|
105
|
+
limit_min = skill_config.get("rate_limit_minutes")
|
|
106
|
+
|
|
107
|
+
# Apply limit ONLY if both values are present and valid (truthy check handles None and 0)
|
|
108
|
+
if limit_num and limit_min:
|
|
109
|
+
limit_source = "Agent"
|
|
110
|
+
logger.debug(
|
|
111
|
+
f"Applying {limit_source} rate limit ({limit_num}/{limit_min} min) for user {user_id} on {self.name}"
|
|
112
|
+
)
|
|
113
|
+
if user_id:
|
|
114
|
+
await self.user_rate_limit_by_category(user_id, limit_num, limit_min)
|
|
115
|
+
else:
|
|
116
|
+
# No valid agent configuration found, so do nothing.
|
|
117
|
+
logger.debug(
|
|
118
|
+
f"No agent rate limits configured for category '{self.category}'. Skipping rate limit for user {user_id}."
|
|
119
|
+
)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from typing import Literal, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
# Define the allowed format literals based on the API documentation
|
|
6
|
+
AllowedAudioFormat = Literal["mp3", "opus", "aac", "flac", "wav", "pcm"]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class VeniceAudioInput(BaseModel):
|
|
10
|
+
"""
|
|
11
|
+
Input schema for Venice AI Text-to-Speech (/audio/speech endpoint).
|
|
12
|
+
Defines parameters controllable by the user when invoking the tool.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
input: str = Field(
|
|
16
|
+
..., # Ellipsis (...) indicates this field is required
|
|
17
|
+
description="The text to generate audio for. Maximum length is 4096 characters.",
|
|
18
|
+
min_length=1, # As per API docs: Required string length: 1
|
|
19
|
+
max_length=4096, # As per API docs: The maximum length is 4096 characters.
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
voice_model: str = Field(
|
|
23
|
+
description="voice model to used to generate voice from text_to_speech tool."
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
speed: Optional[float] = Field(
|
|
27
|
+
default=1.0, # As per API docs: default: 1 (using float for consistency)
|
|
28
|
+
description="The speed of the generated audio. 1.0 is normal speed. Allowed range: 0.25 to 4.0.",
|
|
29
|
+
ge=0.25, # As per API docs: Required range: 0.25 <= x
|
|
30
|
+
le=4.0, # As per API docs: Required range: x <= 4
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
response_format: Optional[AllowedAudioFormat] = Field(
|
|
34
|
+
default="mp3", # As per API docs: default: mp3
|
|
35
|
+
description="The desired audio format for the output file.",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# --- Note on other API parameters ---
|
|
39
|
+
# 'model': Currently hardcoded to 'tts-kokoro' in VeniceAudioBaseTool._arun. Could be added here if needed.
|
|
40
|
+
# 'voice': Handled by the 'voice_model' attribute of the specific VeniceAudioBaseTool instance. Not typically set via input schema.
|
|
41
|
+
# 'streaming': Currently hardcoded to False in VeniceAudioBaseTool._arun. Could be added here if streaming support is implemented.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Venice Audio Skills",
|
|
4
|
+
"x-icon": "https://ai.service.crestal.dev/skills/venice_audio/venice_audio.jpg",
|
|
5
|
+
"description": "Configuration for the Venice Audio skill.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"x-tags": [
|
|
8
|
+
"AI",
|
|
9
|
+
"Audio",
|
|
10
|
+
"Text to Speech"
|
|
11
|
+
],
|
|
12
|
+
"properties": {
|
|
13
|
+
"enabled": {
|
|
14
|
+
"type": "boolean",
|
|
15
|
+
"title": "Enabled",
|
|
16
|
+
"description": "Enable or disable the Venice Audio skill.",
|
|
17
|
+
"default": false
|
|
18
|
+
},
|
|
19
|
+
"voice_model": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"title": "Voice Model",
|
|
22
|
+
"x-link": "[Listen Voice Example](https://huggingface.co/spaces/hexgrad/Kokoro-TTS)",
|
|
23
|
+
"enum": [
|
|
24
|
+
"af_heart",
|
|
25
|
+
"bm_lewis",
|
|
26
|
+
"custom"
|
|
27
|
+
],
|
|
28
|
+
"x-enum-title": [
|
|
29
|
+
"af_heart (default female)",
|
|
30
|
+
"bm_lewis (default male)",
|
|
31
|
+
"Custom"
|
|
32
|
+
],
|
|
33
|
+
"description": "Text to speech tool",
|
|
34
|
+
"default": "af_heart"
|
|
35
|
+
},
|
|
36
|
+
"states": {
|
|
37
|
+
"type": "object",
|
|
38
|
+
"title": "Skill States",
|
|
39
|
+
"description": "Enable/disable specific voice models. Only enable one if you want a consistent characteristic for your agent. See docs for voice details and quality grades.",
|
|
40
|
+
"properties": {
|
|
41
|
+
"text_to_speech": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"title": "Text to Speech",
|
|
44
|
+
"enum": [
|
|
45
|
+
"disabled",
|
|
46
|
+
"public",
|
|
47
|
+
"private"
|
|
48
|
+
],
|
|
49
|
+
"x-enum-title": [
|
|
50
|
+
"Disabled",
|
|
51
|
+
"Agent Owner + All Users",
|
|
52
|
+
"Agent Owner Only"
|
|
53
|
+
],
|
|
54
|
+
"description": "Text to speech tool",
|
|
55
|
+
"default": "disabled"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"api_key_provider": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"title": "API Key Provider",
|
|
62
|
+
"description": "Provider of the API key",
|
|
63
|
+
"enum": [
|
|
64
|
+
"agent_owner"
|
|
65
|
+
],
|
|
66
|
+
"x-enum-title": [
|
|
67
|
+
"Owner Provided"
|
|
68
|
+
],
|
|
69
|
+
"default": "agent_owner"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"required": [
|
|
73
|
+
"states",
|
|
74
|
+
"enabled"
|
|
75
|
+
],
|
|
76
|
+
"allOf": [
|
|
77
|
+
{
|
|
78
|
+
"if": {
|
|
79
|
+
"properties": {
|
|
80
|
+
"voice_model": {
|
|
81
|
+
"const": "custom"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"then": {
|
|
86
|
+
"properties": {
|
|
87
|
+
"voice_model_custom": {
|
|
88
|
+
"type": "array",
|
|
89
|
+
"items": {
|
|
90
|
+
"type": "string"
|
|
91
|
+
},
|
|
92
|
+
"title": "Voice Model (Custom)",
|
|
93
|
+
"x-link": "[Supported Voice Model](https://docs.venice.ai/api-reference/endpoint/audio/speech#body-voice)",
|
|
94
|
+
"description": "You can add one or more custom voice models.",
|
|
95
|
+
"default": [
|
|
96
|
+
"af_heart",
|
|
97
|
+
"bm_lewis"
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"required": [
|
|
102
|
+
"voice_model_custom"
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"if": {
|
|
108
|
+
"allOf": [
|
|
109
|
+
{
|
|
110
|
+
"properties": {
|
|
111
|
+
"enabled": {
|
|
112
|
+
"const": true
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"properties": {
|
|
118
|
+
"api_key_provider": {
|
|
119
|
+
"const": "agent_owner"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
"then": {
|
|
126
|
+
"properties": {
|
|
127
|
+
"api_key": {
|
|
128
|
+
"type": "string",
|
|
129
|
+
"title": "Venice API Key",
|
|
130
|
+
"x-link": "[Get your API key](https://venice.ai/)",
|
|
131
|
+
"x-sensitive": true,
|
|
132
|
+
"description": "API Key for authenticating with the Venice AI API."
|
|
133
|
+
},
|
|
134
|
+
"rate_limit_number": {
|
|
135
|
+
"type": "integer",
|
|
136
|
+
"title": "Rate Limit Number",
|
|
137
|
+
"description": "Number of requests allowed per time window."
|
|
138
|
+
},
|
|
139
|
+
"rate_limit_minutes": {
|
|
140
|
+
"type": "integer",
|
|
141
|
+
"title": "Rate Limit Minutes",
|
|
142
|
+
"description": "Time window in minutes for rate limiting."
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"required": [
|
|
146
|
+
"api_key"
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
"additionalProperties": true
|
|
152
|
+
}
|