From fb408c3c1e21c78853670ce42e543c93b65f371f Mon Sep 17 00:00:00 2001 From: Brett Date: Sun, 29 Jun 2025 12:17:11 -0400 Subject: [PATCH] stupid ai --- news/__pycache__/pool.cpython-312.pyc | Bin 0 -> 12525 bytes news/main.py | 153 ++++++++++++++++++-------- news/shell.nix | 51 +++++++++ 3 files changed, 157 insertions(+), 47 deletions(-) create mode 100644 news/__pycache__/pool.cpython-312.pyc create mode 100644 news/shell.nix diff --git a/news/__pycache__/pool.cpython-312.pyc b/news/__pycache__/pool.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6efef44e2dcfede381923fbf1000c5b610f704f GIT binary patch literal 12525 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 None: fp = io.BytesIO(content.encode("utf-8")) file = discord.File(fp, filename=filename) await channel.send(message, file=file) +def tally_responses(tools): + increment = 0 + decrement = 0 + if tools: + for tool in tools: + if tool['function']['name'] == "increment": + increment += 1 + elif tool['function']['name'] == "decrement": + decrement += 1 + else: + LOGGER.warning(f"Unknown tool: {tool}") + return increment, decrement + async def handle_article_url(message: discord.Message, url: str) -> None: - """ - Placeholder: download + analyse the article here. - - Currently just acknowledges receipt so you can verify the event flow. - """ LOGGER.info("Received URL from %s: %s", message.author, url) try: title, processed_html = await article_repository.get_article(url) - paragraphs = processed_html.split("\n") - paragraphs = [f"\"Paragraph ({i + 1})\": {paragraph.strip()}" for i, paragraph in enumerate(paragraphs)] - processed_graphs = [{"role": "user", "content": paragraph} for paragraph in paragraphs] - # print(paragraphs) - # print(processed_graphs) - # messages = [ - # {"role": "system", "content": "You are an expert article-analysis assistant." - # # "You WILL respond in JSON format." - # "Your job is to analyse paragraphs in the article and look for provocative, emotionally charged, and loaded language" - # "You WILL analyse the paragraphs, determine if they are provocative, and if so, output a rating between 1 and 100, 100 being the most provocative." - # "you WILL NOT output a summary of the article or the paragraphs." - # "Questions you should ask yourself while reading the paragraph:" - # "1. What is the literal meaning of the questionable word or phrase?" - # "2. What is the emotional or social context of the questionable word or phrase?" - # "3. Does that word or phrase have any connotations, that is, associations that are positive or negative?" - # "4. What group (sometimes called a “discourse community”) favors one locution over another, and why?" - # "5. Is the word or phrase “loaded”? How far does it steer us from neutral?" - # "6. Does the word or phrase help me see, or does it prevent me from seeing? (This is important)" - # "You will now be provided with the headline of the article then a paragraph from the article." - # "The headline (title of the page) will be provided as \"Headline\": \"EXAMPLE HEADLINE\"." - # "The paragraphs will be provided as \"Paragraph (numbered index)\": \"EXAMPLE PARAGRAPH\"."}, - # {"role": "user", "content": f"\"Headline\": \"{title}\""} - # ] - # messages.extend(processed_graphs) - social = await send_chat("social", processed_html) - capital = await send_chat("capital", processed_html) - facts = await send_chat("facts", processed_html) + tools = [ + { + 'type': 'function', + 'function': { + 'name': 'increment', + 'description': 'increment internal counter by 1', + 'parameters': { + 'type': 'object', + 'properties': {}, + 'required': [] + } + } + }, + { + 'type': 'function', + 'function': { + 'name': 'decrement', + 'description': 'decrement internal counter by 1', + 'parameters': { + 'type': 'object', + 'properties': {}, + 'required': [] + } + } + } + ] + + social = await send_chat_with_system("social", processed_html, social_system_prompt, tools) + capital = await send_chat_with_system("capital", processed_html, capital_system_prompt, tools) + facts = await send_chat_with_system("facts", processed_html, facts_system_prompt, tools) + print(social) print(capital) print(facts) + + social_increment, social_decrement = tally_responses(social['message']["tool_calls"]) + capital_increment, capital_decrement = tally_responses(capital['message']["tool_calls"]) + facts_increment, facts_decrement = tally_responses(facts['message']["tool_calls"]) + # TODO: parse `html`, summarise, etc. await message.channel.send(f"✅ Article downloaded – {len(processed_html):,} bytes.") + time.sleep(0.1) await send_text_file(message.channel, processed_html) - await send_text_file(message.channel, social.response, "Social calculations:") - await send_text_file(message.channel, capital.response, "capital calculations:") - await send_text_file(message.channel, facts.response, "facts calculations:") + time.sleep(0.1) + await send_text_file(message.channel, social["message"]["content"], "Social calculations:") + time.sleep(0.1) + await message.channel.send(f"Social+ {social_increment} | Social- {social_decrement}") + time.sleep(0.1) + await send_text_file(message.channel, capital["message"]["content"], "capital calculations:") + time.sleep(0.1) + await message.channel.send(f"Capital+ {capital_increment} | Capital- {capital_decrement}") + time.sleep(0.1) + await send_text_file(message.channel, facts["message"]["content"], "facts calculations:") + time.sleep(0.1) + await message.channel.send(f"Facts+ {facts_increment} | Facts- {facts_decrement}") + time.sleep(0.1) except Exception as exc: await message.channel.send("❌ Sorry, an internal error has occurred. Please try again later or contact an administrator.") await message.channel.send(f"```\n{exc}\n```") + LOGGER.error(exc, exc_info=True) def extract_first_url(text: str) -> Optional[str]: diff --git a/news/shell.nix b/news/shell.nix new file mode 100644 index 0000000..b1d1be1 --- /dev/null +++ b/news/shell.nix @@ -0,0 +1,51 @@ +let + pkgs = import {}; +in pkgs.mkShell { + packages = with pkgs; [ + (python3.withPackages (python-pkgs: with python-pkgs; [ + ollama + requests + discordpy + python-dotenv + trafilatura + playwright + ])) + ]; + propagatedBuildInputs = with pkgs; [ + xorg.libX11 + xorg.libX11.dev + xorg.libXcursor + xorg.libXcursor.dev + xorg.libXext + xorg.libXext.dev + xorg.libXinerama + xorg.libXinerama.dev + xorg.libXrandr + xorg.libXrandr.dev + xorg.libXrender + xorg.libXrender.dev + xorg.libxcb + xorg.libxcb.dev + xorg.libXi + xorg.libXi.dev + harfbuzz + harfbuzz.dev + zlib + zlib.dev + bzip2 + bzip2.dev + pngpp + brotli + brotli.dev + pulseaudio.dev + git + libGL + libGL.dev + glfw + ]; + LD_LIBRARY_PATH="/run/opengl-driver/lib:/run/opengl-driver-32/lib"; + shellHook = '' + export PLAYWRIGHT_BROWSERS_PATH=${pkgs.playwright-driver.browsers} + export PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=true + ''; +} \ No newline at end of file