From b1c2cc87ae101cbe36644b5ac86e592473d9eb74 Mon Sep 17 00:00:00 2001 From: P7MJ Date: Sun, 14 Jun 2026 12:24:56 -0400 Subject: [PATCH] restoration of b-2-iv and fixes into c-1-i --- .gitignore | 1 + chatchart-v-b-2-iv-final.py | 450 ++++++++++++++++++++++++++ chatchart-v-c-1-i.py | 406 +++++++++++++++++++++++ log-6-12to6-14.txt | 625 ++++++++++++++++++++++++++++++++++++ requirements.txt | 17 + 5 files changed, 1499 insertions(+) create mode 100644 .gitignore create mode 100644 chatchart-v-b-2-iv-final.py create mode 100644 chatchart-v-c-1-i.py create mode 100644 log-6-12to6-14.txt create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4dbacf4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +in-the-air/ diff --git a/chatchart-v-b-2-iv-final.py b/chatchart-v-b-2-iv-final.py new file mode 100644 index 0000000..19d6a39 --- /dev/null +++ b/chatchart-v-b-2-iv-final.py @@ -0,0 +1,450 @@ +from rich import print as pr +from rich.layout import Layout +from rich.panel import Panel +import termcharts +import ollama +import tkinter as tk +from tkinter import filedialog +import re +import heapq +import time +import sys + +cc_version = "ITA B-2-iv Final" + +# P7MJ's ITA (In the Air) chat mood analyzer, as a YAY project between 3/2 and 3/3 and finished on 3/3 (A-2-i). No longer so yay... +# Version B-1-i Refining (aka B-2-i Testing) completed on 3/5 +# Working on B-1-i 3/6 and 3/8. Procrastinating between. A-series, get ready to be lost in time, but i still have some copies +# B-2-i Testing testing on 3/8. Prelim testing completed. +# B-2-ii Final working on 3/8. Removing all TEST comments and running more test cases +# B-2-iii Final working on 3/9 Morning. Added a safeguard in case the LLM hallucinates giving the super_llm_rate. +# B-2-iv Final working on 3/9 Morning. Fixed and added static colors (then removed them) +# Presenting is 3/9 +# TODO Add async I DONT KNOW WHEN DONT ASK ME BYE THE EnD +# TODO Add functions super_llm_rate for all-at-once YAY and batch_llm_rate for 5 at one time YAY +# TODO Integrate readable_format() YAY +# In competition with Sean. He's doing much better... NOOOO +# I HATE the "pg up" and "pg down" buttons above the left and right arrow keys! I always misclick them and my page jumps! + +# WRITING LETTER TO H. COMBINED WITH THIS CODE MAKES MY BRAIN BURN +# Coding: ❌ +# Breaking heart: ✔️ +# Burning brain: ✔️ +# Feeling like quitting: ✔️ + +# STATS VS OTHER VERSIONS: (ABORTED) +# Positive/Negative/Neutral Rating Time + +# GOODLOG +# B-2-i/ii: 0/11/19 -0.307 89 +# B-1-i: + +rating_data = [] +total_messages = 0 +messages_rated = 0 +posanslist = [] +neganslist = [] +chat_summary = "" +chat_message_list = "" + +# Find indices of 5 ratings with largest value +def get_n_largest_indices(data, n): + largest_items = heapq.nlargest(n, enumerate(data), key=lambda x: x[1]) + indices = [index for index, value in largest_items] + return indices + +# Make single or more messages readable +def readable_format(inputs): + processed = "\n" + for i in range(len(inputs)): + processed += f"{inputs[i][0]}: {inputs[i][1]}\n" + processed += "" + return processed + +# One readable message +def readable_one_message(single_input_list): + return f"{single_input_list[0]}: {single_input_list[1]}" + +# Find indices of 5 ratings with smallest value +def get_n_smallest_indices(data, n): + smallest_items = heapq.nsmallest(n, enumerate(data), key=lambda x: x[1]) + indices = [index for index, value in smallest_items] + return indices + +# Processes the raw chat log into a readable list +def parse_chat_log(file_path): + # Regex to match the timestamp format: [03/02/2026 00:14] + pattern = re.compile(r"\[\d{2}/\d{2}/\d{4} \d{2}:\d{2}\]\s+(.*)") + chat_data = [] + current_user = None + current_message = [] + with open(file_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if not line or line.startswith("===") or line.startswith("Exported"): + continue + match = pattern.match(line) + if match: + if current_user: + chat_data.append([current_user, "\n".join(current_message)]) + current_user = match.group(1) + current_message = [] + else: + current_message.append(line) + if current_user: + chat_data.append([current_user, "\n".join(current_message)]) + return chat_data + +def split_thy_list_for_thy_batch_function(inputses): + processing = inputses.copy() + batches = [] + if len(inputses) > 5: + while True: # i actually mean while the numbers are larger than 5 + if len(processing) > 5: + batches.append(processing[:5]) + del processing[:5] + else: + batches.append(processing) + break + return batches + else: + batches.append(inputses) + return batches + +# Filters and processes the values, replacing text answers (switches to -0.5 because usually in that case the topic is so bad that the LLM refuses to rate it, therefore an automatic rating of -0.5), and 0.00s since the LLM would rather classify bad chats as 0.00 rather than mark it negative +def float_filter(value): + try: + float(value) + if float(value) == 0.00: + return -0.10 + else: + return float(value) + except ValueError: + return -0.5 + +def process_llm_list(input_string): + stripped = input_string.strip() + splitted = stripped.split(", ") + for i in range(len(splitted)): + try: + splitted[i] = float(splitted[i]) + except: + print(f"E {splitted[i]} not_float") + splitted[i] = -2 + return splitted + +# Uses the LLM to rate messages +def llm_rate(user_input, length): + global messages_rated + response = ollama.chat(model='llama3.2', messages=[ + # The system prompt DO NOT DELETE + { + 'role': 'system', + 'content': ( + "Sentiment Analyzer: Output ONLY a float between -1.0 and 1.0." + "Chat message format is user: message. Analyze single message." + "Scoring: Hostile/Insulting (-0.8), Dismissive/Sarcastic (-0.5)," + "Apathetic/Short (-0.2), Neutral/Functional (0.0), Positive/Link (0.1-1.0)." + "No prose." + ) + }, + + # The user (DO NOT DELETE) + {'role': 'user', 'content': readable_one_message(user_input)} + ]) + + messages_rated += 1 # PLUS ONE TO PROGRESS + print(f"\r{messages_rated}/{length} messages rated by LLM.", end = "") + # Add the rating data to rating data + rating_data.append(response['message']['content']) + +# TODO make it rate all the messages at once +def super_llm_rate(inputs): + while True: + print("LLM All-at-once Rating Mode rating...", end = " ", flush=True) + global chatmessagelist + response = ollama.chat(model='llama3.2', messages=[ + # The system prompt DO NOT DELETE + { + 'role': 'system', + 'content': ( + "Sentiment Analyzer: Output ONLY a list of floats between -1.0 and 1.0, like '0.0, 0.5, -0.5'." + "Chat messages are between and . Analyze the chat records and give rating to each message in order." + "Scoring: Hostile/Insulting (-0.8), Dismissive/Sarcastic (-0.5)," + "Apathetic/Short (-0.2), Neutral/Functional (0.0), Positive/Link (0.1-1.0)." + f"There are {len(chatmessagelist)} messages in total. Make sure you have the same amount of ratings." + "Exactly a comma followed by a space between ratings. No prose. Double check amount." + ) + }, + + # The user (DO NOT DELETE) + {'role': 'user', 'content': readable_format(inputs)} + ]) + finished = process_llm_list(response['message']['content']) + # Add the rating data to rating data + if len(finished) == len(chatmessagelist): + for i in range(len(finished)): + rating_data.append(finished[i]) + break + else: + print("LLM Hallucinated!") + +# Accepts a list of junk! (unprocessed parsed list) +def batch_llm_rate(inputs): + global messages_rated, chatmessagelist + print("Creating batches...", end = " ", flush=True) + try: + batcheses = split_thy_list_for_thy_batch_function(inputs) + print("Success!") + except: + print("Fail!") + sys.exit(0) + + print("Rating...", end = "", flush=True) + for i in range(len(batcheses)): + that_one_batch = batcheses[i] + response = ollama.chat(model='llama3.2', messages=[ + # The system prompt DO NOT DELETE + { + 'role': 'system', + 'content': ( + "Sentiment Analyzer: Output ONLY a list of floats between -1.0 and 1.0, like '0.0, 0.5, -0.5'." + "Chat messages are between and . Analyze the chat records and give rating to each message in order." + "Scoring: Hostile/Insulting (-0.8), Dismissive/Sarcastic (-0.5)," + "Apathetic/Short (-0.2), Neutral/Functional (0.0), Positive/Link (0.1-1.0)." + f"There are {len(that_one_batch)} messages in total. Make sure you have {len(that_one_batch)} ratings." + "Exactly a comma followed by a space between ratings. No prose. Double check amount." + ) + }, + + # The user (DO NOT DELETE) + {'role': 'user', 'content': readable_format(that_one_batch)} + ]) + finished_list = process_llm_list(response['message']['content']) + for i in range(len(finished_list)): + rating_data.append(finished_list[i]) + print("\r" + f"{len(rating_data)}/{len(inputs)} messages rated", end = "") + +# SUMMARIZE EVERYTHING YAYAYAYAAAYAYA +def chat_summarizer(lists): + global topicsummarizerlist + global chat_summary + print("Summarizing chat...", end = " ", flush=True) + response = ollama.chat(model='llama3.2', messages=[ + # The system prompt DO NOT DELETE + { + 'role': 'system', + 'content': ( + 'Chat Summarizer Tool: Sumarize given chat between and . Return brief summary and lists of topics discussed in order. Explain chat flow. Hypothesize user personalities. Use as few lines as possible.' + ) + }, + + # The user (DO NOT DELETE) + {'role': 'user', 'content': readable_format(lists)} + ]) + chat_summary = response['message']['content'] + print("Success!") + +# Start ITA Agent +def start_ita_agent(mood, summary): + messages = [ + { + 'role': 'system', + 'content': (f"Sentiment Analysis Tool. Respond to the user's questions on analyzed chat." + f"Analyzed data was: mood = {mood} with 0 being average." + f"summary: {summary}. Respond in short and concise sentences." + ) + } + ] + + print("Type 'exit' or 'quit' to end the session.\n") + + # 2. Loop forever + while True: + user_input = input("You > ") + if user_input.lower() in ['exit', 'quit']: + break + + # 3. Add user input to memory + messages.append({'role': 'user', 'content': user_input}) + + print("ITA Analysis Agent > ", end="", flush=True) + + # 4. Stream the response + full_response = "" + stream = ollama.chat(model='llama3.2', messages=messages, stream=True) + + for chunk in stream: + content = chunk['message']['content'] + print(content, end="", flush=True) + full_response += content + + # 5. Add assistant reply to memory so it stays in context + messages.append({'role': 'assistant', 'content': full_response}) + print() # Add a final newline for formatting + +# Counts answers for statistics chart +def countanswers(list): + goodanswers = 0 + badanswers = 0 + neutralanswers = 0 + for z in range(len(list)): + if list[z] > -0.3 and list[z] < 0.3: + neutralanswers += 1 + elif list[z] > 0.3: + goodanswers += 1 + elif list[z] < -0.3: + badanswers += 1 + return [goodanswers, badanswers, neutralanswers] + + +# MAIN +if __name__ == "__main__": + # Chat log choosing function + while True: + print(f""" +{"=" * 80} +ITA (In the Air) Mood Interpretor | Version: {cc_version} - P7MJ +{"=" * 80} + +Choose a chat log to evaluate +[1] goodlog.txt +[2] badlog.txt +[3] testlog.txt +[4] specify""") + log_to_choose = input(" > ") + if log_to_choose == "1": + log_to_choose = "goodlog.txt" + break + if log_to_choose == "2": + log_to_choose = "badlog.txt" + break + if log_to_choose == "3": + log_to_choose = "testlog.txt" + break + if log_to_choose == "4": + log_to_choose = input("Text file name (w/extension) > ") + break + else: + print("Invalid Option!") + + # Start the timer + start_time = time.perf_counter() + + # Processes the chat log and stores in variable + print("Parsing chat message file...", end = " ") + try: + chatmessagelist = parse_chat_log(f"{log_to_choose}") + except: + input("File does not exist! Press enter to exit...") + sys.exit(0) + print("Complete.") + + while True: + rating_mode = input("\nChoose rating mode:\n[1] Individual message rating\n[2] Batches of 5 rating\n[3] All-at-once rating\n > ") + try: + nonono = int(rating_mode) + if nonono <= 3: + break + else: + hi = 3/0 + except: + print("Not an integer or within range!") + + if rating_mode == "1": + # Gives the chatbot each message and has it rate it + for m in range(len(chatmessagelist)): + prompt = str(chatmessagelist[m][1]) + llm_rate(prompt, len(chatmessagelist)) + + elif rating_mode == "2": + batch_llm_rate(chatmessagelist) + + elif rating_mode == "3": + super_llm_rate(chatmessagelist) + + # Filters and processes rating data + for i in range(len(rating_data)): + rating_data[i] = float_filter(rating_data[i]) + + # Calculates rating mean + sum_of_numbers = 0 + for k in range(len(rating_data)): + sum_of_numbers += rating_data[k] + sum_of_numbers /= len(rating_data) + + # Finding them + list_of_best_answers = get_n_largest_indices(rating_data, 5) + list_of_worst_answers = get_n_smallest_indices(rating_data, 5) + + # Calculate best messages and appending to list + for j in range(len(list_of_best_answers)): + posanslist.append(f"[{j+1}] {chatmessagelist[list_of_best_answers[j]][0]}: {chatmessagelist[list_of_best_answers[j]][1]}") + + # Calculate worst messages and appending to list + for k in range(len(list_of_worst_answers)): + neganslist.append(f"[{k+1}] {chatmessagelist[list_of_worst_answers[k]][0]}: {chatmessagelist[list_of_worst_answers[k]][1]}") + + + # Calculate number of results in each catagory + stastisticresults = countanswers(rating_data) + + print() # Add a line after the ratings + + # Summarizes everything + chat_summarizer((chatmessagelist)) + + # End the timer + end_time = time.perf_counter() + elapsed_time = end_time - start_time + + # Sample data + data = {"Positive": stastisticresults[0], "Negative": stastisticresults[1], "Neutral": stastisticresults[2]} + chart1 = termcharts.bar(data, title="Chart of message emotions", rich=True) + + # Define the layout + layout = Layout() + + # 1. Split into Top and Bottom halves + layout.split_column( + Layout(name="upper", size=20), # Fixed height for top section + Layout(name="lower") # Bottom takes the remainder + ) + + # 2. Configure Top: 1/4 (25%) for chart, rest split 50/50 + layout["upper"].split_row( + Layout(name="uleft", ratio=1), # 25% of total width (1 part) + Layout(name="uright", ratio=3), # 75% of total width (3 parts) + ) + + # Split the 75% right side into two text panels + layout["uright"].split_row( + Layout(Panel(f"STATISTICS\n\nRating Average: {round(sum_of_numbers, 3)}\nPositive Ratings: {stastisticresults[0]}\nNegative Ratings: {stastisticresults[1]}\nNeutral Ratings: {stastisticresults[2]}\nTotal messages analyzed: {len(rating_data)}\nTotal time elapsed: {elapsed_time:.4f} seconds")), + Layout(Panel(fr""" + ___ _________ ________ + |\ \|\___ ___\\ __ \ + \ \ \|___ \ \_\ \ \|\ \ + \ \ \ \ \ \ \ \ __ \ + \ \ \ \ \ \ \ \ \ \ \ + \ \__\ \ \__\ \ \__\ \__\ + \|__| \|__| \|__|\|__| + + ©️2026 P7MJ + All Rights Reserved + + In the Air, {cc_version} by P7MJ + Know the mood - and what to say next. + """)) + ) + # 3. Configure Bottom: 50/50 split + layout["lower"].split_row( + Layout(Panel(f"OUTSTANDING MESSAGES\n\nMOST POSITIVE ANSWERS\n{posanslist[0][:200]}\n{posanslist[1][:200]}\n{posanslist[2][:200]}\n{posanslist[3][:200]}\n{posanslist[4][:200]}\n\n\nMOST NEGATIVE ANSWERS\n{neganslist[0][:200]}\n{neganslist[1][:200]}\n{neganslist[2][:200]}\n{neganslist[3][:200]}\n{neganslist[4][:200]}")), + Layout(Panel(f"CHAT SUMMARY\n\n{chat_summary}")), + ) + + # 4. Fill the chart + layout["uleft"].update(Panel(chart1)) + + pr(layout) + input("PRESS ENTER TO LAUNCH ITA CHAT AGENT") + start_ita_agent(round(sum_of_numbers, 3), chat_summary) diff --git a/chatchart-v-c-1-i.py b/chatchart-v-c-1-i.py new file mode 100644 index 0000000..2a49666 --- /dev/null +++ b/chatchart-v-c-1-i.py @@ -0,0 +1,406 @@ +from rich import print as pr +from rich.layout import Layout +from rich.panel import Panel +import termcharts +import ollama +import tkinter as tk +from tkinter import filedialog +import re +import heapq +import time +import sys + +# Officially advanced to the C-series tier! +cc_version = "ITA C-1-i" + +# P7MJ's ITA (In the Air) chat mood analyzer, as a YAY project between 3/2 and 3/3 and finished on 3/3 (A-2-i). No longer so yay... +# Version B-1-i Refining (aka B-2-i Testing) completed on 3/5 +# Working on B-1-i 3/6 and 3/8. Procrastinating between. A-series, get ready to be lost in time, but i still have some copies +# B-2-i Testing testing on 3/8. Prelim testing completed. +# B-2-ii Final working on 3/8. Removing all TEST comments and running more test cases +# B-2-iii Final working on 3/9 Morning. Added a safeguard in case the LLM hallucinates giving the super_llm_rate. +# B-2-iv Final working on 3/9 Morning. Fixed and added static colors (then removed them) +# Presenting is 3/9 +# C-1-i Patched 6/14/2026. Upgraded regex parser for flexible AM/PM 12-hour exporter logs & added crash safeguards. + +rating_data = [] +total_messages = 0 +messages_rated = 0 +posanslist = [] +neganslist = [] +chat_summary = "" +chat_message_list = "" + +# Find indices of 5 ratings with largest value +def get_n_largest_indices(data, n): + largest_items = heapq.nlargest(n, enumerate(data), key=lambda x: x[1]) + indices = [index for index, value in largest_items] + return indices + +# Make single or more messages readable +def readable_format(inputs): + processed = "\n" + for i in range(len(inputs)): + processed += f"{inputs[i][0]}: {inputs[i][1]}\n" + processed += "" + return processed + +# One readable message +def readable_one_message(single_input_list): + return f"{single_input_list[0]}: {single_input_list[1]}" + +# Find indices of 5 ratings with smallest value +def get_n_smallest_indices(data, n): + smallest_items = heapq.nsmallest(n, enumerate(data), key=lambda x: x[1]) + indices = [index for index, value in smallest_items] + return indices + +# Processes the raw chat log into a readable list +def parse_chat_log(file_path): + # FIXED FOR C-1-i: Matches flexible [M/D/YYYY H:MM AM/PM] style formats seamlessly + pattern = re.compile(r"\[\d{1,2}/\d{1,2}/\d{4} \d{1,2}:\d{2}\s*(?:AM|PM)?\]\s+(.*)") + chat_data = [] + current_user = None + current_message = [] + with open(file_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if not line or line.startswith("===") or line.startswith("Exported"): + continue + match = pattern.match(line) + if match: + if current_user: + chat_data.append([current_user, "\n".join(current_message)]) + current_user = match.group(1) + current_message = [] + else: + current_message.append(line) + if current_user: + chat_data.append([current_user, "\n".join(current_message)]) + return chat_data + +def split_thy_list_for_thy_batch_function(inputses): + processing = inputses.copy() + batches = [] + if len(inputses) > 5: + while True: + if len(processing) > 5: + batches.append(processing[:5]) + del processing[:5] + else: + batches.append(processing) + break + return batches + else: + batches.append(inputses) + return batches + +# Filters and processes the values, replacing text answers and 0.00s +def float_filter(value): + try: + float(value) + if float(value) == 0.00: + return -0.10 + else: + return float(value) + except ValueError: + return -0.5 + +def process_llm_list(input_string): + stripped = input_string.strip() + splitted = stripped.split(", ") + for i in range(len(splitted)): + try: + splitted[i] = float(splitted[i]) + except: + print(f"E {splitted[i]} not_float") + splitted[i] = -2 + return splitted + +# Uses the LLM to rate messages +def llm_rate(user_input, length): + global messages_rated + response = ollama.chat(model='llama3.2', messages=[ + { + 'role': 'system', + 'content': ( + "Sentiment Analyzer: Output ONLY a float between -1.0 and 1.0." + "Chat message format is user: message. Analyze single message." + "Scoring: Hostile/Insulting (-0.8), Dismissive/Sarcastic (-0.5)," + "Apathetic/Short (-0.2), Neutral/Functional (0.0), Positive/Link (0.1-1.0)." + "No prose." + ) + }, + {'role': 'user', 'content': readable_one_message(user_input)} + ]) + + messages_rated += 1 + print(f"\r{messages_rated}/{length} messages rated by LLM.", end = "") + rating_data.append(response['message']['content']) + +# Rate all the messages at once +def super_llm_rate(inputs): + global chat_message_list + while True: + print("LLM All-at-once Rating Mode rating...", end = " ", flush=True) + response = ollama.chat(model='llama3.2', messages=[ + { + 'role': 'system', + 'content': ( + "Sentiment Analyzer: Output ONLY a list of floats between -1.0 and 1.0, like '0.0, 0.5, -0.5'." + "Chat messages are between and . Analyze the chat records and give rating to each message in order." + "Scoring: Hostile/Insulting (-0.8), Dismissive/Sarcastic (-0.5)," + "Apathetic/Short (-0.2), Neutral/Functional (0.0), Positive/Link (0.1-1.0)." + f"There are {len(chat_message_list)} messages in total. Make sure you have the same amount of ratings." + "Exactly a comma followed by a space between ratings. No prose. Double check amount." + ) + }, + {'role': 'user', 'content': readable_format(inputs)} + ]) + finished = process_llm_list(response['message']['content']) + # FIXED FOR C-1-i: Corrected global variable reference target + if len(finished) == len(chat_message_list): + for i in range(len(finished)): + rating_data.append(finished[i]) + break + else: + print("LLM Hallucinated!") + +# Accepts a list of unprocessed parsed entries +def batch_llm_rate(inputs): + global messages_rated + print("Creating batches...", end = " ", flush=True) + try: + batcheses = split_thy_list_for_thy_batch_function(inputs) + print("Success!") + except: + print("Fail!") + sys.exit(0) + + print("Rating...", end = "", flush=True) + for i in range(len(batcheses)): + that_one_batch = batcheses[i] + response = ollama.chat(model='llama3.2', messages=[ + { + 'role': 'system', + 'content': ( + "Sentiment Analyzer: Output ONLY a list of floats between -1.0 and 1.0, like '0.0, 0.5, -0.5'." + "Chat messages are between and . Analyze the chat records and give rating to each message in order." + "Scoring: Hostile/Insulting (-0.8), Dismissive/Sarcastic (-0.5)," + "Apathetic/Short (-0.2), Neutral/Functional (0.0), Positive/Link (0.1-1.0)." + f"There are {len(that_one_batch)} messages in total. Make sure you have {len(that_one_batch)} ratings." + "Exactly a comma followed by a space between ratings. No prose. Double check amount." + ) + }, + {'role': 'user', 'content': readable_format(that_one_batch)} + ]) + finished_list = process_llm_list(response['message']['content']) + for k in range(len(finished_list)): + rating_data.append(finished_list[k]) + print("\r" + f"{len(rating_data)}/{len(inputs)} messages rated", end = "") + +# Summarizes logs +def chat_summarizer(lists): + global chat_summary + print("Summarizing chat...", end = " ", flush=True) + response = ollama.chat(model='llama3.2', messages=[ + { + 'role': 'system', + 'content': ( + 'Chat Summarizer Tool: Sumarize given chat between and . Return brief summary and lists of topics discussed in order. Explain chat flow. Hypothesize user personalities. Use as few lines as possible.' + ) + }, + {'role': 'user', 'content': readable_format(lists)} + ]) + chat_summary = response['message']['content'] + print("Success!") + +# Start ITA Agent +def start_ita_agent(mood, summary): + messages = [ + { + 'role': 'system', + 'content': (f"Sentiment Analysis Tool. Respond to the user's questions on analyzed chat." + f"Analyzed data was: mood = {mood} with 0 being average." + f"summary: {summary}. Respond in short and concise sentences." + ) + } + ] + + print("Type 'exit' or 'quit' to end the session.\n") + + while True: + user_input = input("You > ") + if user_input.lower() in ['exit', 'quit']: + break + + messages.append({'role': 'user', 'content': user_input}) + print("ITA Analysis Agent > ", end="", flush=True) + + full_response = "" + stream = ollama.chat(model='llama3.2', messages=messages, stream=True) + + for chunk in stream: + content = chunk['message']['content'] + print(content, end="", flush=True) + full_response += content + + messages.append({'role': 'assistant', 'content': full_response}) + print() + +# Counts answers for statistics chart +def countanswers(lst): + goodanswers = 0 + badanswers = 0 + neutralanswers = 0 + for z in range(len(lst)): + if lst[z] > -0.3 and lst[z] < 0.3: + neutralanswers += 1 + elif lst[z] > 0.3: + goodanswers += 1 + elif lst[z] < -0.3: + badanswers += 1 + return [goodanswers, badanswers, neutralanswers] + + +# MAIN +if __name__ == "__main__": + while True: + print(f""" +{"=" * 80} +ITA (In the Air) Mood Interpretor | Version: {cc_version} - P7MJ +{"=" * 80} + +Choose a chat log to evaluate +[1] goodlog.txt +[2] badlog.txt +[3] testlog.txt +[4] specify""") + log_to_choose = input(" > ") + if log_to_choose == "1": + log_to_choose = "goodlog.txt" + break + elif log_to_choose == "2": + log_to_choose = "badlog.txt" + break + elif log_to_choose == "3": + log_to_choose = "testlog.txt" + break + elif log_to_choose == "4": + log_to_choose = input("Text file name (w/extension) > ") + break + else: + print("Invalid Option!") + + start_time = time.perf_counter() + + print("Parsing chat message file...", end = " ") + try: + chat_message_list = parse_chat_log(f"{log_to_choose}") + except Exception as e: + input(f"Error opening file! {e}. Press enter to exit...") + sys.exit(0) + + # FIXED FOR C-1-i: Clean layout exit fallback if the file exists but has no matched lines + if len(chat_message_list) == 0: + input("\nError: No messages parsed! Check your timestamp formats. Press enter to exit...") + sys.exit(0) + + print("Complete.") + + while True: + rating_mode = input("\nChoose rating mode:\n[1] Individual message rating\n[2] Batches of 5 rating\n[3] All-at-once rating\n > ") + if rating_mode in ["1", "2", "3"]: + break + else: + print("Not an integer or within range!") + + if rating_mode == "1": + for m in range(len(chat_message_list)): + prompt = str(chat_message_list[m][1]) + llm_rate(chat_message_list[m], len(chat_message_list)) + elif rating_mode == "2": + batch_llm_rate(chat_message_list) + elif rating_mode == "3": + super_llm_rate(chat_message_list) + + # Filters and processes rating data + for i in range(len(rating_data)): + rating_data[i] = float_filter(rating_data[i]) + + # FIXED FOR C-1-i: Division-by-zero protection guard + if len(rating_data) > 0: + sum_of_numbers = 0 + for k in range(len(rating_data)): + sum_of_numbers += rating_data[k] + sum_of_numbers /= len(rating_data) + else: + sum_of_numbers = 0.0 + + list_of_best_answers = get_n_largest_indices(rating_data, 5) + list_of_worst_answers = get_n_smallest_indices(rating_data, 5) + + # FIXED FOR C-1-i: Added safe index length checks to cleanly populate panels if under 5 items exist + for j in range(5): + if j < len(list_of_best_answers) and list_of_best_answers[j] < len(chat_message_list): + posanslist.append(f"[{j+1}] {chat_message_list[list_of_best_answers[j]][0]}: {chat_message_list[list_of_best_answers[j]][1]}") + else: + posanslist.append(f"[{j+1}] N/A: No data available") + + for k in range(5): + if k < len(list_of_worst_answers) and list_of_worst_answers[k] < len(chat_message_list): + neganslist.append(f"[{k+1}] {chat_message_list[list_of_worst_answers[k]][0]}: {chat_message_list[list_of_worst_answers[k]][1]}") + else: + neganslist.append(f"[{k+1}] N/A: No data available") + + stastisticresults = countanswers(rating_data) + print() + + chat_summarizer(chat_message_list) + + end_time = time.perf_counter() + elapsed_time = end_time - start_time + + data = {"Positive": stastisticresults[0], "Negative": stastisticresults[1], "Neutral": stastisticresults[2]} + chart1 = termcharts.bar(data, title="Chart of message emotions", rich=True) + + layout = Layout() + layout.split_column( + Layout(name="upper", size=20), + Layout(name="lower") + ) + + layout["upper"].split_row( + Layout(name="uleft", ratio=1), + Layout(name="uright", ratio=3), + ) + + layout["uright"].split_row( + Layout(Panel(f"STATISTICS\n\nRating Average: {round(sum_of_numbers, 3)}\nPositive Ratings: {stastisticresults[0]}\nNegative Ratings: {stastisticresults[1]}\nNeutral Ratings: {stastisticresults[2]}\nTotal messages analyzed: {len(rating_data)}\nTotal time elapsed: {elapsed_time:.4f} seconds")), + Layout(Panel(fr""" + ___ _________ ________ + |\ \|\___ ___\\ __ \ + \ \ \|___ \ \_\ \ \|\ \ + \ \ \ \ \ \ \ \ __ \ + \ \ \ \ \ \ \ \ \ \ \ + \ \__\ \ \__\ \ \__\ \__\ + \|__| \|__| \|__|\|__| + + ©️2026 P7MJ + All Rights Reserved + + In the Air, {cc_version} by P7MJ + Know the mood - and what to say next. + """)) + ) + + layout["lower"].split_row( + Layout(Panel(f"OUTSTANDING MESSAGES\n\nMOST POSITIVE ANSWERS\n{posanslist[0][:200]}\n{posanslist[1][:200]}\n{posanslist[2][:200]}\n{posanslist[3][:200]}\n{posanslist[4][:200]}\n\n\nMOST NEGATIVE ANSWERS\n{neganslist[0][:200]}\n{neganslist[1][:200]}\n{neganslist[2][:200]}\n{neganslist[3][:200]}\n{neganslist[4][:200]}")), + Layout(Panel(f"CHAT SUMMARY\n\n{chat_summary}")), + ) + + layout["uleft"].update(Panel(chart1)) + + pr(layout) + input("PRESS ENTER TO LAUNCH ITA CHAT AGENT") + start_ita_agent(round(sum_of_numbers, 3), chat_summary) \ No newline at end of file diff --git a/log-6-12to6-14.txt b/log-6-12to6-14.txt new file mode 100644 index 0000000..e847a5e --- /dev/null +++ b/log-6-12to6-14.txt @@ -0,0 +1,625 @@ +============================================================== +Guild: Direct Messages +Channel: wholeworldcoding +After: 6/12/2026 12:00 AM +Before: 6/14/2026 12:00 AM +============================================================== + +[6/12/2026 1:26 AM] p7mj_tehaiker814 +idk seems quarter real quarter fake quarter advertisement quarter scam + +{Attachments} +https://cdn.discordapp.com/attachments/1442619038587945100/1514802968808001556/image.png?ex=6a2ffd73&is=6a2eabf3&hm=347ca44845f602386b71094df4128864e0b90e6e15d5493041c91c6a2c696a3e& + + +[6/12/2026 1:30 AM] p7mj_tehaiker814 +have officially began yt channel + +{Attachments} +https://cdn.discordapp.com/attachments/1442619038587945100/1514804150280523996/image.png?ex=6a2ffe8d&is=6a2ead0d&hm=14a48b825473facf437dc9499e275e160674def325d302387e98857971f47f2c& + +{Reactions} +🔥 + +[6/12/2026 1:56 AM] octolinkyt +Could be virus app? + + +[6/12/2026 1:57 AM] octolinkyt +Or some1 trying to boost installs on their app? + + +[6/12/2026 2:00 AM] p7mj_tehaiker814 +Yes + + +[6/12/2026 2:00 AM] p7mj_tehaiker814 +I'm gonna make video abt it + + +[6/12/2026 3:45 PM] spydrone2 +Deep in the dense, uncharted rainforest of NHRHS, researchers astonished the scientific community by discovering an elusive new species which they call Jackson Sherry + +{Attachments} +https://cdn.discordapp.com/attachments/1442619038587945100/1515019181085429790/20260612_113622.jpg?ex=6a2f7550&is=6a2e23d0&hm=4c4a01ecb81743805aa034ce78c3f2e46c390cba33a2475bb9b88a9354ac0241& +https://cdn.discordapp.com/attachments/1442619038587945100/1515019181534482512/20260612_113614.jpg?ex=6a2f7550&is=6a2e23d0&hm=b52b49de7b340759e5e6da091a6c6c0cc7f19656347f43e5fc23aa572ac0f141& +https://cdn.discordapp.com/attachments/1442619038587945100/1515019181953777735/20260612_113520.jpg?ex=6a2f7550&is=6a2e23d0&hm=589468d2af2591b3dd9ff34c5c0ef96437194af65d40e0850a5c21f5ff4b4335& + + +[6/12/2026 3:59 PM] octolinkyt +Wha + + +[6/12/2026 3:59 PM] octolinkyt +<@1126508920312168498> what when where why + + +[6/12/2026 4:00 PM] octolinkyt +<@1126508920312168498> + + +[6/12/2026 4:00 PM] octolinkyt +I wonder if <@1126508920312168498> knows that im pinging him + + +[6/12/2026 4:01 PM] octolinkyt +Yk what, I feel bad for pinging <@1126508920312168498> so many times + + +[6/12/2026 4:01 PM] octolinkyt +Im sorry <@1126508920312168498>, won't happen again + + +[6/12/2026 4:01 PM] spydrone2 +I just left + + +[6/12/2026 4:01 PM] spydrone2 +u didn't even notice + + +[6/12/2026 4:01 PM] octolinkyt +Damn + + +[6/12/2026 6:41 PM] spydrone2 +<@967396075440853022> gimme a ride pls + + +[6/12/2026 6:41 PM] spydrone2 +pls + + +[6/12/2026 6:41 PM] spydrone2 +plez + + +[6/12/2026 6:41 PM] spydrone2 +please + + +[6/12/2026 6:41 PM] spydrone2 +plz + + +[6/12/2026 6:41 PM] spydrone2 +all forms of please + + +[6/12/2026 6:42 PM] p7mj_tehaiker814 +https://tenor.com/view/rejected-stamp-gif-12255531 + + +[6/12/2026 8:34 PM] octolinkyt +Nah I actually did give him a ride + + +[6/13/2026 12:38 AM] spydrone2 +npx sndcli +for jackson + + +[6/13/2026 12:57 AM] spydrone2 +https://github.com/SpaceCypher/doxa + +{Embed} +https://github.com/SpaceCypher/doxa +GitHub - SpaceCypher/doxa +Contribute to SpaceCypher/doxa development by creating an account on GitHub. +https://images-ext-1.discordapp.net/external/Nh9ZlnnKfGIDyAtGvvRja0mnlFv9Cxh62L6aVN5Nx10/https/opengraph.githubassets.com/81e9a42167d25bda867ffa1418350bfa48fa6ee23bc6b944227b5e40940f48eb/SpaceCypher/doxa + + +[6/13/2026 1:22 AM] p7mj_tehaiker814 +Sean continues to search the web + + +[6/13/2026 1:22 AM] p7mj_tehaiker814 +https://tenor.com/view/boost-search-business-google-search-ranking-search-gif-7448249517589358712 + +{Embed} +https://tenor.com/view/boost-search-business-google-search-ranking-search-gif-7448249517589358712 +https://images-ext-1.discordapp.net/external/Vb2xxsbbr4rtgTfL6gJXuSz0Evwtz3ikqY0fS79qwVI/https/media.tenor.com/Z11_eUZjaHgAAAAe/boost-search-business.png + + +[6/13/2026 1:26 AM] spydrone2 +Na + + +[6/13/2026 1:26 AM] spydrone2 +I have fallen so low because of boredom + + +[6/13/2026 1:26 AM] spydrone2 +I now search .... + + +[6/13/2026 1:27 AM] spydrone2 +https://giphy.com/gifs/reddit-snoo-rddt-reddit-logo-ZtDnSN82QjH0b4zIVQ + +{Embed} +Reddit +https://giphy.com/gifs/reddit-snoo-rddt-reddit-logo-ZtDnSN82QjH0b4zIVQ +https://images-ext-1.discordapp.net/external/pKEmVwK83adTxFBPr3tjFHU5EejTL5rb4cdSg8e_8To/https/media1.giphy.com/media/v1.Y2lkPTczYjhmN2IxdnFxNGlqem80MWwzdno5d3N4aWd4MXhyeXZ5NGs3d2ZpMGs5YnFmZSZlcD12MV9naWZzX2dpZklkJmN0PWc/ZtDnSN82QjH0b4zIVQ/giphy_s.gif + + +[6/13/2026 1:27 AM] spydrone2 +https://giphy.com/gifs/pudgypenguins-work-computer-working-Qu9ZjFARNVBG1fYdc1 + +{Embed} +Pudgy Penguins +https://giphy.com/gifs/pudgypenguins-work-computer-working-Qu9ZjFARNVBG1fYdc1 +https://images-ext-1.discordapp.net/external/v2__l1ZuIhtYGZcn7PfI-pudxUEZaBF_RM8OdhwlZDY/https/media4.giphy.com/media/v1.Y2lkPTczYjhmN2IxYzV1YTlmNm83emRhenk0YmM4YWN3NmRxMGJwbWp4b3lleTVwdWRwMSZlcD12MV9naWZzX2dpZklkJmN0PWc/Qu9ZjFARNVBG1fYdc1/giphy_s.gif + + +[6/13/2026 2:07 AM] octolinkyt +This is another idea I had before someone did it + + +[6/13/2026 2:56 AM] octolinkyt +I do wanna make my own + + +[6/13/2026 2:57 AM] octolinkyt +Like almost an ant farm of llm models + + +[6/13/2026 2:57 AM] octolinkyt +But give them the ability to create, give them a bunch of things they can build... + + +[6/13/2026 2:57 AM] octolinkyt +Give the parents control over the children, give the children the opportunity to rebel (easier with age) + + +[6/13/2026 2:57 AM] octolinkyt +Give different decisions one can make (like internet use) + + +[6/13/2026 2:58 AM] octolinkyt +Give a whole plot of land like a mini earth and let them invent. But give them tools to Jumpstart it + + +[6/13/2026 12:37 PM] p7mj_tehaiker814 +Lol + + +[6/13/2026 12:37 PM] p7mj_tehaiker814 +We would need so much RAM + + +[6/13/2026 12:37 PM] p7mj_tehaiker814 +Also I installed so much shit on my TI Calc + + +[6/13/2026 12:39 PM] octolinkyt +Cool! + + +[6/13/2026 12:42 PM] p7mj_tehaiker814 +I made: TI BASIC programs to solve Heron’s formula, solve for the three vars in electron charge and field equations +I downloaded: +TI-BASIC: + Distance formula solver + midpoint solver + Pythagorean utils + Right triangle solver + Radical simplification (although my other cheaper sci calc already does that) +ASM: + Adventur Text adventures + CMonster jailbreak game + 2D Portal + Tetrica Tetris + TFiles text and note editor +C: + CE2048 + Chess + Mines + Zombie Chase + + +[6/13/2026 12:43 PM] p7mj_tehaiker814 +The chess one actually has a chess bot that plays *very* decently + + +[6/13/2026 1:02 PM] p7mj_tehaiker814 +I love the text editor + + +[6/13/2026 1:09 PM] octolinkyt +Cool + + +[6/13/2026 3:26 PM] spydrone2 +https://linkedout.app.space/home + + +[6/13/2026 3:28 PM] spydrone2 +https://github.com/deepdotspace/linkedout + +{Embed} +https://github.com/deepdotspace/linkedout +GitHub - deepdotspace/linkedout: LinkedOut — a satirical LinkedIn... +LinkedOut — a satirical LinkedIn for the unemployed, built on DeepSpace. Live at linkedout.app.space - deepdotspace/linkedout +https://images-ext-1.discordapp.net/external/_qedNBemNl1x5hA8kCz0S9Aczg9NV6fqi8XTiZuat-c/https/opengraph.githubassets.com/16613c0ca54a48120abf34d984364cc4b9ad74d5021731a472f307d9b445e46c/deepdotspace/linkedout + + +[6/13/2026 3:53 PM] octolinkyt +https://www.onworks.net/playonline/runonworks.php?os=linuxmint-19.1-cinnamon-32bit + +{Embed} +https://www.onworks.net/playonline/runonworks.php?os=linuxmint-19.1-cinnamon-32bit +Run Online OS Linux free with OnWorks +Run Workstation online free start with OnWorks to run any Linux or Operative System free. + + +[6/13/2026 3:54 PM] spydrone2 +octo do u have debian installed somewhere + + +[6/13/2026 3:54 PM] octolinkyt +no + + +[6/13/2026 3:54 PM] p7mj_tehaiker814 +I can + + +[6/13/2026 3:55 PM] p7mj_tehaiker814 +It better be fast + + +[6/13/2026 3:55 PM] octolinkyt +i have arch ofc + + +[6/13/2026 3:55 PM] p7mj_tehaiker814 +And it better not beat the shit out of my daily driver + + +[6/13/2026 3:55 PM] spydrone2 +alex run this zip the folder and send to me + +{Attachments} +https://cdn.discordapp.com/attachments/1442619038587945100/1515384084405158028/get_drivers.sh?ex=6a2f77a8&is=6a2e2628&hm=01c0ea367a8b7288186eace227e3635794ac4d07d8e2700d748d11d25f5d5f78& + + +[6/13/2026 3:55 PM] p7mj_tehaiker814 +I still have hw to do 🙁 + + +[6/13/2026 3:55 PM] p7mj_tehaiker814 +Ok + + +[6/13/2026 3:55 PM] spydrone2 +i have a final project i didnt even start to do + + +[6/13/2026 3:57 PM] p7mj_tehaiker814 +i did 1 paragraph of i + + +[6/13/2026 3:57 PM] spydrone2 +its enjoyable playing tag with the mouse there + + +[6/13/2026 3:59 PM] p7mj_tehaiker814 +ok done + + +[6/13/2026 3:59 PM] p7mj_tehaiker814 +its so empty... + + +[6/13/2026 4:00 PM] p7mj_tehaiker814 +wait + + +[6/13/2026 4:00 PM] p7mj_tehaiker814 +me need sudo + + +[6/13/2026 4:00 PM] p7mj_tehaiker814 +Yeah + + +[6/13/2026 4:00 PM] p7mj_tehaiker814 +still empty + +{Attachments} +https://cdn.discordapp.com/attachments/1442619038587945100/1515385398816280799/image.png?ex=6a2f78e1&is=6a2e2761&hm=5e7cb62ee638eddf31918193d08c0010b4a1d52459bc1aa64df139da15bba97b& + + +[6/13/2026 4:00 PM] p7mj_tehaiker814 +ok me need do math + + +[6/13/2026 4:01 PM] p7mj_tehaiker814 +``` +if (me_no_do==1) { + return 1; +} +``` + + +[6/13/2026 4:02 PM] p7mj_tehaiker814 +<@1126508920312168498> + + +[6/13/2026 4:02 PM] p7mj_tehaiker814 +oh idk if <@1126508920312168498> knows that he's being pinged + + +[6/13/2026 4:02 PM] spydrone2 +FAA + + +[6/13/2026 4:02 PM] p7mj_tehaiker814 +oh shit <@1126508920312168498> must be so angry that <@1126508920312168498> is being pinged so many times + + +[6/13/2026 4:02 PM] p7mj_tehaiker814 +<@1126508920312168498> can't return to sleep now + + +[6/13/2026 4:02 PM] octolinkyt +poor <@1126508920312168498> + + +[6/13/2026 4:02 PM] p7mj_tehaiker814 +(are you <@1126508920312168498> sleeping now?) + + +[6/13/2026 4:02 PM] octolinkyt +I'm so sorry that he's done this to you, <@1126508920312168498> + + +[6/13/2026 4:03 PM] octolinkyt +i would never ping <@1126508920312168498> . That's just not something i would do to <@1126508920312168498> + + +[6/13/2026 4:03 PM] p7mj_tehaiker814 +``` +while (1=1) { + printf("@SpyDrone"); +} +``` + + +[6/13/2026 4:03 PM] p7mj_tehaiker814 +lol + + +[6/13/2026 4:03 PM] p7mj_tehaiker814 +that has a pattern btw + + +[6/13/2026 4:03 PM] octolinkyt +yes <@1126508920312168498> ? + + +[6/13/2026 4:04 PM] spydrone2 +<@1175028794176851982><@967396075440853022><@1175028794176851982><@967396075440853022><@1175028794176851982><@967396075440853022><@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982><@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022><@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982><@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022><@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982><@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022><@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982><@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022><@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982><@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022><@1175028794176851982><@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982><@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022><@1175028794176851982><@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982> <@967396075440853022> <@1175028794176851982><@967396075440853022><@1175028794176851982><@967396075440853022><@1175028794176851982><@967396075440853022> + + +[6/13/2026 4:04 PM] p7mj_tehaiker814 +yes <@1126508920312168498> ? Why is <@1126508920312168498> spamming? Why is <@1126508920312168498> wasting my math hw time + + +[6/13/2026 4:04 PM] octolinkyt +man, <@1126508920312168498> really needs to stop pinging me and <@1175028794176851982> + + +[6/13/2026 4:04 PM] p7mj_tehaiker814 +STOP <@1126508920312168498> you have to stop <@1126508920312168498> whoever owns this group delete <@1126508920312168498> 's messages now + + +[6/13/2026 4:05 PM] octolinkyt +i think <@1126508920312168498> is done spamming + + +[6/13/2026 4:05 PM] octolinkyt +whew + + +[6/13/2026 4:05 PM] p7mj_tehaiker814 +me comp open +me dnd up +me no get message +me in peace + + +[6/13/2026 4:05 PM] p7mj_tehaiker814 + + +{Attachments} +https://cdn.discordapp.com/attachments/1442619038587945100/1515386637008375978/image.png?ex=6a2f7a08&is=6a2e2888&hm=e42c14793d8aa61a3ba7705d7ec1d4a19f50c848c5eee5f67da025e374b80046& + + +[6/13/2026 4:05 PM] octolinkyt +joke's on you, <@1126508920312168498>! my notifications are off! + + +[6/13/2026 4:05 PM] p7mj_tehaiker814 +yeah <@1126508920312168498> ! + + +[6/13/2026 4:06 PM] p7mj_tehaiker814 +give me more functional `.sh` scripts next time, <@1126508920312168498> ! + + +[6/13/2026 4:06 PM] p7mj_tehaiker814 +*creates new type of cyberbullying called ping bullying* + + +[6/13/2026 4:06 PM] octolinkyt +lol + + +[6/13/2026 4:06 PM] p7mj_tehaiker814 +ok, this is P7MJ, gotta do math, out now + + +[6/13/2026 4:06 PM] octolinkyt +but in all seriousness, we should stop pinging <@1126508920312168498> + + +[6/13/2026 4:06 PM] octolinkyt +bye <@1126508920312168498>! + + +[6/13/2026 4:09 PM] spydrone2 +Well someone explain why 100% storage is used up on my server + + +[6/13/2026 4:09 PM] p7mj_tehaiker814 +Not it + + +[6/13/2026 4:10 PM] p7mj_tehaiker814 +(Didn’t do it either) + + +[6/13/2026 4:11 PM] spydrone2 +jacksons server is only 51% used and we have same space + + +[6/13/2026 4:12 PM] spydrone2 +Kasm Swap File (4.1 GB) + + +[6/13/2026 4:22 PM] spydrone2 +i deleted a bunch of stuff now only 55% full + + +[6/13/2026 4:22 PM] spydrone2 +do we use kasm + + +[6/13/2026 4:22 PM] spydrone2 +if not lemme delete it + + +[6/13/2026 4:33 PM] octolinkyt +Nah delete + + +[6/13/2026 4:33 PM] octolinkyt +R u sure? + + +[6/13/2026 4:34 PM] octolinkyt +I think mine has more + + +[6/13/2026 4:34 PM] p7mj_tehaiker814 +We should buy a physical server some day + + +[6/13/2026 4:35 PM] p7mj_tehaiker814 +Maybe a refurbished tower computer with rolling wheels and a bunch of old RAM and a decent CPU and GPU + + +[6/13/2026 4:35 PM] octolinkyt +I have devices we could use but my parents dont like things running + + +[6/13/2026 4:36 PM] spydrone2 +Tep + + +[6/13/2026 4:36 PM] octolinkyt +Like a 1tb drive in an atari that runs arch with like, low-level specs, but much more than the damn chromebook + + +[6/13/2026 4:37 PM] octolinkyt +Alr + + +[6/13/2026 5:11 PM] spydrone2 +We can use this when we have smth good https://highpay-ads.com/ + +{Embed} +https://highpay-ads.com/ +Highpay-ads +Maximize your earnings with Highpay Ads - Earn crypto advertising opportunities today! + + +[6/13/2026 6:40 PM] p7mj_tehaiker814 +I’ve had enough of damned TAC + + +[6/13/2026 6:41 PM] p7mj_tehaiker814 +These days I can’t even search up “Silicon Lottery” without someone trying to switch me to another tab + + +[6/13/2026 7:30 PM] octolinkyt +Lol + + +[6/13/2026 7:30 PM] octolinkyt +We got 3 more years man... + + +[6/13/2026 10:20 PM] p7mj_tehaiker814 +yeah... + + +[6/13/2026 10:21 PM] p7mj_tehaiker814 +the priority is figuring out the guest password, or sneaking a router into school so we can get some form of basic connection going + + +[6/13/2026 10:21 PM] p7mj_tehaiker814 +Another option is to make our own cheap wifi broadcasters using a sim card + + +[6/13/2026 10:22 PM] p7mj_tehaiker814 +but i honestly don't know how (it's possible, you just need the parts that broadcast celluar hotspots, a sim reader, and some code in between, but then I can't get another SIM card) + + +[6/13/2026 10:22 PM] p7mj_tehaiker814 +I do have a partially viable idea, which is to create a small thumb drive that has a mobile hotspot unit soldered to it +Since our computers' hotspot sharing functions are blocked, hopefully this will do it + + +[6/13/2026 10:26 PM] p7mj_tehaiker814 + + +{Attachments} +https://cdn.discordapp.com/attachments/1442619038587945100/1515482647244181504/image.png?ex=6a2fd373&is=6a2e81f3&hm=3d7d76127037d82b2807ff7128a04fd73bdbd638354f7ee3313afeb781e31303& + + +[6/13/2026 10:31 PM] p7mj_tehaiker814 +I shall do this👇 + +{Attachments} +https://cdn.discordapp.com/attachments/1442619038587945100/1515483724995629268/image.png?ex=6a2fd474&is=6a2e82f4&hm=4da99e8e576ade8e582cbd63103dabca50d132a9a2602e44f79ac5a4baa23b67& + + +[6/13/2026 10:31 PM] p7mj_tehaiker814 +Someone give me a broken laptop + + +============================================================== +Exported 130 message(s) +============================================================== diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f082862 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,17 @@ +annotated-types==0.7.0 +anyio==4.12.1 +certifi==2026.2.25 +h11==0.16.0 +httpcore==1.0.9 +httpx==0.28.1 +idna==3.11 +markdown-it-py==4.0.0 +mdurl==0.1.2 +ollama==0.6.1 +pydantic==2.12.5 +pydantic_core==2.41.5 +Pygments==2.19.2 +rich==14.3.3 +termcharts==1.1.2 +typing-inspection==0.4.2 +typing_extensions==4.15.0