From bd2f48cc2fc384369ce8946e117d03f39e8ea121 Mon Sep 17 00:00:00 2001 From: Believethehype Date: Tue, 28 Nov 2023 20:33:30 +0100 Subject: [PATCH] added info command to bot, added fix_cost and per_unit_cost --- backends/nova_server.py | 6 -- bot.py | 148 ++++++++++++++++---------- dvm.py | 2 +- interfaces/dvmtaskinterface.py | 9 +- playground.py | 2 +- tasks/imagegeneration_openai_dalle.py | 2 +- tasks/imagegeneration_sdxl.py | 2 +- tasks/textextraction_whisperx.py | 3 +- tasks/textextractionpdf.py | 2 +- tasks/translation.py | 2 +- utils/backend_utils.py | 6 +- utils/dvmconfig.py | 3 +- 12 files changed, 107 insertions(+), 80 deletions(-) diff --git a/backends/nova_server.py b/backends/nova_server.py index 62398bb..8c2371a 100644 --- a/backends/nova_server.py +++ b/backends/nova_server.py @@ -107,15 +107,9 @@ def check_nova_server_status(jobID, address) -> str | pd.DataFrame: columns = ['from', 'to', 'name', 'conf'] result = pd.DataFrame([row.split(';') for row in anno_string.split('\n')], columns=columns) - #print(str(result)) return result - #with open("response.zip", "wb") as f: - # f.write(response.content) except Exception as e: - #zf.extractall() print(e) - - except Exception as e: print("Couldn't fetch result: " + str(e)) diff --git a/bot.py b/bot.py index 74c3712..84fa395 100644 --- a/bot.py +++ b/bot.py @@ -84,87 +84,117 @@ class Bot: if decrypted_text[0].isdigit(): index = int(decrypted_text.split(' ')[0]) - 1 task = self.dvm_config.SUPPORTED_DVMS[index].TASK - print("[" + self.NAME + "] Request from " + str(user.name) + " (" + str(user.nip05) + ", Balance: " - + str(user.balance) + " Sats) Task: " + str(task)) - if user.isblacklisted: - # For some reason an admin might blacklist npubs, e.g. for abusing the service - evt = EventBuilder.new_encrypted_direct_msg(self.keys, nostr_event.pubkey(), - "Your are currently blocked from all " - "services.", None).to_event(self.keys) - send_event(evt, client=self.client, dvm_config=dvm_config) + if decrypted_text.split(" ")[1].lower() == "info": + nip89 = self.dvm_config.SUPPORTED_DVMS[index].dvm_config.NIP89 + nip89content = json.loads(nip89.content) + info = "" + if nip89content.get("name"): + info += "Name: " + nip89content.get("name") + "\n" + info += nip89content.get("image")+ "\n" + info += "About:\n" + nip89content.get("about") + "\n" + params = nip89content["nip90Params"] + print(params) + info += "\nParameters:\n" + for param in params: + info += "-" + param + '\n' + info += "Required: " + str(params[param]['required']) + '\n' + info += "Possible Values: " + json.dumps(params[param]['values']) + '\n\n' + evt = EventBuilder.new_encrypted_direct_msg(self.keys, nostr_event.pubkey(), + info, None).to_event(self.keys) + send_event(evt, client=self.client, dvm_config=dvm_config) + + print(nip89content) else: - command = decrypted_text.replace(decrypted_text.split(' ')[0] + " ", "") - input = command.split(" -")[0].rstrip() - input_type = "text" - if input.startswith("http"): - input_type = "url" + print("[" + self.NAME + "] Request from " + str(user.name) + " (" + str(user.nip05) + ", Balance: " + + str(user.balance) + " Sats) Task: " + str(task)) - i_tag = Tag.parse(["i", input, input_type]) - #bid = str(self.dvm_config.SUPPORTED_DVMS[index].COST * 1000) - #bid_tag = Tag.parse(['bid', bid, bid]) - relays_tag = Tag.parse(["relays", json.dumps(self.dvm_config.RELAY_LIST)]) - alt_tag = Tag.parse(["alt", self.dvm_config.SUPPORTED_DVMS[index].TASK]) + if user.isblacklisted: + # For some reason an admin might blacklist npubs, e.g. for abusing the service + evt = EventBuilder.new_encrypted_direct_msg(self.keys, nostr_event.pubkey(), + "Your are currently blocked from all " + "services.", None).to_event(self.keys) + send_event(evt, client=self.client, dvm_config=dvm_config) - tags = [i_tag.as_vec(), relays_tag.as_vec(), alt_tag.as_vec()] + else: + command = decrypted_text.replace(decrypted_text.split(' ')[0] + " ", "") + input = command.split(" -")[0].rstrip() + input_type = "text" + if input.startswith("http"): + input_type = "url" - remaining_text = command.replace(input, "") - print(remaining_text) - params = remaining_text.rstrip().split(" -") + i_tag = Tag.parse(["i", input, input_type]) + #bid = str(self.dvm_config.SUPPORTED_DVMS[index].FIX_COST * 1000) + #bid_tag = Tag.parse(['bid', bid, bid]) + relays_tag = Tag.parse(["relays", json.dumps(self.dvm_config.RELAY_LIST)]) + alt_tag = Tag.parse(["alt", self.dvm_config.SUPPORTED_DVMS[index].TASK]) - for i in params: - print(i) - if i != " ": - try: - split = i.split(" ") - param = str(split[0]) - print(str(param)) - value = str(split[1]) - print(str(value)) - if param == "cashu": - tag = Tag.parse([param, value]) - else: - tag = Tag.parse(["param", param, value]) - tags.append(tag.as_vec()) - print("Added params: " + str(tag.as_vec())) - except Exception as e: - print(e) - print("Couldn't add " + str(i)) + tags = [i_tag.as_vec(), relays_tag.as_vec(), alt_tag.as_vec()] - encrypted_params_string = json.dumps(tags) + remaining_text = command.replace(input, "") + print(remaining_text) + params = remaining_text.rstrip().split(" -") - print(encrypted_params_string) + for i in params: + print(i) + if i != " ": + try: + split = i.split(" ") + param = str(split[0]) + print(str(param)) + value = str(split[1]) + print(str(value)) + if param == "cashu": + tag = Tag.parse([param, value]) + else: + tag = Tag.parse(["param", param, value]) + tags.append(tag.as_vec()) + print("Added params: " + str(tag.as_vec())) + except Exception as e: + print(e) + print("Couldn't add " + str(i)) - encrypted_params = nip04_encrypt(self.keys.secret_key(), - PublicKey.from_hex( - self.dvm_config.SUPPORTED_DVMS[index].PUBLIC_KEY), - encrypted_params_string) + encrypted_params_string = json.dumps(tags) - encrypted_tag = Tag.parse(['encrypted']) - p_tag = Tag.parse(['p', self.dvm_config.SUPPORTED_DVMS[index].PUBLIC_KEY]) - encrypted_nip90request = (EventBuilder(self.dvm_config.SUPPORTED_DVMS[index].KIND, - encrypted_params, [p_tag, encrypted_tag]). - to_event(self.keys)) + print(encrypted_params_string) - entry = {"npub": user.npub, "event_id": encrypted_nip90request.id().to_hex(), - "dvm_key": self.dvm_config.SUPPORTED_DVMS[index].PUBLIC_KEY, "is_paid": False} - self.job_list.append(entry) + encrypted_params = nip04_encrypt(self.keys.secret_key(), + PublicKey.from_hex( + self.dvm_config.SUPPORTED_DVMS[index].PUBLIC_KEY), + encrypted_params_string) - send_event(encrypted_nip90request, client=self.client, dvm_config=dvm_config) + encrypted_tag = Tag.parse(['encrypted']) + p_tag = Tag.parse(['p', self.dvm_config.SUPPORTED_DVMS[index].PUBLIC_KEY]) + encrypted_nip90request = (EventBuilder(self.dvm_config.SUPPORTED_DVMS[index].KIND, + encrypted_params, [p_tag, encrypted_tag]). + to_event(self.keys)) + + entry = {"npub": user.npub, "event_id": encrypted_nip90request.id().to_hex(), + "dvm_key": self.dvm_config.SUPPORTED_DVMS[index].PUBLIC_KEY, "is_paid": False} + self.job_list.append(entry) + + send_event(encrypted_nip90request, client=self.client, dvm_config=dvm_config) else: print("[" + self.NAME + "] Message from " + user.name + ": " + decrypted_text) message = "DVMs that I support:\n\n" index = 1 for p in self.dvm_config.SUPPORTED_DVMS: - message += str(index) + " " + p.NAME + " " + p.TASK + " " + str(p.COST) + " Sats" + "\n" + if p.PER_UNIT_COST != 0 and p.PER_UNIT_COST is not None: + message += (str(index) + " " + p.NAME + " " + p.TASK + " " + str(p.FIX_COST) + + " Sats + " + str(p.PER_UNIT_COST) + " Sats per Second\n") + else: + message += (str(index) + " " + p.NAME + " " + p.TASK + " " + str(p.FIX_COST) + + " Sats\n") index += 1 - time.sleep(1.0) + time.sleep(3.0) evt = EventBuilder.new_encrypted_direct_msg(self.keys, nostr_event.pubkey(), message + "\nSelect an Index and provide an input (" - "e.g. 1 A purple ostrich)", + "e.g. 2 A purple ostrich)\nType index info to learn more about each DVM. (e.g. 2 info)\n\n" + "" + "Add -cashu cashutoken with the amount + mint fees (at least 3 sat) to pay via #cashu", nostr_event.id()).to_event(self.keys) send_event(evt, client=self.client, dvm_config=dvm_config) @@ -259,7 +289,7 @@ class Bot: else: print("Bot payment-required") evt = EventBuilder.new_encrypted_direct_msg(self.keys, PublicKey.from_hex(entry["npub"]), - "Current balance: " + str(user.balance) + " Sats. Balance required, please zap me with at least " + + "Current balance: " + str(user.balance) + " Sats. Balance of "+ str(amount) +" Sats required. Please zap me with at least " + str(int(amount - user.balance)) + " Sats, then try again.", None).to_event(self.keys) diff --git a/dvm.py b/dvm.py index be02a2f..fc9f6af 100644 --- a/dvm.py +++ b/dvm.py @@ -110,7 +110,7 @@ class DVM: task_is_free = False for dvm in self.dvm_config.SUPPORTED_DVMS: - if dvm.TASK == task and dvm.COST == 0: + if dvm.TASK == task and dvm.FIX_COST == 0 and dvm.PER_UNIT_COST == 0: task_is_free = True cashu_redeemed = False diff --git a/interfaces/dvmtaskinterface.py b/interfaces/dvmtaskinterface.py index a75c0f0..3e1b48d 100644 --- a/interfaces/dvmtaskinterface.py +++ b/interfaces/dvmtaskinterface.py @@ -13,7 +13,8 @@ class DVMTaskInterface: NAME: str KIND: int TASK: str - COST: float + FIX_COST: float = 0 + PER_UNIT_COST: float = 0 PRIVATE_KEY: str PUBLIC_KEY: str DVM = DVM @@ -31,8 +32,10 @@ class DVMTaskInterface: if dvm_config.PUBLIC_KEY == "" or dvm_config.PUBLIC_KEY is None: dvm_config.PUBLIC_KEY = Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_hex() self.PUBLIC_KEY = dvm_config.PUBLIC_KEY - if dvm_config.COST is not None: - self.COST = dvm_config.COST + if dvm_config.FIX_COST is not None: + self.FIX_COST = dvm_config.FIX_COST + if dvm_config.PER_UNIT_COST is not None: + self.PER_UNIT_COST = dvm_config.PER_UNIT_COST dvm_config.SUPPORTED_DVMS = [self] dvm_config.DB = "db/" + self.NAME + ".db" diff --git a/playground.py b/playground.py index ac87cbe..020e561 100644 --- a/playground.py +++ b/playground.py @@ -200,7 +200,7 @@ def build_dalle(name): dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY") dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST") profit_in_sats = 10 - dvm_config.COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats)) + dvm_config.FIX_COST = int(((4.0 / (get_price_per_sat("USD") * 100)) + profit_in_sats)) nip90params = { "size": { diff --git a/tasks/imagegeneration_openai_dalle.py b/tasks/imagegeneration_openai_dalle.py index 91e1459..99444e5 100644 --- a/tasks/imagegeneration_openai_dalle.py +++ b/tasks/imagegeneration_openai_dalle.py @@ -25,7 +25,7 @@ Params: -model # models: juggernaut, dynavision, colossusProject, newrea class ImageGenerationDALLE(DVMTaskInterface): KIND: int = EventDefinitions.KIND_NIP90_GENERATE_IMAGE TASK: str = "text-to-image" - COST: float = 120 + FIX_COST: float = 120 def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, admin_config: AdminConfig = None, options=None): diff --git a/tasks/imagegeneration_sdxl.py b/tasks/imagegeneration_sdxl.py index 82cdd20..a2fc6ec 100644 --- a/tasks/imagegeneration_sdxl.py +++ b/tasks/imagegeneration_sdxl.py @@ -21,7 +21,7 @@ Params: -model # models: juggernaut, dynavision, colossusProject, newrea class ImageGenerationSDXL(DVMTaskInterface): KIND: int = EventDefinitions.KIND_NIP90_GENERATE_IMAGE TASK: str = "text-to-image" - COST: float = 50 + FIX_COST: float = 50 def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, admin_config: AdminConfig = None, options=None): diff --git a/tasks/textextraction_whisperx.py b/tasks/textextraction_whisperx.py index cdc135b..adfe096 100644 --- a/tasks/textextraction_whisperx.py +++ b/tasks/textextraction_whisperx.py @@ -25,7 +25,8 @@ Params: -model # models: juggernaut, dynavision, colossusProject, newrea class SpeechToTextWhisperX(DVMTaskInterface): KIND: int = EventDefinitions.KIND_NIP90_EXTRACT_TEXT TASK: str = "speech-to-text" - COST: float = 0.1 + FIX_COST: float = 10 + PER_UNIT_COST: float = 0.1 def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, admin_config: AdminConfig = None, options=None): diff --git a/tasks/textextractionpdf.py b/tasks/textextractionpdf.py index a69a9e3..4a38d04 100644 --- a/tasks/textextractionpdf.py +++ b/tasks/textextractionpdf.py @@ -23,7 +23,7 @@ Params: None class TextExtractionPDF(DVMTaskInterface): KIND: int = EventDefinitions.KIND_NIP90_EXTRACT_TEXT TASK: str = "pdf-to-text" - COST: float = 0 + FIX_COST: float = 0 def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, admin_config: AdminConfig = None, options=None): diff --git a/tasks/translation.py b/tasks/translation.py index 3c0a8e4..5e3b005 100644 --- a/tasks/translation.py +++ b/tasks/translation.py @@ -21,7 +21,7 @@ Params: -language The target language class Translation(DVMTaskInterface): KIND: int = EventDefinitions.KIND_NIP90_TRANSLATE_TEXT TASK: str = "translation" - COST: float = 0 + FIX_COST: float = 0 def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, admin_config: AdminConfig = None, options=None): diff --git a/utils/backend_utils.py b/utils/backend_utils.py index bad8f3a..0ad2a4e 100644 --- a/utils/backend_utils.py +++ b/utils/backend_utils.py @@ -144,12 +144,10 @@ def check_url_is_readable(url): def get_amount_per_task(task, dvm_config, duration=1): - # duration is either static 1 (for images etc) or in seconds - if duration == 0: - duration = 1 + # duration is either static 1 (for images etc) or in seconds by default (e.g. audio/video) for dvm in dvm_config.SUPPORTED_DVMS: # this is currently just one if dvm.TASK == task: - amount = dvm.COST * duration + amount = dvm.FIX_COST + (dvm.PER_UNIT_COST * duration) return amount else: print("[" + dvm_config.SUPPORTED_DVMS[ diff --git a/utils/dvmconfig.py b/utils/dvmconfig.py index fda96c0..a6c1e38 100644 --- a/utils/dvmconfig.py +++ b/utils/dvmconfig.py @@ -9,7 +9,8 @@ class DVMConfig: SUPPORTED_DVMS= [] PRIVATE_KEY: str = "" PUBLIC_KEY: str = "" - COST: int = None + FIX_COST: float = None + PER_UNIT_COST: float = None RELAY_LIST = ["wss://relay.damus.io", "wss://nostr-pub.wellorder.net", "wss://nos.lol", "wss://nostr.wine", "wss://relay.nostfiles.dev", "wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg",