fix(files): force a final answer before tool cutoff

This commit is contained in:
Mikei386
2026-08-24 07:12:15 +02:00
parent c3121281de
commit b997fcb9f7
4 changed files with 57 additions and 4 deletions
+33
View File
@@ -159,6 +159,39 @@ class StabilityGuardTests(unittest.IsolatedAsyncioTestCase):
["execute_code"],
)
async def test_private_csv_stops_before_openwebui_hard_tool_limit(self):
calls = []
for index in range(6):
calls.extend(
[
{
"role": "assistant",
"tool_calls": [
{
"function": {
"name": "execute_code",
"arguments": '{"code":"step %d"}' % index,
}
}
],
},
{"role": "tool", "content": "ok", "tool_call_id": str(index)},
]
)
body = {
"model": "qwen-fast",
"tools": [
{"type": "function", "function": {"name": "execute_code"}},
],
"messages": [
{"role": "user", "content": "Werte diese CSV aus."},
*calls,
],
}
result = await self.guard.inlet(body)
self.assertEqual(result["tools"], [])
self.assertIn("vorhandenen Ergebnisse", result["messages"][0]["content"])
class AutoToolSelectorTests(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
+5 -1
View File
@@ -25,7 +25,11 @@ benötigte deshalb kleinere, klarere Werkzeuge und harte Abbruchgrenzen.
Webwerkzeug-Injektion. Vor `pandas.read_csv` werden Rohvorschau, Kodierung,
Trennzeichen, Kopfzeile, Metadatenzeilen, Dezimal- und Datumsformat erkannt;
damit führen deutsche Bankexporte nicht mehr unnötig zuerst zu einem
ParserError wegen einer falschen Spaltenzahl.
ParserError wegen einer falschen Spaltenzahl. Tabellenanalysen sollen im
Regelfall mit einer Erkennungs- und einer Auswertungsrunde auskommen. Nach
sechs lokalen Dateiaufrufen erzwingt der Guard eine werkzeugfreie
Abschlussantwort, bevor OpenWebUI bei seiner harten Zwölf-Runden-Grenze
ohne sichtbares Ergebnis abbricht.
4. Pro Antwort sind höchstens zwölf Werkzeugrunden erlaubt. Der zweite
identische Aufruf wird gestoppt. Ein einzelnes Resultat ist auf 10.000, alle
Resultate zusammen auf 36.000 Zeichen begrenzt.
+16 -3
View File
@@ -1,7 +1,7 @@
"""
title: MikeAI Stability Guard
author: MikeAI
version: 2.0.0
version: 2.1.0
description: Bounds tool output and context use and breaks repeated tool-call loops.
"""
@@ -29,7 +29,11 @@ class Filter:
max_total_tool_chars: int = 36000
compacted_tool_chars: int = 2000
duplicate_tool_call_limit: int = 2
max_tool_calls_per_turn: int = 12
# OpenWebUI itself stops after twelve rounds without giving the model
# another completion. Stay below that ceiling so the model still gets
# a final, tool-free turn.
max_tool_calls_per_turn: int = 10
max_private_table_tool_calls: int = 6
def __init__(self):
self.valves = self.Valves()
@@ -149,7 +153,11 @@ class Filter:
"pandas.read_csv(path, sep=None, engine='python') for discovery, then parse "
"again with explicit verified parameters. Compute exact aggregates, validate "
"that totals reconcile, and always return a visible final answer or a clear "
"local parsing error."
"local parsing error. Consolidate discovery and calculation into as few code "
"calls as possible: normally one preview/dialect call and one complete analysis "
"call. After one failed parse, use its error to correct the next call instead "
"of repeatedly searching the filesystem. Never spend more than four code calls "
"on a table unless the user explicitly requests debugging."
)
messages = body.setdefault("messages", [])
for message in messages:
@@ -339,6 +347,11 @@ class Filter:
breaker_reason = None
if duplicate >= self.valves.duplicate_tool_call_limit:
breaker_reason = f"derselbe Aufruf wurde {duplicate}-mal wiederholt"
elif private_table and len(signatures) >= self.valves.max_private_table_tool_calls:
breaker_reason = (
f"{len(signatures)} lokale Dateiaufrufe; die vorhandenen Ergebnisse "
"müssen jetzt als Antwort ausgegeben werden"
)
elif len(signatures) >= self.valves.max_tool_calls_per_turn:
breaker_reason = f"{len(signatures)} Werkzeugaufrufe in einem Schritt"
+3
View File
@@ -206,6 +206,9 @@ params = {
"lines, header row, decimal separator and date format before parsing. Do not begin "
"with a blind pandas.read_csv(path) call; use csv.Sniffer or sep=None with the "
"Python engine for discovery, then parse with explicit verified parameters. "
"Normally use one preview/dialect call and one complete analysis call. After one failed "
"parse, correct the next call from its error instead of repeatedly searching the filesystem. "
"Never spend more than four code calls on one table unless debugging was explicitly requested. "
"Compute exact aggregates, reconcile the result, and always provide a visible final answer. "
"For GitHub repository implementation details, README files, source trees, "
"API routes, or code search, use the dedicated official GitHub repository "