@@ -2037,9 +2037,39 @@ function checkTriggerWords(triggerString, sentence) {
20372037}
20382038
20392039let isProcessing = false ;
2040+ let activeBotResponseCount = 0 ;
20402041const lastResponseTime = { } ;
20412042// lastSentMessage is already declared in background.js
20422043
2044+ function getMaxParallelBotResponses ( ) {
2045+ const configured = settings ?. ollamaMaxParallelAgents ?. numbersetting ;
2046+ let maxParallel = parseInt ( configured , 10 ) ;
2047+ if ( ! Number . isFinite ( maxParallel ) || maxParallel < 1 ) {
2048+ maxParallel = 1 ;
2049+ }
2050+ return Math . min ( maxParallel , 10 ) ;
2051+ }
2052+
2053+ function reserveBotResponseSlot ( data ) {
2054+ const maxParallel = getMaxParallelBotResponses ( ) ;
2055+ if ( isProcessing && activeBotResponseCount === 0 ) {
2056+ noteChatBotDecision ( 'busy' , data ) ;
2057+ return false ;
2058+ }
2059+ if ( activeBotResponseCount >= maxParallel ) {
2060+ noteChatBotDecision ( 'parallel-limit' , data , { active : activeBotResponseCount , max : maxParallel } ) ;
2061+ return false ;
2062+ }
2063+ activeBotResponseCount += 1 ;
2064+ isProcessing = true ;
2065+ return true ;
2066+ }
2067+
2068+ function releaseBotResponseSlot ( ) {
2069+ activeBotResponseCount = Math . max ( 0 , activeBotResponseCount - 1 ) ;
2070+ isProcessing = activeBotResponseCount > 0 ;
2071+ }
2072+
20432073const hostReflectionTracker = new Map ( ) ;
20442074const HOST_REFLECTION_TTL_MS = 20 * 1000 ; // mirror duplicate reflection window
20452075
@@ -2119,13 +2149,11 @@ async function processMessageWithOllama(data, idx=null) {
21192149 if ( ! data . tid ) return ;
21202150
21212151 const currentTime = Date . now ( ) ;
2122- if ( isProcessing ) return ;
2152+ if ( ! reserveBotResponseSlot ( data ) ) return ;
21232153
21242154 //console.log("starting processing");
2125- isProcessing = true ;
21262155 try {
21272156 if ( data ?. bot ) {
2128- isProcessing = false ;
21292157 noteChatBotDecision ( 'ignored-bot-message' , data ) ;
21302158 return ;
21312159 }
@@ -2135,9 +2163,8 @@ async function processMessageWithOllama(data, idx=null) {
21352163 if ( settings . ollamaRateLimitPerTab ) {
21362164 ollamaRateLimitPerTab = Math . max ( 0 , parseInt ( settings . ollamaRateLimitPerTab . numbersetting ) || 0 ) ;
21372165 }
2138-
2166+
21392167 if ( data . type !== "stageten" && ! settings . ollamaoverlayonly && data . tid && lastResponseTime [ data . tid ] && ( currentTime - lastResponseTime [ data . tid ] < ollamaRateLimitPerTab ) ) {
2140- isProcessing = false ;
21412168 const waitMs = Math . max ( 0 , ollamaRateLimitPerTab - ( currentTime - lastResponseTime [ data . tid ] ) ) ;
21422169 noteChatBotDecision ( 'rate-limited' , data , { waitMs } ) ;
21432170 return ;
@@ -2148,10 +2175,9 @@ async function processMessageWithOllama(data, idx=null) {
21482175 if ( settings . ollamabotname ?. textsetting ) {
21492176 botname = settings . ollamabotname . textsetting . trim ( ) ;
21502177 }
2151-
2152- // Early return conditions
2178+
2179+ // Early return conditions
21532180 if ( ( data . type === "stageten" && botname === data . chatname ) || ! data . chatmessage || ( ! settings . noollamabotname && data . chatmessage . startsWith ( botname + ":" ) ) ) {
2154- isProcessing = false ;
21552181 noteChatBotDecision ( 'ignored-self-message' , data ) ;
21562182 return ;
21572183 }
@@ -2163,21 +2189,18 @@ async function processMessageWithOllama(data, idx=null) {
21632189 ) ;
21642190
21652191 if ( data ?. chatbotReflection ) {
2166- isProcessing = false ;
21672192 noteChatBotDecision ( 'ignored-chatbot-reflection' , data ) ;
21682193 return ;
21692194 }
21702195
21712196 if ( data ?. reflection && ! allowHostReflectionResponse ) {
2172- isProcessing = false ;
21732197 noteChatBotDecision ( 'ignored-reflection' , data , { origin : data ?. reflectionOrigin || '' } ) ;
21742198 return ;
21752199 }
21762200
21772201 // Trigger words check
21782202 if ( settings . bottriggerwords ?. textsetting . trim ( ) ) { // bottriggerwords
21792203 if ( ! checkTriggerWords ( settings . bottriggerwords . textsetting , data . chatmessage ) ) {
2180- isProcessing = false ;
21812204 noteChatBotDecision ( 'missing-trigger' , data ) ;
21822205 return ;
21832206 }
@@ -2194,9 +2217,8 @@ async function processMessageWithOllama(data, idx=null) {
21942217 . replace ( / [ \r \n ] + / g, "" )
21952218 . replace ( / \s + / g, " " )
21962219 . trim ( ) ;
2197-
2220+
21982221 if ( ! cleanedText ) {
2199- isProcessing = false ;
22002222 noteChatBotDecision ( 'empty-after-cleaning' , data ) ;
22012223 return ;
22022224 }
@@ -2206,7 +2228,6 @@ async function processMessageWithOllama(data, idx=null) {
22062228 hostReflectionKey = getHostReflectionKey ( data , cleanedText ) ;
22072229 pruneHostReflectionTracker ( ) ;
22082230 if ( hostReflectionKey && hostReflectionTracker . has ( hostReflectionKey ) ) {
2209- isProcessing = false ;
22102231 noteChatBotDecision ( 'reflection-already-handled' , data ) ;
22112232 return ;
22122233 }
@@ -2215,7 +2236,6 @@ async function processMessageWithOllama(data, idx=null) {
22152236 if ( ! allowHostReflectionResponse ) {
22162237 const score = fastMessageSimilarity ( cleanedText , lastSentMessage ) ;
22172238 if ( score > 0.5 ) {
2218- isProcessing = false ;
22192239 noteChatBotDecision ( 'too-similar-to-last-reply' , data ) ;
22202240 return ;
22212241 }
@@ -2306,7 +2326,7 @@ async function processMessageWithOllama(data, idx=null) {
23062326 } catch ( error ) {
23072327 console . warn ( "Error processing message:" , error ) ;
23082328 } finally {
2309- isProcessing = false ;
2329+ releaseBotResponseSlot ( ) ;
23102330 }
23112331}
23122332
0 commit comments