move examples to framework

This commit is contained in:
dbth
2025-01-02 09:14:21 +01:00
parent cee488bb70
commit 6ceeec556d
17 changed files with 112 additions and 118 deletions

View File

@@ -2,6 +2,7 @@ import json
from pathlib import Path
import dotenv
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks.generic_dvm import GenericDVM
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.dvmconfig import build_default_config
@@ -11,6 +12,8 @@ from nostr_sdk import Keys, Kind
def playground(announce=False):
framework = DVMFramework()
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = announce
admin_config.REBROADCAST_NIP65_RELAY_LIST = announce
@@ -51,7 +54,9 @@ def playground(announce=False):
return result
dvm.process = process # overwrite the process function with the above one
dvm.run(True)
framework.add(dvm)
framework.run()
if __name__ == '__main__':
env_path = Path('.env')

View File

@@ -1,6 +1,7 @@
import os
import signal
import time
from nostr_dvm.utils.print_utils import bcolors
class DVMFramework:
@@ -22,8 +23,13 @@ class DVMFramework:
time.sleep(0.1)
except KeyboardInterrupt:
for dvm in self.dvms:
if dvm.dvm_config.NIP89 is not None:
print(bcolors.CYAN + "Shuting down " + dvm.dvm_config.NIP89.NAME + bcolors.ENDC)
dvm.join()
print("All DVMs shut down.")
print(bcolors.GREEN +"All DVMs shut down." + bcolors.ENDC)
os.kill(os.getpid(), signal.SIGKILL)
exit(1)
def get_dvms(self):
return self.dvms

View File

@@ -111,14 +111,12 @@ class DVMTaskInterface:
print("Implement the run dvm function")
pass
def run(self, join=False):
def run(self):
try:
self.nostr_dvm_thread = Thread(target=self.DVM, args=[self.dvm_config, self.admin_config, lambda: self.stop_threads], daemon=False)
self.nostr_dvm_thread.start()
if join:
self.nostr_dvm_thread.join()
except BaseException as e:
print("gone")

View File

@@ -164,8 +164,11 @@ async def _build_network_from(index_map, network_graph, visited_pk=None, depth=2
else:
# recursive call
index_map, network_graph = await _build_network_from(index_map, network_graph, visited_pk, depth - 1, max_batch,
max_time_request, dvm_config=dvm_config)
try:
index_map, network_graph = await _build_network_from(index_map, network_graph, visited_pk, depth - 1, max_batch,
max_time_request, dvm_config=dvm_config)
except BaseException as e:
print(e)
print('current network: ' + str(len(network_graph.nodes())) + ' npubs', end='\r')

View File

@@ -6,6 +6,7 @@ import dotenv
from nostr_sdk import Keys
from nostr_dvm.bot import Bot
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks import textextraction_pdf, convert_media, discovery_inactive_follows, translation_google
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.definitions import EventDefinitions
@@ -17,6 +18,7 @@ from nostr_dvm.utils.zap_utils import check_and_set_ln_bits_keys
def playground():
framework = DVMFramework()
bot_config = DVMConfig()
identifier = "bot_test"
bot_config.PRIVATE_KEY = check_and_set_private_key(identifier)
@@ -32,7 +34,7 @@ def playground():
pdfextractor = textextraction_pdf.build_example("PDF Extractor", "pdf_extractor", admin_config)
# If we don't add it to the bot, the bot will not provide access to the DVM
pdfextractor.run()
framework.add(pdfextractor)
bot_config.SUPPORTED_DVMS.append(pdfextractor) # We add translator to the bot
ymhm_external = build_external_dvm(pubkey="58c52fdca7593dffea63ba6f758779d8251c6732f54e9dc0e56d7a1afe1bb1b6",
@@ -49,7 +51,7 @@ def playground():
media_bringer = convert_media.build_example("Nostr AI DVM Media Converter",
"media_converter", admin_config_media)
bot_config.SUPPORTED_DVMS.append(media_bringer)
media_bringer.run()
framework.add(media_bringer)
admin_config_followers = AdminConfig()
@@ -58,7 +60,7 @@ def playground():
discover_inactive = discovery_inactive_follows.build_example("Those who left",
"discovery_inactive_follows", admin_config_followers)
bot_config.SUPPORTED_DVMS.append(discover_inactive)
discover_inactive.run()
framework.add(discover_inactive)
admin_config_google = AdminConfig()
admin_config_google.UPDATE_PROFILE = True
@@ -66,7 +68,10 @@ def playground():
translator = translation_google.build_example("NostrAI DVM Translator", "google_translator", admin_config_google)
bot_config.SUPPORTED_DVMS.append(translator) # We add translator to the bot
translator.run()
framework.add(translator)
framework.run()
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP65_RELAY_LIST = True

View File

@@ -47,9 +47,7 @@ SYNC_DB_RELAY_LIST = ["wss://relay.damus.io",
"wss://nostr.oxtr.dev"]
RELAY_LIST = ["wss://relay.nostrdvm.com",
#"wss://relay.primal.net",
"wss://nostr.oxtr.dev",
#"wss://relay.nostr.net"
"wss://nostr.oxtr.dev"
]
if use_logger:
@@ -702,16 +700,11 @@ def playground():
database=DATABASE)
framework.add(db_scheduler)
#db_scheduler.run()
admin_config_gallery = AdminConfig()
admin_config_gallery.REBROADCAST_NIP89 = rebroadcast_NIP89
admin_config_gallery.REBROADCAST_NIP65_RELAY_LIST = rebroadcast_NIP65_Relay_List
admin_config_gallery.UPDATE_PROFILE = update_profile
# admin_config_global_popular.DELETE_NIP89 = True
# admin_config_global_popular.PRIVKEY = ""
# admin_config_global_popular.EVENTID = "2fea4ee2ccf0fa11db171113ffd7a676f800f34121478b7c9a4e73c2f1990028"
# admin_config_global_popular.POW = True
custom_processing_msg = ["Looking for popular Gallery entries"]
update_db = True

View File

@@ -5,6 +5,7 @@ from pathlib import Path
import dotenv
from nostr_sdk import init_logger, LogLevel
from nostr_dvm.framework import DVMFramework
# os.environ["RUST_BACKTRACE"] = "full"
from nostr_dvm.tasks.content_discovery_currently_popular_topic import DicoverContentCurrentlyPopularbyTopic
from nostr_dvm.tasks.content_discovery_update_db_only import DicoverContentDBUpdateScheduler
@@ -126,6 +127,8 @@ def build_example_topic(name, identifier, admin_config, options, image, descript
def playground():
framework = DVMFramework()
main_db = "db/nostr_recent_notes.db"
main_db_limit = 1024 # in mb
@@ -149,7 +152,8 @@ def playground():
cost=0,
update_db=True,
database=database)
db_scheduler.run()
framework.add(db_scheduler)
# Popular Animals (Fluffy frens)
admin_config = AdminConfig()
@@ -204,7 +208,9 @@ def playground():
update_db=update_db,
database=database)
discovery_animals.run()
framework.add(discovery_animals)
framework.run()
if __name__ == '__main__':

View File

@@ -4,6 +4,7 @@ from pathlib import Path
import dotenv
from nostr_sdk import init_logger, LogLevel
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks.content_discovery_currently_popular_topic import DicoverContentCurrentlyPopularbyTopic
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.dvmconfig import build_default_config
@@ -86,6 +87,8 @@ def build_example_topic(name, identifier, admin_config, options, image, descript
def playground():
framework = DVMFramework()
admin_config_plants = AdminConfig()
admin_config_plants.REBROADCAST_NIP89 = rebroadcast_NIP89
admin_config_plants.REBROADCAST_NIP65_RELAY_LIST = rebroadcast_NIP65_Relay_List
@@ -113,27 +116,11 @@ def playground():
cost=cost,
processing_msg=custom_processing_msg,
update_db=update_db)
discovery_custom.run()
# discovery_test_sub = content_discovery_currently_popular.build_example_subscription("Currently Popular Notes DVM (with Subscriptions)", "discovery_content_test", admin_config)
# discovery_test_sub.run()
framework.add(discovery_custom)
# Subscription Manager DVM
# subscription_config = DVMConfig()
# subscription_config.PRIVATE_KEY = check_and_set_private_key("dvm_subscription")
# npub = Keys.parse(subscription_config.PRIVATE_KEY).public_key().to_bech32()
# invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys("dvm_subscription", npub)
# subscription_config.LNBITS_INVOICE_KEY = invoice_key
# subscription_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
# subscription_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# sub_admin_config = AdminConfig()
# sub_admin_config.USERNPUBS = ["7782f93c5762538e1f7ccc5af83cd8018a528b9cd965048386ca1b75335f24c6"] #Add npubs of services that can contact the subscription handler
framework.run()
# currently there is none, but add this once subscriptions are live.
# x = threading.Thread(target=Subscription, args=(Subscription(subscription_config, sub_admin_config),))
# x.start()
# keep_alive()
if __name__ == '__main__':

View File

@@ -4,6 +4,7 @@ from pathlib import Path
import dotenv
from nostr_sdk import init_logger, LogLevel
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks.content_discovery_currently_popular_gallery import DicoverContentCurrentlyPopularGallery
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.dvmconfig import build_default_config
@@ -56,6 +57,8 @@ def build_example_gallery(name, identifier, admin_config, options, image, cost=0
def playground():
framework = DVMFramework()
# Popular Global
admin_config_global_gallery = AdminConfig()
admin_config_global_gallery.REBROADCAST_NIP89 = rebroadcast_NIP89
@@ -85,27 +88,12 @@ def playground():
update_rate=global_update_rate,
processing_msg=custom_processing_msg,
update_db=update_db)
discover_gallery.run()
# discovery_test_sub = content_discovery_currently_popular.build_example_subscription("Currently Popular Notes DVM (with Subscriptions)", "discovery_content_test", admin_config)
# discovery_test_sub.run()
framework.add(discover_gallery)
# Subscription Manager DVM
# subscription_config = DVMConfig()
# subscription_config.PRIVATE_KEY = check_and_set_private_key("dvm_subscription")
# npub = Keys.parse(subscription_config.PRIVATE_KEY).public_key().to_bech32()
# invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys("dvm_subscription", npub)
# subscription_config.LNBITS_INVOICE_KEY = invoice_key
# subscription_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
# subscription_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# sub_admin_config = AdminConfig()
# sub_admin_config.USERNPUBS = ["7782f93c5762538e1f7ccc5af83cd8018a528b9cd965048386ca1b75335f24c6"] #Add npubs of services that can contact the subscription handler
framework.run()
# currently there is none, but add this once subscriptions are live.
# x = threading.Thread(target=Subscription, args=(Subscription(subscription_config, sub_admin_config),))
# x.start()
# keep_alive()
if __name__ == '__main__':

View File

@@ -4,6 +4,7 @@ from pathlib import Path
import dotenv
from nostr_sdk import init_logger, LogLevel
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks.content_discovery_latest_one_per_follower import Discoverlatestperfollower
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.dvmconfig import build_default_config
@@ -63,6 +64,8 @@ def build_example_oneperfollow(name, identifier, admin_config, options, image, c
def playground():
framework = DVMFramework()
# Popular Global
admin_config_opf = AdminConfig()
admin_config_opf.REBROADCAST_NIP89 = rebroadcast_NIP89
@@ -83,7 +86,7 @@ def playground():
}
cost = 0
image = "https://i.nostr.build/H6SMmCl7eRDvkbAn.jpg"
discovery_one_per_follow = build_example_oneperfollow("Lasted per follow",
discovery_one_per_follow = build_example_oneperfollow("One per follow",
"discovery_latest_per_follow",
admin_config=admin_config_opf,
options=options_opf,
@@ -92,27 +95,12 @@ def playground():
update_rate=global_update_rate,
processing_msg=custom_processing_msg,
update_db=update_db)
discovery_one_per_follow.run()
# discovery_test_sub = content_discovery_currently_popular.build_example_subscription("Currently Popular Notes DVM (with Subscriptions)", "discovery_content_test", admin_config)
# discovery_test_sub.run()
framework.add(discovery_one_per_follow)
# Subscription Manager DVM
# subscription_config = DVMConfig()
# subscription_config.PRIVATE_KEY = check_and_set_private_key("dvm_subscription")
# npub = Keys.parse(subscription_config.PRIVATE_KEY).public_key().to_bech32()
# invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys("dvm_subscription", npub)
# subscription_config.LNBITS_INVOICE_KEY = invoice_key
# subscription_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
# subscription_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# sub_admin_config = AdminConfig()
# sub_admin_config.USERNPUBS = ["7782f93c5762538e1f7ccc5af83cd8018a528b9cd965048386ca1b75335f24c6"] #Add npubs of services that can contact the subscription handler
framework.run()
# currently there is none, but add this once subscriptions are live.
# x = threading.Thread(target=Subscription, args=(Subscription(subscription_config, sub_admin_config),))
# x.start()
# keep_alive()
if __name__ == '__main__':

View File

@@ -4,6 +4,7 @@ from pathlib import Path
import dotenv
from nostr_sdk import init_logger, LogLevel
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks.people_discovery_mywot import DiscoverPeopleMyWOT
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.dvmconfig import build_default_config
@@ -69,7 +70,7 @@ def build_example_wot(name, identifier, admin_config, options, image, cost=0, up
def playground():
framework = DVMFramework()
# Popular Global
admin_config_global_wot = AdminConfig()
admin_config_global_wot.REBROADCAST_NIP89 = rebroadcast_NIP89
@@ -97,27 +98,10 @@ def playground():
update_rate=global_update_rate,
processing_msg=custom_processing_msg,
update_db=update_db)
discovery_wot.run()
framework.add(discovery_wot)
# discovery_test_sub = content_discovery_currently_popular.build_example_subscription("Currently Popular Notes DVM (with Subscriptions)", "discovery_content_test", admin_config)
# discovery_test_sub.run()
framework.run()
# Subscription Manager DVM
# subscription_config = DVMConfig()
# subscription_config.PRIVATE_KEY = check_and_set_private_key("dvm_subscription")
# npub = Keys.parse(subscription_config.PRIVATE_KEY).public_key().to_bech32()
# invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys("dvm_subscription", npub)
# subscription_config.LNBITS_INVOICE_KEY = invoice_key
# subscription_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
# subscription_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# sub_admin_config = AdminConfig()
# sub_admin_config.USERNPUBS = ["7782f93c5762538e1f7ccc5af83cd8018a528b9cd965048386ca1b75335f24c6"] #Add npubs of services that can contact the subscription handler
# currently there is none, but add this once subscriptions are live.
# x = threading.Thread(target=Subscription, args=(Subscription(subscription_config, sub_admin_config),))
# x.start()
# keep_alive()

View File

@@ -4,6 +4,7 @@ from pathlib import Path
import dotenv
from nostr_sdk import init_logger, LogLevel
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks.content_discovery_currently_latest_longform import DicoverContentLatestLongForm
from nostr_dvm.tasks.content_discovery_currently_latest_wiki import DicoverContentLatestWiki
from nostr_dvm.tasks.content_discovery_currently_popular_gallery import DicoverContentCurrentlyPopularGallery
@@ -588,6 +589,7 @@ def build_example_oneperfollow(name, identifier, admin_config, options, image, c
def playground():
framework = DVMFramework()
#DB Scheduler, do not announce, just use it to update the DB for the other DVMs.
admin_config_db_scheduler= AdminConfig()
@@ -606,7 +608,8 @@ def playground():
update_rate=global_update_rate,
cost=0,
update_db=True)
db_scheduler.run()
framework.add(db_scheduler)
@@ -643,7 +646,7 @@ def playground():
processing_msg=custom_processing_msg,
update_db=update_db)
discovery_topzaps.run()
framework.add(discovery_topzaps)
admin_config_plants = AdminConfig()
admin_config_plants.REBROADCAST_NIP89 = rebroadcast_NIP89
@@ -672,7 +675,9 @@ def playground():
cost=cost,
processing_msg=custom_processing_msg,
update_db=update_db)
discovery_custom.run(True)
framework.add(discovery_custom)
framework.run

View File

@@ -5,6 +5,7 @@ from pathlib import Path
import dotenv
from nostr_sdk import init_logger, LogLevel
from nostr_dvm.framework import DVMFramework
# os.environ["RUST_BACKTRACE"] = "full"
from nostr_dvm.tasks.content_discovery_currently_popular_tweets import DicoverContentCurrentlyPopularTweets
from nostr_dvm.tasks.content_discovery_update_db_only import DicoverContentDBUpdateScheduler
@@ -126,6 +127,7 @@ def build_example_tweets(name, identifier, admin_config, options, image, descrip
def playground():
framework = DVMFramework()
main_db = "db/nostr_recent_notes.db"
main_db_limit = 1024 # in mb
@@ -149,7 +151,8 @@ def playground():
cost=0,
update_db=True,
database=database)
db_scheduler.run()
framework.add(db_scheduler)
# Popular Tweets
admin_config = AdminConfig()
@@ -180,7 +183,9 @@ def playground():
update_db=update_db,
database=database)
discovery_tweets.run()
framework.add(discovery_tweets)
framework.run()
if __name__ == '__main__':

View File

@@ -2,11 +2,13 @@ from pathlib import Path
import dotenv
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks import discovery_bot_farms
from nostr_dvm.utils.admin_utils import AdminConfig
def playground():
framework = DVMFramework()
# Generate an optional Admin Config, in this case, whenever we give our DVMs this config, they will (re)broadcast
# their NIP89 announcement
# You can create individual admins configs and hand them over when initializing the dvm,
@@ -17,16 +19,15 @@ def playground():
admin_config.UPDATE_PROFILE = False
#discovery_test_sub = discovery_censor_wot.build_example("Censorship", "discovery_censor", admin_config)
#discovery_test_sub.run()
#framework.add(discovery_test_sub)
discovery_test_sub = discovery_bot_farms.build_example("Bot Hunter", "discovery_botfarms", admin_config)
discovery_test_sub.run()
framework.add(discovery_test_sub)
#discovery_test_sub = discovery_inactive_follows.build_example("Inactive Followings", "discovery_inactive", admin_config)
#discovery_test_sub.run()
#framework.add(discovery_test_sub)
#keep_alive()
framework.run()
if __name__ == '__main__':

View File

@@ -7,6 +7,7 @@ import dotenv
from nostr_sdk import LogLevel, init_logger
from nostr_dvm.bot import Bot
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks.convert_media import MediaConverter
from nostr_dvm.tasks.discovery_bot_farms import DiscoveryBotFarms
from nostr_dvm.tasks.discovery_censor_wot import DiscoverReports
@@ -422,6 +423,9 @@ def build_replicate_fluxpro(name, identifier, announce):
def playground(announce=False):
framework = DVMFramework()
#bot_config = DVMConfig()
bot_config = build_default_config("bot")
bot_config.AVOID_OUTBOX_RELAY_LIST = AVOID_OUTBOX_RELAY_LIST
@@ -436,48 +440,51 @@ def playground(announce=False):
if os.getenv("OPENAI_API_KEY") is not None and os.getenv("OPENAI_API_KEY") != "":
dalle = build_dalle("Dall-E 3", "dalle3", announce)
bot_config.SUPPORTED_DVMS.append(dalle)
dalle.run()
framework.add(dalle)
if os.getenv("STABILITY_KEY") is not None and os.getenv("STABILITY_KEY") != "":
sd35 = build_sd35("Stable Diffusion Ultra", "sd35", announce)
sd35.run()
framework.add(sd35)
if os.getenv("REPLICATE_API_TOKEN") is not None and os.getenv("REPLICATE_API_TOKEN") != "":
model = "stability-ai/stable-diffusion-3.5-large"
sd3replicate = build_replicate("Stable Diffusion 3.5 Large", "replicate_svd", model, announce)
bot_config.SUPPORTED_DVMS.append(sd3replicate)
sd3replicate.run()
framework.add(sd3replicate)
model = "black-forest-labs/flux-1.1-pro"
fluxreplicate = build_replicate_fluxpro("Flux 1.1. Pro", "fluxpro", announce)
bot_config.SUPPORTED_DVMS.append(fluxreplicate)
fluxreplicate.run()
framework.add(fluxreplicate)
recraftreplicate = build_replicate_recraft("Recraft v3", "recraftsvg", announce)
bot_config.SUPPORTED_DVMS.append(recraftreplicate)
recraftreplicate.run()
framework.add(recraftreplicate)
media_bringer = build_media_converter("Nostr AI DVM Media Converter", "media_converter", announce)
#bot_config.SUPPORTED_DVMS.append(media_bringer)
media_bringer.run()
framework.add(media_bringer)
discover_inactive = build_inactive_follows_finder("Those who left", "discovery_inactive_follows", announce)
bot_config.SUPPORTED_DVMS.append(discover_inactive)
discover_inactive.run()
framework.add(discover_inactive)
discovery_censor = build_1984("Censorship 1984", "discovery_censor", announce)
#bot_config.SUPPORTED_DVMS.append(discovery_censor)
discovery_censor.run()
framework.add(discovery_censor)
discovery_bots = build_botfarms("Bot Hunter", "discovery_botfarms", announce)
#bot_config.SUPPORTED_DVMS.append(discovery_bots)
discovery_bots.run()
framework.add(discovery_bots)
framework.run()
admin_config = AdminConfig()

View File

@@ -5,6 +5,7 @@ from pathlib import Path
import dotenv
from nostr_sdk import Keys, LogLevel, init_logger
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks.advanced_search import AdvancedSearch
from nostr_dvm.tasks.advanced_search_wine import AdvancedSearchWine
from nostr_dvm.tasks.search_users import SearchUser
@@ -199,15 +200,22 @@ def build_user_search(name, identifier):
def playground():
framework = DVMFramework()
advanced_search = build_advanced_search("Nostr.band Search",
"discovery_content_search")
advanced_search.run()
framework.add(advanced_search)
advanced_search_wine = build_advanced_search_wine("Nostr.wine Search", "discovery_content_searchwine")
advanced_search_wine.run()
framework.add(advanced_search_wine)
framework.run()
#profile_search = build_user_search("Profile Searcher", "profile_search")
#profile_search.run()
#framework.add(profile_search)
framework.run()

View File

@@ -3,6 +3,7 @@ from pathlib import Path
import dotenv
from nostr_dvm.framework import DVMFramework
from nostr_dvm.tasks.texttospeech import TextToSpeech
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.dvmconfig import build_default_config
@@ -15,6 +16,8 @@ if __name__ == '__main__':
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
framework = DVMFramework()
name = "TTS Guy Swann"
identifier = "ttsguy"
admin_config_tts = AdminConfig()
@@ -51,4 +54,6 @@ if __name__ == '__main__':
nip89config.CONTENT = json.dumps(nip89info)
tts = TextToSpeech(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=admin_config_tts,
options=options)
tts.run()
framework.add(tts)
framework.run()