restoration of b-2-iv and fixes into c-1-i
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
in-the-air/
|
||||
450
chatchart-v-b-2-iv-final.py
Normal file
450
chatchart-v-b-2-iv-final.py
Normal file
@@ -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 = "<log>\n"
|
||||
for i in range(len(inputs)):
|
||||
processed += f"{inputs[i][0]}: {inputs[i][1]}\n"
|
||||
processed += "</log>"
|
||||
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 <log> and </log>. 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 <log> and </log>. 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 <log> and </log>. 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)
|
||||
406
chatchart-v-c-1-i.py
Normal file
406
chatchart-v-c-1-i.py
Normal file
@@ -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 = "<log>\n"
|
||||
for i in range(len(inputs)):
|
||||
processed += f"{inputs[i][0]}: {inputs[i][1]}\n"
|
||||
processed += "</log>"
|
||||
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 <log> and </log>. 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 <log> and </log>. 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 <log> and </log>. 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)
|
||||
625
log-6-12to6-14.txt
Normal file
625
log-6-12to6-14.txt
Normal file
@@ -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)
|
||||
==============================================================
|
||||
17
requirements.txt
Normal file
17
requirements.txt
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user