some fixes, updated readme

This commit is contained in:
Believethehype
2023-11-20 23:18:05 +01:00
parent 13bffaea96
commit 2e1920a940
6 changed files with 249 additions and 241 deletions

View File

@@ -10,3 +10,11 @@ Place .env file (based on .env_example) in main folder, install requirements.txt
Use vendata.io to create a nip89 announcement of your dvm and save the dtag in your .env config. Use vendata.io to create a nip89 announcement of your dvm and save the dtag in your .env config.
A tutorial on how to add additional tasks, as well as the larger server backend will be added soon. A tutorial on how to add additional tasks, as well as the larger server backend will be added soon.
Known Issues:
- After refactoring DVMs work independent from each other for the most part.
- They currently still share a joblist and might act weird together (TODO rework joblist)
- Some functions might work easier than they did before (need some refactoring)
- Bot currently not implemented
- Some basic functionality is still missing, e.g. handling various mediasources
- Interface might still change a lot and brick things.

24
dvm.py
View File

@@ -60,14 +60,14 @@ class DVM:
def handle(self, relay_url, nostr_event): def handle(self, relay_url, nostr_event):
print(f"[Nostr] Received new NIP90 Job Request from {relay_url}: {nostr_event.as_json()}") print(f"[Nostr] Received new NIP90 Job Request from {relay_url}: {nostr_event.as_json()}")
if EventDefinitions.KIND_NIP90_EXTRACT_TEXT <= nostr_event.kind() <= EventDefinitions.KIND_NIP90_GENERIC: if EventDefinitions.KIND_NIP90_EXTRACT_TEXT <= nostr_event.kind() <= EventDefinitions.KIND_NIP90_GENERIC:
self.handle_nip90_job_event(nostr_event) handle_nip90_job_event(nostr_event)
elif nostr_event.kind() == EventDefinitions.KIND_ZAP: elif nostr_event.kind() == EventDefinitions.KIND_ZAP:
self.handle_zap(nostr_event) handle_zap(nostr_event)
def handle_msg(self, relay_url, msg): def handle_msg(self, relay_url, msg):
return return
def handle_nip90_job_event(self, nip90_event): def handle_nip90_job_event(nip90_event):
user = get_or_add_user(nip90_event.pubkey().to_hex()) user = get_or_add_user(nip90_event.pubkey().to_hex())
task_supported, task, duration = check_task_is_supported(nip90_event, client=self.client, task_supported, task, duration = check_task_is_supported(nip90_event, client=self.client,
get_duration=(not user.iswhitelisted), get_duration=(not user.iswhitelisted),
@@ -116,11 +116,12 @@ class DVM:
else: else:
print("Task not supported on this DVM, skipping..") print("Task not supported on this DVM, skipping..")
def handle_zap(self, event): def handle_zap(event):
zapped_event = None zapped_event = None
invoice_amount = 0 invoice_amount = 0
anon = False anon = False
sender = event.pubkey() sender = event.pubkey()
print("Zap received")
try: try:
for tag in event.tags(): for tag in event.tags():
@@ -153,7 +154,6 @@ class DVM:
if zapped_event is not None: if zapped_event is not None:
if zapped_event.kind() == EventDefinitions.KIND_FEEDBACK: # if a reaction by us got zapped if zapped_event.kind() == EventDefinitions.KIND_FEEDBACK: # if a reaction by us got zapped
if not self.dvm_config.IS_BOT:
print("Zap received for NIP90 task: " + str(invoice_amount) + " Sats from " + str( print("Zap received for NIP90 task: " + str(invoice_amount) + " Sats from " + str(
user.name)) user.name))
amount = 0 amount = 0
@@ -200,13 +200,13 @@ class DVM:
elif zapped_event.kind() in EventDefinitions.ANY_RESULT: elif zapped_event.kind() in EventDefinitions.ANY_RESULT:
print("Someone zapped the result of an exisiting Task. Nice") print("Someone zapped the result of an exisiting Task. Nice")
elif not anon and not self.dvm_config.PASSIVE_MODE: elif not anon:
print("Note Zap received for Bot balance: " + str(invoice_amount) + " Sats from " + str( print("Note Zap received for Bot balance: " + str(invoice_amount) + " Sats from " + str(
user.name)) user.name))
update_user_balance(sender, invoice_amount, config=self.dvm_config) update_user_balance(sender, invoice_amount, config=self.dvm_config)
# a regular note # a regular note
elif not anon and not self.dvm_config.PASSIVE_MODE: elif not anon:
print("Profile Zap received for Bot balance: " + str(invoice_amount) + " Sats from " + str( print("Profile Zap received for Bot balance: " + str(invoice_amount) + " Sats from " + str(
user.name)) user.name))
update_user_balance(sender, invoice_amount, config=self.dvm_config) update_user_balance(sender, invoice_amount, config=self.dvm_config)
@@ -214,8 +214,6 @@ class DVM:
except Exception as e: except Exception as e:
print(f"Error during content decryption: {e}") print(f"Error during content decryption: {e}")
def check_event_has_not_unfinished_job_input(nevent, append, client, dvmconfig): def check_event_has_not_unfinished_job_input(nevent, append, client, dvmconfig):
task_supported, task, duration = check_task_is_supported(nevent, client, False, config=dvmconfig) task_supported, task, duration = check_task_is_supported(nevent, client, False, config=dvmconfig)
if not task_supported: if not task_supported:
@@ -243,8 +241,6 @@ class DVM:
else: else:
return True return True
def check_and_return_event(data, original_event_str: str, dvm_key=""): def check_and_return_event(data, original_event_str: str, dvm_key=""):
original_event = Event.from_json(original_event_str) original_event = Event.from_json(original_event_str)
keys = Keys.from_sk_str(dvm_key) keys = Keys.from_sk_str(dvm_key)
@@ -428,6 +424,7 @@ class DVM:
"[Nostr] Sent Kind " + str( "[Nostr] Sent Kind " + str(
EventDefinitions.KIND_FEEDBACK) + " Reaction: " + status + " " + event.as_json()) EventDefinitions.KIND_FEEDBACK) + " Reaction: " + status + " " + event.as_json())
return event.as_json() return event.as_json()
def do_work(job_event, is_from_bot=False): def do_work(job_event, is_from_bot=False):
if (( if ((
EventDefinitions.KIND_NIP90_EXTRACT_TEXT <= job_event.kind() <= EventDefinitions.KIND_NIP90_GENERIC) EventDefinitions.KIND_NIP90_EXTRACT_TEXT <= job_event.kind() <= EventDefinitions.KIND_NIP90_GENERIC)
@@ -478,14 +475,13 @@ class DVM:
for job in jobs_on_hold_list: for job in jobs_on_hold_list:
if check_event_has_not_unfinished_job_input(job.event, False, client=self.client, if check_event_has_not_unfinished_job_input(job.event, False, client=self.client,
dvmconfig=self.dvm_config): dvmconfig=self.dvm_config):
# handle_nip90_job_event(event=job.event) handle_nip90_job_event(nip90_event=job.event)
try: try:
jobs_on_hold_list.remove(job) jobs_on_hold_list.remove(job)
except: except:
continue continue
if Timestamp.now().as_secs() > job.timestamp + 60 * 20: # remove jobs to look for after 20 minutes.. if Timestamp.now().as_secs() > job.timestamp + 60 * 20: # remove jobs to look for after 20 minutes..
jobs_on_hold_list.remove(job) jobs_on_hold_list.remove(job)
time.sleep(1.0) time.sleep(2.0)

16
main.py
View File

@@ -67,20 +67,18 @@ def run_nostr_dvm_with_local_config():
dvm_config.LNBITS_INVOICE_KEY = os.getenv(env.LNBITS_INVOICE_KEY) dvm_config.LNBITS_INVOICE_KEY = os.getenv(env.LNBITS_INVOICE_KEY)
dvm_config.LNBITS_URL = os.getenv(env.LNBITS_HOST) dvm_config.LNBITS_URL = os.getenv(env.LNBITS_HOST)
unstableartist = ImageGenerationSDXL("Unstable Diffusion", dvm_config, "unstable") #unstableartist = ImageGenerationSDXL("Unstable Diffusion", dvm_config, "unstable")
d_tag = os.getenv(env.TASK_IMAGEGENERATION_NIP89_DTAG) #d_tag = os.getenv(env.TASK_IMAGEGENERATION_NIP89_DTAG)
content = "{\"name\":\"" + unstableartist.NAME + ("\",\"image\":\"https://image.nostr.build" #content = "{\"name\":\"" + unstableartist.NAME + ("\",\"image\":\"https://image.nostr.build"
"/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg" # "/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg"
"\",\"about\":\"I draw images based on a prompt with a Model called unstable diffusion.\",\"nip90Params\":{}}") # "\",\"about\":\"I draw images based on a prompt with a Model called unstable diffusion.\",\"nip90Params\":{}}")
dvm_config.NIP89s.append(unstableartist.NIP89_announcement(d_tag, content)) #dvm_config.NIP89s.append(unstableartist.NIP89_announcement(d_tag, content))
# Spawn another Instance of text-to-image but use a different model and lora this time.
dvm_config = DVMConfig() dvm_config = DVMConfig()
dvm_config.PRIVATE_KEY = "73b262d31edc6ea1316dffcc7daa772651d661e6475761b7b78291482c1bf5cb" dvm_config.PRIVATE_KEY = "73b262d31edc6ea1316dffcc7daa772651d661e6475761b7b78291482c1bf5cb"
dvm_config.LNBITS_INVOICE_KEY = os.getenv(env.LNBITS_INVOICE_KEY) dvm_config.LNBITS_INVOICE_KEY = os.getenv(env.LNBITS_INVOICE_KEY)
dvm_config.LNBITS_URL = os.getenv(env.LNBITS_HOST) dvm_config.LNBITS_URL = os.getenv(env.LNBITS_HOST)
# Spawn another Instance of text-to-image but use a different model and lora this time.
sketcher = ImageGenerationSDXL("Sketcher", dvm_config, "mohawk", "timburton") sketcher = ImageGenerationSDXL("Sketcher", dvm_config, "mohawk", "timburton")
d_tag = os.getenv(env.TASK_IMAGEGENERATION_NIP89_DTAG2) d_tag = os.getenv(env.TASK_IMAGEGENERATION_NIP89_DTAG2)
content = "{\"name\":\"" + sketcher.NAME + ("\",\"image\":\"https://image.nostr.build" content = "{\"name\":\"" + sketcher.NAME + ("\",\"image\":\"https://image.nostr.build"

View File

@@ -21,7 +21,7 @@ class ImageGenerationSDXL(DVMTaskInterface):
NAME: str NAME: str
KIND: int = EventDefinitions.KIND_NIP90_GENERATE_IMAGE KIND: int = EventDefinitions.KIND_NIP90_GENERATE_IMAGE
TASK: str = "text-to-image" TASK: str = "text-to-image"
COST: int = 50 COST: int = 5
PK: str PK: str
def __init__(self, name, dvm_config, default_model=None, default_lora=None): def __init__(self, name, dvm_config, default_model=None, default_lora=None):

View File

@@ -10,6 +10,8 @@ import pandas
''' '''
Post process results to either given output format or a Nostr readable plain text. Post process results to either given output format or a Nostr readable plain text.
''' '''
def post_process_result(anno, original_event): def post_process_result(anno, original_event):
print("post-processing...") print("post-processing...")
if isinstance(anno, pandas.DataFrame): # if input is an anno we parse it to required output format if isinstance(anno, pandas.DataFrame): # if input is an anno we parse it to required output format
@@ -85,13 +87,15 @@ def post_process_result(anno, original_event):
elif isinstance(anno, NoneType): elif isinstance(anno, NoneType):
return "An error occurred" return "An error occurred"
else: else:
result = replace_broken_words(anno) #TODO result = replace_broken_words(anno) # TODO
return result return result
''' '''
Convenience function to replace words like Noster with Nostr Convenience function to replace words like Noster with Nostr
''' '''
def replace_broken_words(text): def replace_broken_words(text):
result = (text.replace("Noster", "Nostr").replace("Nostra", "Nostr").replace("no stir", "Nostr"). result = (text.replace("Noster", "Nostr").replace("Nostra", "Nostr").replace("no stir", "Nostr").
replace("Nostro", "Nostr").replace("Impub", "npub").replace("sets", "Sats")) replace("Nostro", "Nostr").replace("Impub", "npub").replace("sets", "Sats"))
@@ -103,12 +107,14 @@ Function to upload to Nostr.build and if it fails to Nostrfiles.dev
Larger files than these hosters allow and fallback is catbox currently. Larger files than these hosters allow and fallback is catbox currently.
Will probably need to switch to another system in the future. Will probably need to switch to another system in the future.
''' '''
def uploadMediaToHoster(filepath): def uploadMediaToHoster(filepath):
print("Uploading image: " + filepath) print("Uploading image: " + filepath)
try: try:
files = {'file': open(filepath, 'rb')} files = {'file': open(filepath, 'rb')}
file_stats = os.stat(filepath) file_stats = os.stat(filepath)
sizeinmb = file_stats.st_size / (1024*1024) sizeinmb = file_stats.st_size / (1024 * 1024)
print("Filesize of Uploaded media: " + str(sizeinmb) + " Mb.") print("Filesize of Uploaded media: " + str(sizeinmb) + " Mb.")
if sizeinmb > 25: if sizeinmb > 25:
uploader = CatboxUploader(filepath) uploader = CatboxUploader(filepath)

View File

@@ -43,7 +43,7 @@ def create_bolt11_ln_bits(sats, config):
obj = json.loads(res.text) obj = json.loads(res.text)
return obj["payment_request"], obj["payment_hash"] return obj["payment_request"], obj["payment_hash"]
except Exception as e: except Exception as e:
print(e) print("LNBITS: " + str(e))
return None return None