Skip to content

Commit f5b3fbc

Browse files
authored
Merge pull request #817 from steveseguin/beta
Beta
2 parents 22c09d1 + ba70578 commit f5b3fbc

33 files changed

Lines changed: 3585 additions & 516 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ tests/cohost-customopenai*.playwright.js
2424

2525
# Generated benchmark/stress outputs
2626
tests/artifacts/
27+
tmp/

ai.js

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,9 +2037,39 @@ function checkTriggerWords(triggerString, sentence) {
20372037
}
20382038

20392039
let isProcessing = false;
2040+
let activeBotResponseCount = 0;
20402041
const 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+
20432073
const hostReflectionTracker = new Map();
20442074
const 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

Comments
 (0)