@@ -4,6 +4,7 @@ const { PubSubClient } = require('@twurple/pubsub');
4
4
const { ApiClient } = require ( '@twurple/api' ) ;
5
5
const { EventSubWsListener } = require ( '@twurple/eventsub-ws' ) ;
6
6
const EventQueue = require ( './components/base/eventQueue' ) ;
7
+ const ollamaJs = require ( 'ollama' ) ;
7
8
8
9
const readline = require ( 'readline' ) ;
9
10
@@ -80,14 +81,54 @@ const performCustomCommand = (command, {type, coolDown, target}, botContext) =>
80
81
}
81
82
}
82
83
84
+ class OllamaClient {
85
+ constructor ( aiSettings ) {
86
+ this . aiSettings = aiSettings ;
87
+ this . messages = [ ] ;
88
+ this . client = new ollamaJs . Ollama ( { host : aiSettings . llmUrl } ) ;
89
+ }
90
+
91
+ setup = async ( setupPrompt ) => {
92
+ this . messages . push ( {
93
+ role : "system" ,
94
+ content : setupPrompt
95
+ } ) ;
96
+ await this . client . chat ( {
97
+ stream : false ,
98
+ model : this . aiSettings . llmModel ,
99
+ messages : this . messages
100
+ } ) ;
101
+ }
102
+
103
+ send = async ( username , message ) => {
104
+ this . messages . push ( {
105
+ role : "user" ,
106
+ content : `${ username } : ${ message } `
107
+ } ) ;
108
+ let response = await this . client . chat ( {
109
+ stream : false ,
110
+ model : this . aiSettings . llmModel ,
111
+ messages : this . messages
112
+ } ) ;
113
+ this . messages . push ( response . message ) ;
114
+ return response . message . content ;
115
+ }
116
+ }
117
+
83
118
// Define configuration options for chat bot
84
119
const startBot = async ( botConfig , selectedBotUser ) => {
85
120
try {
86
121
let { accessToken, clientId, twitchChannel, botUsers, devMode, broadcasterId} = botConfig ;
87
122
let botContext = { } ;
88
- let chatAccessToken = botUsers [ selectedBotUser ] . accessToken ;
123
+ let { accessToken : chatAccessToken , aiSettings} = botUsers [ selectedBotUser ] ;
124
+ let ollama ;
89
125
90
- console . log ( "STARTING BOT AS : " + selectedBotUser ) ;
126
+ if ( aiSettings && aiSettings . aiEnabled ) {
127
+ ollama = new OllamaClient ( aiSettings ) ;
128
+ ollama . setup ( `You are a chatter in a Twitch stream. The following is a description of your personality: "${ aiSettings . chatBotPersonalityPrompt } ". Every prompt after this one is a message from one of the other people in Twitch chat preceded by their name. When you reply you do not need to append your username to the beginning of your response.` )
129
+ }
130
+
131
+ console . log ( "STARTING A BOT AS : " + selectedBotUser ) ;
91
132
92
133
let plugins = [ deathCounterPlugin , requestPlugin , cameraObscura , modTools ] ;
93
134
@@ -142,6 +183,9 @@ const startBot = async (botConfig, selectedBotUser) => {
142
183
console . error ( e . message + ": " + e . stack ) ;
143
184
EventQueue . sendErrorToChat ( new Error ( e ) ) ;
144
185
}
186
+ } else if ( command . includes ( selectedBotUser ) ) {
187
+ let response = await ollama . send ( context . username , command ) ;
188
+ EventQueue . sendInfoToChat ( response ) ;
145
189
}
146
190
}
147
191
@@ -254,15 +298,14 @@ const startBot = async (botConfig, selectedBotUser) => {
254
298
onMessageHandler ( channel , { username, id : "" } , message ) ;
255
299
} ) ;
256
300
client . onConnect ( onConnectedHandler ) ;
257
- client . onRaid ( ( channel , username , { viewerCount} ) => { onRaid ( channel , username , viewerCount ) } ) ;
258
-
259
- let subListener = await pubSubClient . onSubscription ( broadcasterId , onSubscription ) ;
260
- let cheerListener = await pubSubClient . onBits ( broadcasterId , onBits ) ;
261
- let redemptionListener = await pubSubClient . onRedemption ( broadcasterId , onRedemption ) ;
262
301
263
- eventListener . onChannelFollow ( broadcasterId , broadcasterId , onFollow ) ;
302
+ let followListener = eventListener . onChannelFollow ( broadcasterId , broadcasterId , onFollow ) ;
303
+ let raidListener = eventListener . onChannelRaidTo ( broadcasterId , ( { raidingBroadcasterName, viewers} ) => onRaid ( twitchChannel , raidingBroadcasterName , viewers ) ) ;
304
+ let redemptionListener = eventListener . onChannelRedemptionAdd ( broadcasterId , onRedemption ) ;
305
+ let subListener = eventListener . onChannelSubscription ( broadcasterId , onSubscription ) ;
306
+ let cheerListener = eventListener . onChannelCheer ( broadcasterId , onBits ) ;
264
307
265
- listeners = [ subListener , cheerListener , redemptionListener ] ;
308
+ listeners = [ subListener , cheerListener , redemptionListener , followListener , raidListener ] ;
266
309
267
310
// Connect to twitch chat and pubsub
268
311
await client . connect ( ) ;
@@ -277,7 +320,11 @@ const stopBot = () => {
277
320
EventQueue . stopEventListener ( ) ;
278
321
client . quit ( ) ;
279
322
listeners . forEach ( ( listener ) => {
280
- listener . remove ( ) ;
323
+ if ( listener . remove ) {
324
+ listener . remove ( ) ;
325
+ } else if ( listener . stop ) {
326
+ listener . stop ( ) ;
327
+ }
281
328
} ) ;
282
329
} ;
283
330
0 commit comments