move examples from playground to modules

This commit is contained in:
Believethehype 2023-12-01 19:11:13 +01:00
parent 56cdddce2c
commit fa2b9d266c
14 changed files with 747 additions and 518 deletions

166
main.py
View File

@ -1,21 +1,33 @@
import json
import os
import signal
import time
from pathlib import Path
import dotenv
from nostr_sdk import PublicKey
from bot.bot import Bot
from playground import build_pdf_extractor, build_googletranslator, build_unstable_diffusion, build_sketcher, \
build_dalle, \
build_whisperx, build_libretranslator, build_external_dvm, build_media_converter, build_inactive_follows_finder, \
build_image_converter, build_googletranscribe
from interfaces.dvmtaskinterface import DVMTaskInterface
import tasks.convert_media as convert_media
import tasks.discovery_inactive_follows as discovery_inactive_follows
import tasks.imagegeneration_openai_dalle as imagegeneration_openai_dalle
import tasks.imagegeneration_sdxl as imagegeneration_sdxl
import tasks.imagegeneration_sdxlimg2img as imagegeneration_sdxlimg2img
import tasks.textextraction_pdf as textextraction_pdf
import tasks.textextraction_google as textextraction_google
import tasks.textextraction_whisperx as textextraction_whisperx
import tasks.translation_google as translation_google
import tasks.translation_libretranslate as translation_libretranslate
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.definitions import EventDefinitions
from utils.dvmconfig import DVMConfig
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.nostr_utils import check_and_set_private_key
from utils.output_utils import PostProcessFunctionType
def run_nostr_dvm_with_local_config():
def playground():
# We will run an optional bot that can communicate with the DVMs
# Note this is very basic for now and still under development
bot_config = DVMConfig()
@ -24,54 +36,108 @@ def run_nostr_dvm_with_local_config():
bot_config.LNBITS_ADMIN_KEY = os.getenv("LNBITS_ADMIN_KEY") # The bot will forward zaps for us, use responsibly
bot_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# 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,
# for example to whilelist users or add to their balance.
# If you use this global config, options will be set for all dvms that use it.
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
# Set rebroadcast to true once you have set your NIP89 descriptions and d tags. You only need to rebroadcast once you
# want to update your NIP89 descriptions
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
# Spawn some DVMs in the playground and run them
# You can add arbitrary DVMs there and instantiate them here
# Spawn DVM1 Kind 5000: A local Text Extractor from PDFs
pdfextractor = build_pdf_extractor("PDF Extractor", "pdf_extractor")
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()
# Spawn DVM2 Kind 5002 Local Text TranslationGoogle, calling the free Google API.
translator = build_googletranslator("Google Translator", "google_translator")
translator = translation_google.build_example("Google Translator", "google_translator", admin_config)
bot_config.SUPPORTED_DVMS.append(translator) # We add translator to the bot
translator.run()
# Spawn DVM3 Kind 5002 Local Text TranslationLibre, calling the free LibreTranslateApi, as an alternative.
# This will only run and appear on the bot if an endpoint is set in the .env
if os.getenv("LIBRE_TRANSLATE_ENDPOINT") is not None and os.getenv("LIBRE_TRANSLATE_ENDPOINT") != "":
libre_translator = build_libretranslator("Libre Translator", "libre_translator")
libre_translator = translation_libretranslate.build_example("Libre Translator", "libre_translator", admin_config)
bot_config.SUPPORTED_DVMS.append(libre_translator) # We add translator to the bot
libre_translator.run()
# Spawn DVM3 Kind 5100 Image Generation This one uses a specific backend called nova-server.
# If you want to use it, see the instructions in backends/nova_server
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
unstable_artist = build_unstable_diffusion("Unstable Diffusion", "unstable_diffusion")
bot_config.SUPPORTED_DVMS.append(unstable_artist) # We add unstable Diffusion to the bot
unstable_artist.run()
stable_artist = imagegeneration_sdxl.build_example("Stable Diffusion XL", "stable_diffusion",
admin_config, os.getenv("NOVA_SERVER"),
"stabilityai/stable-diffusion-xl",
"")
bot_config.SUPPORTED_DVMS.append(stable_artist) # We add unstable Diffusion to the bot
stable_artist.run()
# Spawn DVM4, another Instance of text-to-image, as before but use a different privatekey, model and lora this time.
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
sketcher = build_sketcher("Sketcher", "sketcher")
# Let's not use one of the examples in this one, but generate our own variation of the dvm. We make a new DVM
# called "Sketcher", with a predefined model and lora, so it will always make sketches of prompts
def build_sketcher(name, identifier, admin_config):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
nip90params = {
"negative_prompt": {
"required": False,
"values": []
},
"ratio": {
"required": False,
"values": ["1:1", "4:3", "16:9", "3:4", "9:16", "10:16"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/229c14e440895da30de77b3ca145d66d4b04efb4027ba3c44ca147eecde891f1.jpg",
"about": "I draw images based on a prompt in the style of paper sketches",
"nip90Params": nip90params
}
# A module might have options it can be initialized with, here we set a default model, lora and the nova-server
# address it should use. These parameters can be freely defined in the task component
options = {'default_model': "mohawk", 'default_lora': "timburton", 'nova_server': os.getenv("NOVA_SERVER")}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
return imagegeneration_sdxl.ImageGenerationSDXL(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
sketcher = build_sketcher("Sketcher", "sketcher", admin_config)
bot_config.SUPPORTED_DVMS.append(sketcher) # We also add Sketcher to the bot
sketcher.run()
# Spawn DVM5, image-to-image, .
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
imageconverter = build_image_converter("Image Converter Inkpunk", "image_converter_inkpunk")
imageconverter = imagegeneration_sdxlimg2img.build_example("Image Converter Inkpunk",
"image_converter_inkpunk", admin_config,
os.getenv("NOVA_SERVER"),
"inkpunk", 0.6)
bot_config.SUPPORTED_DVMS.append(imageconverter) # We also add Sketcher to the bot
imageconverter.run()
# Spawn DVM5, Another script on nova-server calling WhisperX to transcribe media files
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
whisperer = build_whisperx("Whisperer", "whisperx")
whisperer = textextraction_whisperx.build_example("Whisperer", "whisperx", admin_config, os.getenv("NOVA_SERVER"))
bot_config.SUPPORTED_DVMS.append(whisperer) # We also add Sketcher to the bot
whisperer.run()
transcriptor = build_googletranscribe("Transcriptor", "speech_recognition")
transcriptor = textextraction_google.build_example("Transcriptor", "speech_recognition", admin_config)
bot_config.SUPPORTED_DVMS.append(transcriptor) # We also add Sketcher to the bot
transcriptor.run()
@ -79,56 +145,68 @@ def run_nostr_dvm_with_local_config():
# per call. Make sure you have enough balance and the DVM's cost is set higher than what you pay yourself, except, you know,
# you're being generous.
if os.getenv("OPENAI_API_KEY") is not None and os.getenv("OPENAI_API_KEY") != "":
dalle = build_dalle("Dall-E 3", "dalle3")
dalle = imagegeneration_openai_dalle.build_example("Dall-E 3", "dalle3", admin_config)
bot_config.SUPPORTED_DVMS.append(dalle)
dalle.run()
#Let's define a function so we can add external DVMs to our bot, we will instanciate it afterwards
def build_external_dvm(name, pubkey, task, kind, fix_cost, per_unit_cost,
external_post_process=PostProcessFunctionType.NONE):
dvm_config = DVMConfig()
dvm_config.PUBLIC_KEY = PublicKey.from_hex(pubkey).to_hex()
dvm_config.FIX_COST = fix_cost
dvm_config.PER_UNIT_COST = per_unit_cost
dvm_config.EXTERNAL_POST_PROCESS_TYPE = external_post_process
nip89info = {
"name": name,
}
nip89config = NIP89Config()
nip89config.KIND = kind
nip89config.CONTENT = json.dumps(nip89info)
interface = DVMTaskInterface(name=name, dvm_config=dvm_config, nip89config=nip89config, task=task)
return interface
# Spawn DVM7.. oh wait, actually we don't spawn a new DVM, we use the dvmtaskinterface to define an external dvm by providing some info about it, such as
# their pubkey, a name, task, kind etc. (unencrypted)
tasktiger_external = build_external_dvm(name="External DVM: TaskTiger",
pubkey="d483935d6bfcef3645195c04c97bbb70aedb6e65665c5ea83e562ca3c7acb978",
task="text-to-image",
kind=EventDefinitions.KIND_NIP90_GENERATE_IMAGE,
fix_cost=80, per_unit_cost=0)
pubkey="d483935d6bfcef3645195c04c97bbb70aedb6e65665c5ea83e562ca3c7acb978",
task="text-to-image",
kind=EventDefinitions.KIND_NIP90_GENERATE_IMAGE,
fix_cost=80, per_unit_cost=0)
tasktiger_external.SUPPORTS_ENCRYPTION = False # if the dvm does not support encrypted events, just send a regular event and mark it with p tag. Other dvms might initial answer
tasktiger_external.SUPPORTS_ENCRYPTION = False # if the dvm does not support encrypted events, just send a regular NIP90 event and mark it with p tag. Other dvms might answer initally
bot_config.SUPPORTED_DVMS.append(tasktiger_external)
# Don't run it, it's on someone else's machine, and we simply make the bot aware of it.
# Spawn DVM8 A Media Grabber/Converter
media_bringer = convert_media.build_example("Media Bringer", "media_converter", admin_config)
bot_config.SUPPORTED_DVMS.append(media_bringer)
media_bringer.run()
# DVM: 8 Another external dvm for recommendations:
# DVM: 9 Another external dvm for recommendations:
ymhm_external = build_external_dvm(name="External DVM: You might have missed",
pubkey="6b37d5dc88c1cbd32d75b713f6d4c2f7766276f51c9337af9d32c8d715cc1b93",
task="content-discovery",
kind=EventDefinitions.KIND_NIP90_CONTENT_DISCOVERY,
fix_cost=0, per_unit_cost=0,
external_post_process=PostProcessFunctionType.LIST_TO_EVENTS)
# If we get back a list of people or events, we can post-process it to make it readable in social clients
ymhm_external.SUPPORTS_ENCRYPTION = False # if the dvm does not support encrypted events, just send a regular event and mark it with p tag. Other dvms might initial answer
ymhm_external.SUPPORTS_ENCRYPTION = False
bot_config.SUPPORTED_DVMS.append(ymhm_external)
# Spawn DVM9.. A Media Grabber/Converter
media_bringer = build_media_converter("Media Bringer", "media_converter")
bot_config.SUPPORTED_DVMS.append(media_bringer)
media_bringer.run()
# Spawn DVM10 Discover inactive followers
discover_inactive = build_inactive_follows_finder("Bygones", "discovery_inactive_follows")
# Spawn DVM10 Find inactive followers
discover_inactive = discovery_inactive_follows.build_example("Bygones", "discovery_inactive_follows",
admin_config)
bot_config.SUPPORTED_DVMS.append(discover_inactive)
discover_inactive.run()
Bot(bot_config)
# Keep the main function alive for libraries that require it, like openai
try:
while True:
time.sleep(10)
except KeyboardInterrupt:
os.kill(os.getpid(), signal.SIGKILL)
exit(1)
keep_alive()
if __name__ == '__main__':
@ -138,4 +216,4 @@ if __name__ == '__main__':
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
run_nostr_dvm_with_local_config()
playground()

View File

@ -1,455 +0,0 @@
import json
import os
from nostr_sdk import PublicKey
from interfaces.dvmtaskinterface import DVMTaskInterface
from tasks.convert_media import MediaConverter
from tasks.discovery_inactive_follows import DiscoverInactiveFollows
from tasks.imagegeneration_openai_dalle import ImageGenerationDALLE
from tasks.imagegeneration_sdxl import ImageGenerationSDXL
from tasks.imagegeneration_sdxlimg2img import ImageGenerationSDXLIMG2IMG
from tasks.textextraction_google import SpeechToTextGoogle
from tasks.textextraction_whisperx import SpeechToTextWhisperX
from tasks.textextraction_pdf import TextExtractionPDF
from tasks.translation_google import TranslationGoogle
from tasks.translation_libretranslate import TranslationLibre
from utils.admin_utils import AdminConfig
from utils.dvmconfig import DVMConfig
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.nostr_utils import check_and_set_private_key
from utils.output_utils import PostProcessFunctionType
"""
This File is a playground to create DVMs. It shows some examples of DVMs that make use of the modules in the tasks folder
These DVMs should be considered examples and will be extended in the future.
Keys and dtags will be automatically generated and stored in the .env file.
If you already have a pk and dtag you can replace them there before publishing the nip89
Note that the admin_config is optional, and if given commands as defined in admin_utils will be called at start of the
DVM. For example the NIP89 event can be rebroadcasted.
If LNBITS_INVOICE_KEY is not set (=""), the DVM is still zappable but a lud16 address in required in the profile.
Additional options can be set, for example to preinitalize vaiables or give parameters that are required to perform a
task, for example an address or an API key.
"""
# 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,
# for example to whilelist users or add to their balance.
# If you use this global config, options will be set for all dvms that use it.
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
# Set rebroadcast to true once you have set your NIP89 descriptions and d tags. You only need to rebroadcast once you
# want to update your NIP89 descriptions
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
# Auto update the profiles of your privkeys based on the nip89 information.
# Ideally set a lightning address in the LUD16 field above so our DVMs can get zapped from everywhere
# We build a couple of example dvms, create privatekeys and dtags and set their NIP89 descriptions
# We currently call these from the main function and start the dvms there.
def build_pdf_extractor(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# Add NIP89
nip90params = {}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I extract text from pdf documents",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return TextExtractionPDF(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
def build_googletranslator(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
nip90params = {
"language": {
"required": False,
"values": ["en", "az", "be", "bg", "bn", "bs", "ca", "ceb", "co", "cs", "cy", "da", "de", "el", "eo", "es",
"et", "eu", "fa", "fi", "fr", "fy", "ga", "gd", "gl", "gu", "ha", "haw", "hi", "hmn", "hr", "ht",
"hu", "hy", "id", "ig", "is", "it", "he", "ja", "jv", "ka", "kk", "km", "kn", "ko", "ku", "ky",
"la", "lb", "lo", "lt", "lv", "mg", "mi", "mk", "ml", "mn", "mr", "ms", "mt", "my", "ne", "nl",
"no", "ny", "or", "pa", "pl", "ps", "pt", "ro", "ru", "sd", "si", "sk", "sl", "sm", "sn", "so",
"sq", "sr", "st", "su", "sv", "sw", "ta", "te", "tg", "th", "tl", "tr", "ug", "uk", "ur", "uz",
"vi", "xh", "yi", "yo", "zh", "zu"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I translate text from given text/event/job. Currently using Google TranslationGoogle Services to translate "
"input into the language defined in params.",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return TranslationGoogle(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=admin_config)
def build_libretranslator(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
options = {'libre_end_point': os.getenv("LIBRE_TRANSLATE_ENDPOINT"),
'libre_api_key': os.getenv("LIBRE_TRANSLATE_API_KEY")}
nip90params = {
"language": {
"required": False,
"values": ["en", "az", "be", "bg", "bn", "bs", "ca", "ceb", "co", "cs", "cy", "da", "de", "el", "eo", "es",
"et", "eu", "fa", "fi", "fr", "fy", "ga", "gd", "gl", "gu", "ha", "haw", "hi", "hmn", "hr", "ht",
"hu", "hy", "id", "ig", "is", "it", "he", "ja", "jv", "ka", "kk", "km", "kn", "ko", "ku", "ky",
"la", "lb", "lo", "lt", "lv", "mg", "mi", "mk", "ml", "mn", "mr", "ms", "mt", "my", "ne", "nl",
"no", "ny", "or", "pa", "pl", "ps", "pt", "ro", "ru", "sd", "si", "sk", "sl", "sm", "sn", "so",
"sq", "sr", "st", "su", "sv", "sw", "ta", "te", "tg", "th", "tl", "tr", "ug", "uk", "ur", "uz",
"vi", "xh", "yi", "yo", "zh", "zu"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I translate text from given text/event/job using LibreTranslate Services to translate "
"input into the language defined in params.",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return TranslationLibre(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
def build_unstable_diffusion(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = "" # This one will not use Lnbits to create invoices, but rely on zaps
dvm_config.LNBITS_URL = ""
# A module might have options it can be initialized with, here we set a default model, and the nova-server
# address it should use. These parameters can be freely defined in the task component
options = {'default_model': "unstable", 'nova_server': os.getenv("NOVA_SERVER")}
nip90params = {
"negative_prompt": {
"required": False,
"values": []
},
"ratio": {
"required": False,
"values": ["1:1", "4:3", "16:9", "3:4", "9:16", "10:16"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I draw images based on a prompt with a Model called unstable diffusion",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return ImageGenerationSDXL(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
def build_whisperx(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# A module might have options it can be initialized with, here we set a default model, and the nova-server
# address it should use. These parameters can be freely defined in the task component
options = {'default_model': "base", 'nova_server': os.getenv("NOVA_SERVER")}
nip90params = {
"model": {
"required": False,
"values": ["base", "tiny", "small", "medium", "large-v1", "large-v2", "tiny.en", "base.en", "small.en",
"medium.en"]
},
"alignment": {
"required": False,
"values": ["raw", "segment", "word"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I extract text from media files with WhisperX",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return SpeechToTextWhisperX(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
def build_googletranscribe(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
options = {'api_key': None}
# A module might have options it can be initialized with, here we set a default model, and the nova-server
# address it should use. These parameters can be freely defined in the task component
nip90params = {
"language": {
"required": False,
"values": ["en-US"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I extract text from media files with the Google API. I understand English by default",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return SpeechToTextGoogle(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
def build_sketcher(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
nip90params = {
"negative_prompt": {
"required": False,
"values": []
},
"ratio": {
"required": False,
"values": ["1:1", "4:3", "16:9", "3:4", "9:16", "10:16"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/229c14e440895da30de77b3ca145d66d4b04efb4027ba3c44ca147eecde891f1.jpg",
"about": "I draw images based on a prompt in the style of paper sketches",
"nip90Params": nip90params
}
# A module might have options it can be initialized with, here we set a default model, lora and the nova-server
# address it should use. These parameters can be freely defined in the task component
options = {'default_model': "mohawk", 'default_lora': "timburton", 'nova_server': os.getenv("NOVA_SERVER")}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
return ImageGenerationSDXL(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
def build_image_converter(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
nip90params = {
"negative_prompt": {
"required": False,
"values": []
},
"lora": {
"required": False,
"values": ["inkpunk", "timburton", "voxel"]
},
"strength": {
"required": False,
"values": []
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/229c14e440895da30de77b3ca145d66d4b04efb4027ba3c44ca147eecde891f1.jpg",
"about": "I convert an image to another image, kinda random for now. ",
"nip90Params": nip90params
}
# A module might have options it can be initialized with, here we set a default model, lora and the nova-server
options = {'default_lora': "inkpunk", 'strength': 0.5, 'nova_server': os.getenv("NOVA_SERVER")}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
return ImageGenerationSDXLIMG2IMG(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
def build_dalle(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
profit_in_sats = 10
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip90params = {
"size": {
"required": False,
"values": ["1024:1024", "1024x1792", "1792x1024"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I use OpenAI's DALL·E 3",
"nip90Params": nip90params
}
# A module might have options it can be initialized with, here we set a default model, lora and the nova-server
# address it should use. These parameters can be freely defined in the task component
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
return ImageGenerationDALLE(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=admin_config)
def build_media_converter(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# Add NIP89
nip90params = {
"media_format": {
"required": False,
"values": ["video/mp4", "audio/mp3"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I convert videos from urls to given output format.",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return MediaConverter(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
def build_inactive_follows_finder(name, identifier):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# Add NIP89
nip90params = {
"user": {
"required": False,
"values": [],
"description": "Do the task for another user"
},
"since_days": {
"required": False,
"values": [],
"description": "The number of days a user has not been active to be considered inactive"
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I discover users you follow, but that have been inactive on Nostr",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return DiscoverInactiveFollows(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
# This function can be used to build a DVM object for a DVM we don't control, but we want the bot to be aware of.
# See main.py for examples.
def build_external_dvm(name, pubkey, task, kind, fix_cost, per_unit_cost, external_post_process=PostProcessFunctionType.NONE):
dvm_config = DVMConfig()
dvm_config.PUBLIC_KEY = PublicKey.from_hex(pubkey).to_hex()
dvm_config.FIX_COST = fix_cost
dvm_config.PER_UNIT_COST = per_unit_cost
dvm_config.EXTERNAL_POST_PROCESS_TYPE = external_post_process
nip89info = {
"name": name,
}
nip89config = NIP89Config()
nip89config.KIND = kind
nip89config.CONTENT = json.dumps(nip89info)
interface = DVMTaskInterface(name=name, dvm_config=dvm_config, nip89config=nip89config, task=task)
return interface
# Little optional Gimmick:
# For Dalle where we have to pay 4cent per image to openai, we fetch current sat price in fiat from coinstats api
# and update cost at each start
def get_price_per_sat(currency):
import requests
url = "https://api.coinstats.app/public/v1/coins"
params = {"skip": 0, "limit": 1, "currency": currency}
try:
response = requests.get(url, params=params)
response_json = response.json()
bitcoin_price = response_json["coins"][0]["price"]
price_currency_per_sat = bitcoin_price / 100000000.0
except:
price_currency_per_sat = 0.0004
return price_currency_per_sat

View File

@ -1,11 +1,19 @@
import json
import os
import signal
import time
from pathlib import Path
import dotenv
from interfaces.dvmtaskinterface import DVMTaskInterface
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.definitions import EventDefinitions
from utils.dvmconfig import DVMConfig
from utils.nip89_utils import NIP89Config
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.mediasource_utils import organize_input_media_data
from utils.nostr_utils import check_and_set_private_key
from utils.output_utils import upload_media_to_hoster
"""
@ -57,7 +65,8 @@ class MediaConverter(DVMTaskInterface):
if param == "format": # check for param type
media_format = tag.as_vec()[2]
filepath = organize_input_media_data(url, input_type, start_time, end_time, dvm_config, client, True, media_format)
filepath = organize_input_media_data(url, input_type, start_time, end_time, dvm_config, client, True,
media_format)
options = {
"filepath": filepath
}
@ -70,3 +79,52 @@ class MediaConverter(DVMTaskInterface):
url = upload_media_to_hoster(options["filepath"])
return url
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# Add NIP89
nip90params = {
"media_format": {
"required": False,
"values": ["video/mp4", "audio/mp3"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I convert videos from urls to given output format.",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return MediaConverter(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
if __name__ == '__main__':
env_path = Path('.env')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
dvm = build_example("Media Bringer", "media_converter", admin_config)
dvm.run()
keep_alive()

View File

@ -2,16 +2,20 @@ import json
import os
import re
from datetime import timedelta
from pathlib import Path
from threading import Thread
import dotenv
from nostr_sdk import Client, Timestamp, PublicKey, Tag, Keys, Options, Alphabet
from interfaces.dvmtaskinterface import DVMTaskInterface
from tasks.convert_media import MediaConverter
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.definitions import EventDefinitions
from utils.dvmconfig import DVMConfig
from utils.nip89_utils import NIP89Config
from utils.nostr_utils import get_event_by_id
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.nostr_utils import get_event_by_id, check_and_set_private_key
from utils.output_utils import post_process_list_to_users
"""
@ -163,3 +167,59 @@ class DiscoverInactiveFollows(DVMTaskInterface):
# if not text/plain, don't post-process
return result
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# Add NIP89
nip90params = {
"user": {
"required": False,
"values": [],
"description": "Do the task for another user"
},
"since_days": {
"required": False,
"values": [],
"description": "The number of days a user has not been active to be considered inactive"
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I discover users you follow, but that have been inactive on Nostr",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return DiscoverInactiveFollows(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
if __name__ == '__main__':
env_path = Path('.env')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
dvm = build_example("Bygones", "discovery_inactive_follows", admin_config)
dvm.run()
keep_alive()

View File

@ -1,15 +1,21 @@
import json
import os
from io import BytesIO
from pathlib import Path
import dotenv
import requests
from PIL import Image
from interfaces.dvmtaskinterface import DVMTaskInterface
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.definitions import EventDefinitions
from utils.dvmconfig import DVMConfig
from utils.nip89_utils import NIP89Config
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.nostr_utils import check_and_set_private_key
from utils.output_utils import upload_media_to_hoster
from utils.zap_utils import get_price_per_sat
"""
This File contains a Module to transform Text input on NOVA-Server and receive results back.
@ -116,3 +122,54 @@ class ImageGenerationDALLE(DVMTaskInterface):
except Exception as e:
print("Error in Module")
raise Exception(e)
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
profit_in_sats = 10
dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats))
nip90params = {
"size": {
"required": False,
"values": ["1024:1024", "1024x1792", "1792x1024"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I use OpenAI's DALL·E 3",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
return ImageGenerationDALLE(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=admin_config)
if __name__ == '__main__':
env_path = Path('.env')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
dvm = build_example("Dall-E 3", "dalle3", admin_config)
dvm.run()
keep_alive()

View File

@ -1,12 +1,18 @@
import json
import os
from multiprocessing.pool import ThreadPool
from pathlib import Path
import dotenv
from backends.nova_server import check_nova_server_status, send_request_to_nova_server
from interfaces.dvmtaskinterface import DVMTaskInterface
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.dvmconfig import DVMConfig
from utils.nip89_utils import NIP89Config
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.definitions import EventDefinitions
from utils.nostr_utils import check_and_set_private_key
"""
This File contains a Module to transform Text input on NOVA-Server and receive results back.
@ -51,7 +57,7 @@ class ImageGenerationSDXL(DVMTaskInterface):
prompt = ""
negative_prompt = ""
if self.options.get("default_model"):
if self.options.get("default_model") and self.options.get("default_model") != "":
model = self.options['default_model']
else:
model = "stabilityai/stable-diffusion-xl-base-1.0"
@ -60,7 +66,7 @@ class ImageGenerationSDXL(DVMTaskInterface):
ratio_height = "1"
width = ""
height = ""
if self.options.get("default_lora"):
if self.options.get("default_lora") and self.options.get("default_lora") != "":
lora = self.options['default_lora']
else:
lora = ""
@ -155,3 +161,58 @@ class ImageGenerationSDXL(DVMTaskInterface):
except Exception as e:
raise Exception(e)
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config, server_address, default_model="stabilityai/stable-diffusion-xl"
"-base-1.0", default_lora=""):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = "" # This one will not use Lnbits to create invoices, but rely on zaps
dvm_config.LNBITS_URL = ""
# A module might have options it can be initialized with, here we set a default model, and the nova-server
# address it should use. These parameters can be freely defined in the task component
options = {'default_model': default_model, 'default_lora': default_lora, 'nova_server': server_address}
nip90params = {
"negative_prompt": {
"required": False,
"values": []
},
"ratio": {
"required": False,
"values": ["1:1", "4:3", "16:9", "3:4", "9:16", "10:16"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I draw images based on a prompt with a Model called unstable diffusion",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return ImageGenerationSDXL(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
if __name__ == '__main__':
env_path = Path('.env')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
dvm = build_example("Unstable Diffusion", "unstable_diffusion", admin_config, os.getenv("NOVA_SERVER"), "stabilityai/stable-diffusion-xl", "")
dvm.run()
keep_alive()

View File

@ -1,12 +1,18 @@
import json
import os
from multiprocessing.pool import ThreadPool
from pathlib import Path
import dotenv
from backends.nova_server import check_nova_server_status, send_request_to_nova_server
from interfaces.dvmtaskinterface import DVMTaskInterface
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.dvmconfig import DVMConfig
from utils.nip89_utils import NIP89Config
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.definitions import EventDefinitions
from utils.nostr_utils import check_and_set_private_key
"""
This File contains a Module to transform Text input on NOVA-Server and receive results back.
@ -69,7 +75,7 @@ class ImageGenerationSDXLIMG2IMG(DVMTaskInterface):
width = ""
height = ""
if self.options.get("default_lora"):
if self.options.get("default_lora") and self.options.get("default_lora") != "":
lora = self.options['default_lora']
else:
lora = ""
@ -184,3 +190,64 @@ class ImageGenerationSDXLIMG2IMG(DVMTaskInterface):
except Exception as e:
raise Exception(e)
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config, server_address, default_lora="", strength=0.6):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
nip90params = {
"negative_prompt": {
"required": False,
"values": []
},
"lora": {
"required": False,
"values": ["inkpunk", "timburton", "voxel"]
},
"strength": {
"required": False,
"values": []
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/229c14e440895da30de77b3ca145d66d4b04efb4027ba3c44ca147eecde891f1.jpg",
"about": "I convert an image to another image, kinda random for now. ",
"nip90Params": nip90params
}
# A module might have options it can be initialized with, here we set a default model, lora and the nova-server
options = {'default_lora': default_lora, 'strength': strength, 'nova_server': server_address}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
return ImageGenerationSDXLIMG2IMG(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
if __name__ == '__main__':
env_path = Path('.env')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
dvm = build_example("Image Converter Inkpunk", "image_converter_inkpunk", admin_config, os.getenv("NOVA_SERVER"), "inkpunk", 0.6)
dvm.run()
keep_alive()

View File

@ -4,13 +4,17 @@ import time
from multiprocessing.pool import ThreadPool
from pathlib import Path
import dotenv
from backends.nova_server import check_nova_server_status, send_request_to_nova_server, send_file_to_nova_server
from interfaces.dvmtaskinterface import DVMTaskInterface
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.dvmconfig import DVMConfig
from utils.mediasource_utils import organize_input_media_data
from utils.nip89_utils import NIP89Config
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.definitions import EventDefinitions
from utils.nostr_utils import check_and_set_private_key
"""
This File contains a Module to transform a media file input on Google Cloud
@ -123,3 +127,52 @@ class SpeechToTextGoogle(DVMTaskInterface):
return "error"
return result
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
options = {'api_key': None}
# A module might have options it can be initialized with, here we set a default model, and the nova-server
# address it should use. These parameters can be freely defined in the task component
nip90params = {
"language": {
"required": False,
"values": ["en-US"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I extract text from media files with the Google API. I understand English by default",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return SpeechToTextGoogle(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
if __name__ == '__main__':
env_path = Path('.env')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
dvm = build_example("Transcriptor", "speech_recognition", admin_config)
dvm.run()
keep_alive()

View File

@ -1,13 +1,17 @@
import json
import os
import re
from pathlib import Path
import dotenv
from interfaces.dvmtaskinterface import DVMTaskInterface
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.definitions import EventDefinitions
from utils.dvmconfig import DVMConfig
from utils.nip89_utils import NIP89Config
from utils.nostr_utils import get_event_by_id
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.nostr_utils import get_event_by_id, check_and_set_private_key
"""
This File contains a Module to extract Text from a PDF file locally on the DVM Machine
@ -84,3 +88,45 @@ class TextExtractionPDF(DVMTaskInterface):
return text
except Exception as e:
raise Exception(e)
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# Add NIP89
nip90params = {}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I extract text from pdf documents",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return TextExtractionPDF(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
if __name__ == '__main__':
env_path = Path('.env')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
dvm = build_example("PDF Extractor", "pdf_extractor", admin_config)
dvm.run()
keep_alive()

View File

@ -4,13 +4,17 @@ import time
from multiprocessing.pool import ThreadPool
from pathlib import Path
import dotenv
from backends.nova_server import check_nova_server_status, send_request_to_nova_server, send_file_to_nova_server
from interfaces.dvmtaskinterface import DVMTaskInterface
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.dvmconfig import DVMConfig
from utils.mediasource_utils import organize_input_media_data
from utils.nip89_utils import NIP89Config
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.definitions import EventDefinitions
from utils.nostr_utils import check_and_set_private_key
"""
This File contains a Module to transform A media file input on NOVA-Server and receive results back.
@ -142,3 +146,58 @@ class SpeechToTextWhisperX(DVMTaskInterface):
except Exception as e:
raise Exception(e)
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config, server_address):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# A module might have options it can be initialized with, here we set a default model, and the nova-server
# address it should use. These parameters can be freely defined in the task component
options = {'default_model': "base", 'nova_server': server_address}
nip90params = {
"model": {
"required": False,
"values": ["base", "tiny", "small", "medium", "large-v1", "large-v2", "tiny.en", "base.en", "small.en",
"medium.en"]
},
"alignment": {
"required": False,
"values": ["raw", "segment", "word"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I extract text from media files with WhisperX",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return SpeechToTextWhisperX(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
if __name__ == '__main__':
env_path = Path('.env')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
dvm = build_example("Whisperer", "whisperx", admin_config, os.getenv("NOVA_SERVER"))
dvm.run()
keep_alive()

View File

@ -1,11 +1,16 @@
import json
import os
from pathlib import Path
import dotenv
from interfaces.dvmtaskinterface import DVMTaskInterface
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.definitions import EventDefinitions
from utils.dvmconfig import DVMConfig
from utils.nip89_utils import NIP89Config
from utils.nostr_utils import get_referenced_event_by_id, get_event_by_id
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.nostr_utils import get_referenced_event_by_id, get_event_by_id, check_and_set_private_key
"""
This File contains a Module to call Google Translate Services locally on the DVM Machine
@ -101,3 +106,54 @@ class TranslationGoogle(DVMTaskInterface):
translated_text = translated_text + translated_text_part
return translated_text
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
nip90params = {
"language": {
"required": False,
"values": ["en", "az", "be", "bg", "bn", "bs", "ca", "ceb", "co", "cs", "cy", "da", "de", "el", "eo", "es",
"et", "eu", "fa", "fi", "fr", "fy", "ga", "gd", "gl", "gu", "ha", "haw", "hi", "hmn", "hr", "ht",
"hu", "hy", "id", "ig", "is", "it", "he", "ja", "jv", "ka", "kk", "km", "kn", "ko", "ku", "ky",
"la", "lb", "lo", "lt", "lv", "mg", "mi", "mk", "ml", "mn", "mr", "ms", "mt", "my", "ne", "nl",
"no", "ny", "or", "pa", "pl", "ps", "pt", "ro", "ru", "sd", "si", "sk", "sl", "sm", "sn", "so",
"sq", "sr", "st", "su", "sv", "sw", "ta", "te", "tg", "th", "tl", "tr", "ug", "uk", "ur", "uz",
"vi", "xh", "yi", "yo", "zh", "zu"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I translate text from given text/event/job. Currently using Google TranslationGoogle Services to translate "
"input into the language defined in params.",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return TranslationGoogle(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=admin_config)
if __name__ == '__main__':
env_path = Path('.env')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
dvm = build_example("Google Translator", "google_translator", admin_config)
dvm.run()
keep_alive()

View File

@ -1,13 +1,17 @@
import json
import os
from pathlib import Path
import dotenv
import requests
from interfaces.dvmtaskinterface import DVMTaskInterface
from utils.admin_utils import AdminConfig
from utils.backend_utils import keep_alive
from utils.definitions import EventDefinitions
from utils.dvmconfig import DVMConfig
from utils.nip89_utils import NIP89Config
from utils.nostr_utils import get_referenced_event_by_id, get_event_by_id
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
from utils.nostr_utils import get_referenced_event_by_id, get_event_by_id, check_and_set_private_key
"""
This File contains a Module to call Google Translate Services locally on the DVM Machine
@ -98,3 +102,59 @@ class TranslationLibre(DVMTaskInterface):
return response.text
return translated_text
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config):
dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
options = {'libre_end_point': os.getenv("LIBRE_TRANSLATE_ENDPOINT"),
'libre_api_key': os.getenv("LIBRE_TRANSLATE_API_KEY")}
nip90params = {
"language": {
"required": False,
"values": ["en", "az", "be", "bg", "bn", "bs", "ca", "ceb", "co", "cs", "cy", "da", "de", "el", "eo", "es",
"et", "eu", "fa", "fi", "fr", "fy", "ga", "gd", "gl", "gu", "ha", "haw", "hi", "hmn", "hr", "ht",
"hu", "hy", "id", "ig", "is", "it", "he", "ja", "jv", "ka", "kk", "km", "kn", "ko", "ku", "ky",
"la", "lb", "lo", "lt", "lv", "mg", "mi", "mk", "ml", "mn", "mr", "ms", "mt", "my", "ne", "nl",
"no", "ny", "or", "pa", "pl", "ps", "pt", "ro", "ru", "sd", "si", "sk", "sl", "sm", "sn", "so",
"sq", "sr", "st", "su", "sv", "sw", "ta", "te", "tg", "th", "tl", "tr", "ug", "uk", "ur", "uz",
"vi", "xh", "yi", "yo", "zh", "zu"]
}
}
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I translate text from given text/event/job using LibreTranslate Services to translate "
"input into the language defined in params.",
"nip90Params": nip90params
}
nip89config = NIP89Config()
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return TranslationLibre(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
if __name__ == '__main__':
env_path = Path('.env')
if env_path.is_file():
print(f'loading environment from {env_path.resolve()}')
dotenv.load_dotenv(env_path, verbose=True, override=True)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
admin_config = AdminConfig()
admin_config.REBROADCAST_NIP89 = False
admin_config.UPDATE_PROFILE = False
admin_config.LUD16 = ""
dvm = build_example("Libre Translator", "libre_translator", admin_config)
dvm.run()
keep_alive()

View File

@ -1,4 +1,6 @@
import typing
import os
import signal
import time
import requests
from nostr_sdk import Event, Tag
@ -184,3 +186,13 @@ def get_amount_per_task(task, dvm_config, duration=1):
print("[" + dvm_config.SUPPORTED_DVMS[
0].NAME + "] Task " + task + " is currently not supported by this instance, skipping")
return None
def keep_alive():
try:
while True:
time.sleep(10)
except KeyboardInterrupt:
os.kill(os.getpid(), signal.SIGKILL)
exit(1)

View File

@ -318,3 +318,20 @@ def redeem_cashu(cashu, required_amount, config, client) -> (bool, str):
print(e)
return False, ""
def get_price_per_sat(currency):
import requests
url = "https://api.coinstats.app/public/v1/coins"
params = {"skip": 0, "limit": 1, "currency": currency}
try:
response = requests.get(url, params=params)
response_json = response.json()
bitcoin_price = response_json["coins"][0]["price"]
price_currency_per_sat = bitcoin_price / 100000000.0
except:
price_currency_per_sat = 0.0004
return price_currency_per_sat