Skip to content

Commit 0e021b6

Browse files
committed
New script ollama_bot.py: Adds non-blocking API calls using hook_process_hashtable()
1 parent 0fe640a commit 0e021b6

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

python/ollama.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import weechat
2+
import json
3+
4+
"""
5+
Ollama Bot for WeeChat (Non-blocking version)
6+
7+
This script automatically responds to mentions in channels and private messages using an Ollama LLM running locally.
8+
9+
Features:
10+
- Responds to mentions in channels.
11+
- Can respond to private messages if enabled.
12+
- Allows manual queries using the /ollama command.
13+
- Configurable via WeeChat /set commands.
14+
- Uses hook_url for non-blocking HTTP requests.
15+
16+
Usage:
17+
- To ask a question manually:
18+
/ollama What is Python?
19+
20+
- To enable or disable automatic responses in channels:
21+
/set plugins.var.python.ollama.highlight_response on # Enable responses in channels
22+
/set plugins.var.python.ollama.highlight_response off # Disable responses in channels
23+
24+
- To enable or disable automatic responses in private messages:
25+
/set plugins.var.python.ollama.pm_response on # Enable PM responses
26+
/set plugins.var.python.ollama.pm_response off # Disable PM responses
27+
28+
Dependencies:
29+
- Requires an Ollama server running locally at http://localhost:11434/api/generate
30+
"""
31+
32+
# Script metadata
33+
SCRIPT_NAME = "ollama"
34+
SCRIPT_AUTHOR = "teraflops"
35+
SCRIPT_VERSION = "2.1"
36+
SCRIPT_LICENSE = "MIT"
37+
SCRIPT_DESC = "Automatically responds to mentions using Ollama and allows manual queries, including PMs"
38+
OLLAMA_API_URL = "http://localhost:11434/api/generate"
39+
40+
# Register the script
41+
weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", "")
42+
43+
# Script configuration in Weechat
44+
def setup_config():
45+
if not weechat.config_is_set_plugin("highlight_response"):
46+
weechat.config_set_plugin("highlight_response", "on") # Enable auto-responses by default
47+
if not weechat.config_is_set_plugin("pm_response"):
48+
weechat.config_set_plugin("pm_response", "off") # Disable PM responses by default
49+
setup_config()
50+
51+
def fetch_ollama(data, command, return_code, out, err):
52+
"""Callback function that handles the response from Ollama."""
53+
if return_code == 0:
54+
response = json.loads(out).get("response", "No response received from Ollama.")
55+
weechat.prnt("", response) # Print the response in the chat
56+
else:
57+
weechat.prnt("", f"Error fetching Ollama response: {err}")
58+
59+
def ask_ollama(message):
60+
"""Send a query to Ollama using hook_url (non-blocking)."""
61+
data = json.dumps({"model": "gemma", "prompt": message, "stream": False})
62+
headers = "Content-Type: application/json"
63+
64+
weechat.hook_process_hashtable(
65+
"url:fetch",
66+
{"url": OLLAMA_API_URL, "type": "post", "data": data, "headers": headers},
67+
60000, # Timeout in milliseconds (60 seconds)
68+
"fetch_ollama",
69+
""
70+
)
71+
72+
def command_ollama(data, buffer, args):
73+
"""Command /ollama to manually ask Ollama a question."""
74+
if not args:
75+
weechat.prnt(buffer, "Usage: /ollama <question>")
76+
return weechat.WEECHAT_RC_OK
77+
78+
ask_ollama(args)
79+
return weechat.WEECHAT_RC_OK
80+
81+
def message_callback(data, buffer, date, tags, displayed, highlight, prefix, message):
82+
"""Detect mentions in channels or private messages and respond automatically with Ollama."""
83+
84+
if weechat.config_get_plugin("highlight_response") == "off":
85+
return weechat.WEECHAT_RC_OK
86+
87+
buffer_type = weechat.buffer_get_string(buffer, "localvar_type")
88+
is_private = buffer_type == "private"
89+
username = weechat.info_get("irc_nick", "") # Get the current IRC username
90+
is_mentioned = f"@{username.lower()}" in message.lower() # Ensure @username is explicitly mentioned
91+
92+
# Ignore private messages if pm_response is off
93+
if is_private and weechat.config_get_plugin("pm_response") == "off":
94+
return weechat.WEECHAT_RC_OK
95+
96+
# Only respond in private messages if it's a direct question
97+
if is_private and not message.strip().endswith("?"):
98+
return weechat.WEECHAT_RC_OK
99+
100+
# Only respond in channels if explicitly mentioned or highlighted
101+
if not is_private and not is_mentioned and not int(highlight):
102+
return weechat.WEECHAT_RC_OK
103+
104+
ask_ollama(message)
105+
return weechat.WEECHAT_RC_OK
106+
107+
def config_callback(data, option, value):
108+
"""Callback for Weechat configuration changes."""
109+
weechat.prnt("", f"Configuration changed: {option} = {value}")
110+
return weechat.WEECHAT_RC_OK
111+
112+
# Register configuration with /set
113+
weechat.config_set_desc_plugin("highlight_response", "Automatically respond to mentions in channels (on/off)")
114+
weechat.config_set_desc_plugin("pm_response", "Automatically respond to private messages (on/off)")
115+
weechat.hook_config("plugins.var.python.ollama.highlight_response", "config_callback", "")
116+
weechat.hook_config("plugins.var.python.ollama.pm_response", "config_callback", "")
117+
118+
# Register commands and hooks
119+
weechat.hook_command("ollama", "Ask something to Ollama", "<question>", "Example: /ollama What is Python?", "", "command_ollama", "")
120+
weechat.hook_print("", "notify_highlight", "", 1, "message_callback", "")
121+
weechat.hook_print("", "notify_message", "", 1, "message_callback", "")
122+
weechat.hook_print("", "notify_private", "", 1, "message_callback", "")
123+

0 commit comments

Comments
 (0)