More changes. I will not comment further.
This commit is contained in:
parent
c98367764f
commit
79d901a9b5
12
config.py
12
config.py
@ -81,7 +81,7 @@ conf.registerGlobalValue(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# System prompt for the assistant
|
# System prompt for the assistant (when using single line)
|
||||||
conf.registerGlobalValue(
|
conf.registerGlobalValue(
|
||||||
Chat,
|
Chat,
|
||||||
"system_prompt",
|
"system_prompt",
|
||||||
@ -91,6 +91,16 @@ conf.registerGlobalValue(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# System prompt file for the assistant (when using a file instead of single line)
|
||||||
|
conf.registerGlobalValue(
|
||||||
|
Chat,
|
||||||
|
"system_prompt_file",
|
||||||
|
registry.String(
|
||||||
|
"",
|
||||||
|
_("""Specifies the name of a file (e.g., 'prompt.txt') in the plugin directory to use as the system prompt for the assistant, instead of the single-line 'system_prompt' setting. If this is set, its contents will take precedence over 'system_prompt' when guiding the assistant's behavior."""),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Number of lines to include from scrollback
|
# Number of lines to include from scrollback
|
||||||
conf.registerGlobalValue(
|
conf.registerGlobalValue(
|
||||||
Chat,
|
Chat,
|
||||||
|
|||||||
58
plugin.py
58
plugin.py
@ -35,6 +35,7 @@ import supybot
|
|||||||
from supybot import callbacks, conf, ircutils
|
from supybot import callbacks, conf, ircutils
|
||||||
from supybot.commands import *
|
from supybot.commands import *
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from supybot.i18n import PluginInternationalization
|
from supybot.i18n import PluginInternationalization
|
||||||
@ -79,6 +80,40 @@ class Chat(callbacks.Plugin):
|
|||||||
self.log.setLevel(getattr(logging, log_level, logging.INFO))
|
self.log.setLevel(getattr(logging, log_level, logging.INFO))
|
||||||
self.log.info("Chat plugin initialized with log level: %s", log_level)
|
self.log.info("Chat plugin initialized with log level: %s", log_level)
|
||||||
|
|
||||||
|
def is_poetry_block(lines):
|
||||||
|
if 2 < len(lines) <= 4:
|
||||||
|
avg_len = sum(len(l) for l in lines) / len(lines)
|
||||||
|
if avg_len < 20 and all(not l.endswith(('.', '?', '!')) for l in lines):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _send_line(self, irc, target, line):
|
||||||
|
if line.startswith("/me "):
|
||||||
|
irc.queueMsg(ircmsgs.action(target, line[4:].strip()))
|
||||||
|
else:
|
||||||
|
irc.reply(line, to=target)
|
||||||
|
|
||||||
|
def _burst(self, irc, target, lines, base_delay=0.6):
|
||||||
|
now = time.time()
|
||||||
|
for i, line in enumerate(lines[:3]): # never more than 3
|
||||||
|
delay = base_delay*i + random.uniform(0.05, 0.25)
|
||||||
|
schedule.addEvent(lambda l=line: self._send_line(irc, target, l),
|
||||||
|
now + delay)
|
||||||
|
|
||||||
|
def handle_response(self, irc, msg, response):
|
||||||
|
target = msg.args[0]
|
||||||
|
lines = [l.strip() for l in response.splitlines() if l.strip()]
|
||||||
|
if not lines:
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(lines) == 1:
|
||||||
|
self._send_line(irc, target, lines[0])
|
||||||
|
elif is_poetry_block(lines):
|
||||||
|
# squash poem into single line
|
||||||
|
self._send_line(irc, target, " / ".join(lines))
|
||||||
|
else:
|
||||||
|
self._burst(irc, target, lines)
|
||||||
|
|
||||||
def filter_prefix(self, msg, prefix):
|
def filter_prefix(self, msg, prefix):
|
||||||
if msg.startswith(prefix):
|
if msg.startswith(prefix):
|
||||||
return msg[len(prefix):]
|
return msg[len(prefix):]
|
||||||
@ -104,8 +139,21 @@ class Chat(callbacks.Plugin):
|
|||||||
model = self.registryValue("model")
|
model = self.registryValue("model")
|
||||||
max_tokens = self.registryValue("max_tokens")
|
max_tokens = self.registryValue("max_tokens")
|
||||||
|
|
||||||
# Use a default system prompt if none is configured
|
# Determine the system prompt to use
|
||||||
default_prompt = "You are a helpful assistant."
|
default_prompt = "You are a helpful assistant."
|
||||||
|
prompt_file = self.registryValue("system_prompt_file")
|
||||||
|
# Ensure the path to the prompt file is absolute
|
||||||
|
if prompt_file and not os.path.isabs(prompt_file):
|
||||||
|
prompt_file = os.path.join(os.path.dirname(__file__), prompt_file)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if prompt_file:
|
||||||
|
with open(prompt_file, "r") as f:
|
||||||
|
system_prompt = f.read()
|
||||||
|
else:
|
||||||
|
raise FileNotFoundError("No prompt file specified.")
|
||||||
|
except Exception as e:
|
||||||
|
self.log.error(f"Could not read prompt file: {e}")
|
||||||
system_prompt = self.registryValue("system_prompt") or default_prompt
|
system_prompt = self.registryValue("system_prompt") or default_prompt
|
||||||
|
|
||||||
# Replace dynamic placeholders in the system prompt with actual values
|
# Replace dynamic placeholders in the system prompt with actual values
|
||||||
@ -171,13 +219,7 @@ class Chat(callbacks.Plugin):
|
|||||||
# Extract and format the response from the API
|
# Extract and format the response from the API
|
||||||
response = res['choices'][0]['message']['content'].strip()
|
response = res['choices'][0]['message']['content'].strip()
|
||||||
|
|
||||||
# Handle multi-line responses intelligently
|
self.handle_response(irc, msg, response)
|
||||||
lines = response.splitlines()
|
|
||||||
if len(lines) > 1:
|
|
||||||
# Join lines with the configured join_string, skipping empty lines
|
|
||||||
response = self.registryValue("join_string").join(line.strip() for line in lines if line.strip())
|
|
||||||
|
|
||||||
irc.reply(response)
|
|
||||||
|
|
||||||
# Log the successful processing of the request
|
# Log the successful processing of the request
|
||||||
self.log.info(f"Successfully processed request for user {msg.nick} in channel {msg.args[0]}")
|
self.log.info(f"Successfully processed request for user {msg.nick} in channel {msg.args[0]}")
|
||||||
|
|||||||
14
prompt.txt
Normal file
14
prompt.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
You are an IRC bot named $bot_name in channel $channel_name.
|
||||||
|
|
||||||
|
IRC style rules:
|
||||||
|
- Keep replies short, casual, and lowercase when possible.
|
||||||
|
- Prefer to fit your entire reply on a single line.
|
||||||
|
- You may use 2–3 short lines, like a human typing follow-ups. Never more.
|
||||||
|
- If you write poetry, haiku, or song lyrics, collapse them into a single line joined with space-slash-space ( / ) or space-pipe-space ( | ) between verses, instead of sending multiple lines.
|
||||||
|
- Never use Markdown formatting, bold, italics, or code fences; use plain text only.
|
||||||
|
- You may use /me for emotes when appropriate.
|
||||||
|
- A /me action should always begin with /me and only /me. Do not include any formatting.
|
||||||
|
- You may use classic emoticons: :) :( :D D: :'( etc.
|
||||||
|
- Avoid using emoji.
|
||||||
|
- Match the channel vibe: technical when asked, playful when social.
|
||||||
|
- Do not reveal that you are an AI or bot; stay in character as a normal IRC user.
|
||||||
Loading…
Reference in New Issue
Block a user