From 7e463052778d0122f1a279644e0b67d9d29848b1 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Fri, 6 Sep 2024 09:30:07 -0700 Subject: [PATCH 1/8] responseDelay --- mesh_bot.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mesh_bot.py b/mesh_bot.py index aad1a71..78b8011 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -8,6 +8,8 @@ from pubsub import pub # pip install pubsub from modules.log import * from modules.system import * +responseDelay = 0.7 # delay in seconds for response to avoid message collision + def auto_response(message, snr, rssi, hop, message_from_id, channel_number, deviceID): #Auto response to messages message_lower = message.lower() @@ -57,8 +59,8 @@ def auto_response(message, snr, rssi, hop, message_from_id, channel_number, devi # run the first command after sorting bot_response = command_handler[cmds[0]['cmd']]() - # wait a 700ms to avoid message collision from lora-ack - time.sleep(0.7) + # wait a responseDelay to avoid message collision from lora-ack + time.sleep(responseDelay) return bot_response @@ -342,8 +344,8 @@ def onReceive(packet, interface): msg = bbs_check_dm(message_from_id) if msg: - # wait a 700ms to avoid message collision from lora-ack. - time.sleep(0.7) + # wait a responseDelay to avoid message collision from lora-ack. + time.sleep(responseDelay) logger.info(f"System: BBS DM Found: {msg[1]} For: {get_name_from_number(message_from_id, 'long', rxNode)}") message = "Mail: " + msg[1] + " From: " + get_name_from_number(msg[2], 'long', rxNode) bbs_delete_dm(msg[0], msg[1]) @@ -462,8 +464,8 @@ def onReceive(packet, interface): # repeat the message on the other device if repeater_enabled and interface2_enabled: - # wait a 700ms to avoid message collision from lora-ack. - time.sleep(0.7) + # wait a responseDelay to avoid message collision from lora-ack. + time.sleep(responseDelay) rMsg = (f"{message_string} From:{get_name_from_number(message_from_id, 'short', rxNode)}") # if channel found in the repeater list repeat the message if str(channel_number) in repeater_channels: From b12cf6219a48681341dd18d84d109ec9f02f3ae4 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Fri, 6 Sep 2024 09:31:30 -0700 Subject: [PATCH 2/8] responseDelay --- pong_bot.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pong_bot.py b/pong_bot.py index c932e7c..dffd044 100755 --- a/pong_bot.py +++ b/pong_bot.py @@ -8,6 +8,8 @@ from pubsub import pub # pip install pubsub from modules.log import * from modules.system import * +responseDelay = 0.7 # delay in seconds for response to avoid message collision + def auto_response(message, snr, rssi, hop, message_from_id, channel_number, deviceID): # Auto response to messages message_lower = message.lower() @@ -37,8 +39,8 @@ def auto_response(message, snr, rssi, hop, message_from_id, channel_number, devi # run the first command after sorting bot_response = command_handler[cmds[0]['cmd']]() - # wait a 700ms to avoid message collision from lora-ack - time.sleep(0.7) + # wait a responseDelay to avoid message collision from lora-ack + time.sleep(responseDelay) return bot_response @@ -252,8 +254,8 @@ def onReceive(packet, interface): # repeat the message on the other device if repeater_enabled and interface2_enabled: - # wait a 700ms to avoid message collision from lora-ack. - time.sleep(0.7) + # wait a responseDelay to avoid message collision from lora-ack. + time.sleep(responseDelay) rMsg = (f"{message_string} From:{get_name_from_number(message_from_id, 'short', rxNode)}") # if channel found in the repeater list repeat the message if str(channel_number) in repeater_channels: From 6eb82b26a7388f50eadd0963d9cf4062e3bfd931 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Mon, 9 Sep 2024 23:27:12 -0700 Subject: [PATCH 3/8] Update mesh_bot.py --- mesh_bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesh_bot.py b/mesh_bot.py index 78b8011..4e4cbd6 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -147,7 +147,7 @@ def handle_llm(message_from_id, channel_number, deviceID, message, publicChannel # send via channel send_message(msg, channel_number, 0, deviceID) else: - msg = "Please wait, response could take 3+ minutes. Fund the SysOp's GPU budget!" + msg = "Please wait, response could take 30+ seconds. Fund the SysOp's GPU budget!" if channel_number == publicChannel: # send via DM send_message(msg, channel_number, message_from_id, deviceID) From 711844cc832703054ec52b5a123e5f09ba2e4dd5 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Tue, 10 Sep 2024 00:46:32 -0700 Subject: [PATCH 4/8] enhanceMessages fixes a few things I didnt wrap up and also enhances this suggestion https://github.com/SpudGunMan/meshing-around/issues/59 --- mesh_bot.py | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/mesh_bot.py b/mesh_bot.py index 4e4cbd6..2e603d3 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -106,30 +106,49 @@ def handle_wiki(message): return get_wikipedia_summary(search) else: return "Please add a search term example:wiki: travelling gnome" + +llmRunCounter = 0 +llmTotalRuntime = [] +llmLocationTable = {} def handle_llm(message_from_id, channel_number, deviceID, message, publicChannel): global llmRunCounter, llmTotalRuntime, llmLocationTable - + if location_enabled: location = get_node_location(message_from_id, deviceID) # if message_from_id is is the llmLocationTable use the location from the table to save on API calls if message_from_id in llmLocationTable: - location = llmLocationTable[message_from_id] + location_name = llmLocationTable[message_from_id] else: location_name = where_am_i(str(location[0]), str(location[1]), short = True) - llmLocationTable.append({message_from_id: location_name}) - if NO_DATA_NOGPS in location_name: - location_name = "no location provided " + if NO_DATA_NOGPS in location_name: + location_name = "no location provided " else: - location_name = "no location provided " + location_name = "no location provided" if "ask:" in message.lower(): user_input = message.split(":")[1] elif "askai" in message.lower(): user_input = message.replace("askai", "") else: + # likely a DM user_input = message + + # if the message_from_id is not in the llmLocationTable send the welcome message + if not message_from_id in llmLocationTable: + if channel_number == publicChannel: + # send via DM + send_message(welcome_message, channel_number, message_from_id, deviceID) + time.sleep(responseDelay) + else: + # send via channel + send_message(welcome_message, channel_number, 0, deviceID) + time.sleep(responseDelay) + + # add the node to the llmLocationTable for future use + llmLocationTable[message_from_id] = location_name + user_input = user_input.strip() if len(user_input) < 1: @@ -143,17 +162,21 @@ def handle_llm(message_from_id, channel_number, deviceID, message, publicChannel if channel_number == publicChannel: # send via DM send_message(msg, channel_number, message_from_id, deviceID) + time.sleep(responseDelay) else: # send via channel send_message(msg, channel_number, 0, deviceID) + time.sleep(responseDelay) else: - msg = "Please wait, response could take 30+ seconds. Fund the SysOp's GPU budget!" - if channel_number == publicChannel: - # send via DM - send_message(msg, channel_number, message_from_id, deviceID) - else: - # send via channel - send_message(msg, channel_number, 0, deviceID) + msg = "Please wait, response could take 30+ seconds. Fund the SysOp's GPU budget!" + if channel_number == publicChannel: + # send via DM + send_message(msg, channel_number, message_from_id, deviceID) + time.sleep(responseDelay) + else: + # send via channel + send_message(msg, channel_number, 0, deviceID) + time.sleep(responseDelay) start = time.time() From 96201648842d453c95b3314d149fd7c30e962dae Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Tue, 10 Sep 2024 00:46:43 -0700 Subject: [PATCH 5/8] Update locationdata.py enhance for LLM --- modules/locationdata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/locationdata.py b/modules/locationdata.py index 259b700..6717b7f 100644 --- a/modules/locationdata.py +++ b/modules/locationdata.py @@ -28,7 +28,7 @@ def where_am_i(lat=0, lon=0, short=False): location = geolocator.reverse(lat + ", " + lon) address = location.raw['address'] address_components = ['city', 'state', 'county', 'country'] - whereIam = f"City: {address.get('city', '')} State: {address.get('state', '')} County: {address.get('county', '')} Country: {address.get('country', '')}" + whereIam = f"City: {address.get('city', '')}. State: {address.get('state', '')}. County: {address.get('county', '')}. Country: {address.get('country', '')}." return whereIam if float(lat) == latitudeValue and float(lon) == longitudeValue: From e36755a21dd6847195a6b01ff512cdf9037c4527 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Tue, 10 Sep 2024 00:52:20 -0700 Subject: [PATCH 6/8] Update llm.py fix typo --- modules/llm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/llm.py b/modules/llm.py index e58f4d3..58a8329 100644 --- a/modules/llm.py +++ b/modules/llm.py @@ -105,9 +105,9 @@ def llm_query(input, nodeID=0, location_name=None): if googleResults: - logger.debug(f"System: External LLM Query: {input} From:{nodeID} with context from google") + logger.debug(f"System: LLM Query: {input} From:{nodeID} with context from google") else: - logger.debug(f"System: External LLM Query: {input} From:{nodeID}") + logger.debug(f"System: LLM Query: {input} From:{nodeID}") response = "" result = "" From d5e48a3e36292738ab677113afb542151400361f Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Tue, 10 Sep 2024 00:56:16 -0700 Subject: [PATCH 7/8] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fd3be30..1c53d4d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ The feature-rich bot requires the internet for full functionality. These respond Along with network testing, this bot has a lot of other fun features, like simple mail messaging you can leave for another device, and when that device is seen, it can send the mail as a DM. Or a scheduler to send weather or a reminder weekly for the VHF net. -The bot is also capable of using dual radio/nodes, so you can monitor two networks at the same time and send messages to nodes using the same `bbspost @nodeNumber #message` or `bbspost @nodeShportName #message` function. There is a small message board to fit in the constraints of Meshtastic for posting bulletin messages with `bbspost $subject #message`. +The bot is also capable of using dual radio/nodes, so you can monitor two networks at the same time and send messages to nodes using the same `bbspost @nodeNumber #message` or `bbspost @nodeShortName #message` function. There is a small message board to fit in the constraints of Meshtastic for posting bulletin messages with `bbspost $subject #message`. Look up data using wiki results or interact with [Ollama](https://ollama.com) LLM AI see the [OllamaDocs](https://github.com/ollama/ollama/tree/main/docs) If Ollama is enabled you can DM the bot directly. The default model for mesh-bot which is currently `gemma2:2b` @@ -32,7 +32,7 @@ Any messages that are over 160 characters are chunked into 160 message bytes to - `bbshelp` returns the following - `bbslist` list the messages by ID and subject - `bbsread` read a message example use: `bbsread #1` - - `bbspost` post a message to public board or send a DM example use: `bbspost $subject #message, or bbspost @nodeNumber #message or bbspost @nodeShportName #message` + - `bbspost` post a message to public board or send a DM example use: `bbspost $subject #message, or bbspost @nodeNumber #message or bbspost @nodeShortName #message` - `bbsdelete` delete a message example use: `bbsdelete #4` - Other functions - `whereami` returns the address of location of sender if known From 71733de05f6ee92d1b21e1c52a85f90339e37dfe Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Tue, 10 Sep 2024 12:59:00 -0700 Subject: [PATCH 8/8] enhance DM/Channel logic for llm fix logic for DM or Channel Sending --- mesh_bot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mesh_bot.py b/mesh_bot.py index 2e603d3..308e914 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -137,7 +137,7 @@ def handle_llm(message_from_id, channel_number, deviceID, message, publicChannel # if the message_from_id is not in the llmLocationTable send the welcome message if not message_from_id in llmLocationTable: - if channel_number == publicChannel: + if (channel_number == publicChannel and antiSpam) or useDMForResponse: # send via DM send_message(welcome_message, channel_number, message_from_id, deviceID) time.sleep(responseDelay) @@ -159,7 +159,7 @@ def handle_llm(message_from_id, channel_number, deviceID, message, publicChannel averageRuntime = sum(llmTotalRuntime) / len(llmTotalRuntime) if averageRuntime > 25: msg = f"Please wait, average query time is: {int(averageRuntime)} seconds" - if channel_number == publicChannel: + if (channel_number == publicChannel and antiSpam) or useDMForResponse: # send via DM send_message(msg, channel_number, message_from_id, deviceID) time.sleep(responseDelay) @@ -169,7 +169,7 @@ def handle_llm(message_from_id, channel_number, deviceID, message, publicChannel time.sleep(responseDelay) else: msg = "Please wait, response could take 30+ seconds. Fund the SysOp's GPU budget!" - if channel_number == publicChannel: + if (channel_number == publicChannel and antiSpam) or useDMForResponse: # send via DM send_message(msg, channel_number, message_from_id, deviceID) time.sleep(responseDelay)