added summarization

This commit is contained in:
Believethehype 2024-01-03 20:17:25 +01:00
parent 7972a35ffd
commit 1a8a4d1e5e
4 changed files with 136 additions and 3 deletions

View File

@ -347,7 +347,7 @@ class DVM:
def send_nostr_reply_event(content, original_event_as_str):
original_event = Event.from_json(original_event_as_str)
request_tag = Tag.parse(["request", original_event_as_str.replace("\\", "")])
request_tag = Tag.parse(["request", original_event_as_str])
e_tag = Tag.parse(["e", original_event.id().to_hex()])
p_tag = Tag.parse(["p", original_event.pubkey().to_hex()])
alt_tag = Tag.parse(["alt", "This is the result of a NIP90 DVM AI task with kind " + str(
@ -368,6 +368,7 @@ class DVM:
reply_tags.append(i_tag)
if encrypted:
print(content)
content = nip04_encrypt(self.keys.secret_key(), PublicKey.from_hex(original_event.pubkey().to_hex()),
content)

View File

@ -12,9 +12,11 @@ Current List of Tasks:
| SpeechToTextGoogle | 5000 | Extracts Speech from Media files via Google Services | googleAPI |
| SpeechToTextWhisperX | 5000 | Extracts Speech from Media files via local WhisperX | nserver |
| ImageInterrogator | 5000 | Extracts Prompts from Images | nserver |
| TextSummarizationHuggingChat | 5001 | Summarizes given Input | huggingface |
| TranslationGoogle | 5002 | Translates Inputs to another language | googleAPI |
| TranslationLibre | 5002 | Translates Inputs to another language | libreAPI |
| TextGenerationLLMLite | 5050 | Chat with LLM backends like Ollama, ChatGPT etc | local/api/openai |
| TextGenerationHuggingChat | 5050 | Chat with LLM backend on Huggingface | huggingface |
| ImageGenerationSDXL | 5100 | Generates an Image from Prompt with Stable Diffusion XL | nserver |
| ImageGenerationSDXLIMG2IMG | 5100 | Generates an Image from an Image with Stable Diffusion XL | nserver |
| ImageGenerationReplicateSDXL | 5100 | Generates an Image from Prompt with Stable Diffusion XL | replicate |
@ -26,7 +28,7 @@ Current List of Tasks:
| TextToSpeech | 5250 | Generate Audio from a prompt | local |
| TrendingNotesNostrBand | 5300 | Show trending notes on nostr.band | nostr.band api |
| DiscoverInactiveFollows | 5301 | Find inactive Nostr users | local |
| AdvancedSearch | 5302 (inoff) | Search Content on nostr.band | local |
| AdvancedSearch | 5302 (inoff) | Search Content on nostr.band | local/nostr.band |
Kinds with (inoff) are suggestions and not merged yet and might change in the future.
Backends might require to add an API key to the .env file or run an external server/framework the dvm will communicate with.

View File

@ -0,0 +1,130 @@
import json
import os
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.definitions import EventDefinitions
from nostr_dvm.utils.dvmconfig import DVMConfig, build_default_config
from nostr_dvm.utils.nip89_utils import NIP89Config, check_and_set_d_tag
from nostr_dvm.utils.nostr_utils import get_referenced_event_by_id, get_event_by_id
from nostr_sdk import Tag
"""
This File contains a Module to generate Text, based on a prompt using a LLM (local or API) (Ollama, custom model, chatgpt)
Accepted Inputs: Prompt (text)
Outputs: Generated text
"""
class TextSummarizationHuggingChat(DVMTaskInterface):
KIND: int = EventDefinitions.KIND_NIP90_SUMMARIZE_TEXT
TASK: str = "summarization"
FIX_COST: float = 0
dependencies = [("nostr-dvm", "nostr-dvm"),
("hugchat", "hugchat")]
def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config,
admin_config: AdminConfig = None, options=None):
dvm_config.SCRIPT = os.path.abspath(__file__)
super().__init__(name, dvm_config, nip89config, admin_config, options)
def is_input_supported(self, tags, client=None, dvm_config=None):
for tag in tags:
if tag.as_vec()[0] == 'i':
input_value = tag.as_vec()[1]
input_type = tag.as_vec()[2]
if input_type != "text":
return False
return True
def create_request_from_nostr_event(self, event, client=None, dvm_config=None):
request_form = {"jobID": event.id().to_hex() + "_" + self.NAME.replace(" ", "")}
prompt = ""
for tag in event.tags():
if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2]
if input_type == "text":
prompt = tag.as_vec()[1]
elif input_type == "event":
evt = get_event_by_id(tag.as_vec()[1], client=client, config=dvm_config)
prompt = evt.content()
elif input_type == "job":
evt = get_referenced_event_by_id(event_id=tag.as_vec()[1], client=client,
kinds=[EventDefinitions.KIND_NIP90_RESULT_EXTRACT_TEXT,
EventDefinitions.KIND_NIP90_RESULT_SUMMARIZE_TEXT,
EventDefinitions.KIND_NIP90_RESULT_TRANSLATE_TEXT,
EventDefinitions.KIND_NIP90_RESULT_CONTENT_DISCOVERY],
dvm_config=dvm_config)
if evt.kind() == EventDefinitions.KIND_NIP90_RESULT_CONTENT_DISCOVERY:
result_list = json.loads(evt.content())
prompt = ""
for tag in result_list:
e_tag = Tag.parse(tag)
evt = get_event_by_id(e_tag.as_vec()[1], client=client, config=dvm_config)
prompt += evt.content() + "\n"
else:
prompt = evt.content()
options = {
"prompt": prompt,
}
request_form['options'] = json.dumps(options)
return request_form
def process(self, request_form):
from hugchat import hugchat
from hugchat.login import Login
sign = Login(os.getenv("HUGGINGFACE_EMAIL"), os.getenv("HUGGINGFACE_PASSWORD"))
cookie_path_dir = "./cookies_snapshot"
try:
cookies = sign.loadCookiesFromDir(
cookie_path_dir) # This will detect if the JSON file exists, return cookies if it does and raise an Exception if it's not.
except:
cookies = sign.login()
sign.saveCookiesToDir(cookie_path_dir)
options = DVMTaskInterface.set_options(request_form)
try:
chatbot = hugchat.ChatBot(cookies=cookies.get_dict()) # or cookie_path="usercookies/<email>.json"
query_result = chatbot.query("Summarize the following text in maximum 5 sentences: " + options["prompt"])
print(query_result["text"]) # or query_result.text or query_result["text"]
return str(query_result["text"]).lstrip()
except Exception as e:
print("Error in Module: " + str(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 = build_default_config(identifier)
admin_config.LUD16 = dvm_config.LN_ADDRESS
nip89info = {
"name": name,
"image": "https://image.nostr.build/c33ca6fc4cc038ca4adb46fdfdfda34951656f87ee364ef59095bae1495ce669.jpg",
"about": "I use a LLM connected via Huggingchat",
"encryptionSupported": True,
"cashuAccepted": True,
"nip90Params": {}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return TextSummarizationHuggingChat(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config)
if __name__ == '__main__':
process_venv(TextSummarizationHuggingChat)

View File

@ -51,7 +51,7 @@ def nostr_client_test_image(prompt):
bidTag = Tag.parse(['bid', str(1000 * 1000), str(1000 * 1000)])
relaysTag = Tag.parse(['relays', "wss://relay.damus.io", "wss://blastr.f7z.xyz", "wss://relayable.org",
"wss://nostr-pub.wellorder.net"])
alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to translate a given Input"])
alttag = Tag.parse(["alt", "This is a NIP90 DVM AI task to generate an Image from a given Input"])
event = EventBuilder(EventDefinitions.KIND_NIP90_GENERATE_IMAGE, str("Generate an Image."),
[iTag, outTag, tTag, paramTag1, bidTag, relaysTag, alttag]).to_event(keys)