Freigabe-Hygiene (#631, #579, #609, #610) und JSON-Filter fuer WebFetch (#632)

#631: Derselbe Vorschlag (gleicher Agent, gleiches Werkzeug, gleiche Argumente unabhaengig
von Schluesselreihenfolge) wird nicht erneut angelegt - der Agent erfaehrt die bestehende
Nummer. Offene Vorschlaege verfallen nach 24 h (Status Expired).

#609: Werkzeuge koennen den Freigabeschluessel aus dem Inhalt bestimmen
(IAgentTool.StagingAktion). Database: SELECT/SHOW/DESCRIBE -> query, INSERT/UPDATE/DELETE
-> write, DDL -> schema; write und schema sind freigabepflichtig. Ausgefuehrt wird nach
Statement-Art, schreibende Statements melden die Zeilenzahl.

#579: Database-Vorpruefung (Zugriffsebene, Tabellenfreigabe, SqlGuard) - was das Werkzeug
ablehnen wuerde, kommt nicht mehr in die Freigabeliste.

#610: SqlGuard ueberspringt IF [NOT] EXISTS und erkennt DESCRIBE/DESC <tabelle>.

#632: WebFetch fetch mit filter liefert aus JSON/JSONP nur passende Eintraege; beim
Blaettern durch grosses JSON empfiehlt der Hinweis den filter.

Version 0.1.10.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-09-18 18:51:06 +02:00
co-authored by Claude Opus 5
parent f5731c50f8
commit f74e49ba35
18 changed files with 727 additions and 29 deletions
@@ -21,7 +21,9 @@ public sealed class WebFetchTool : IAgentTool
den du brauchst - noch guenstiger. Linkziele (URLs) kommen nur mit links=true - nur
setzen, wenn du die Adressen wirklich brauchst. mode="full" liefert den ganzen Seitentext und kostet
ein Vielfaches: nur verwenden, wenn der Hauptinhalt fehlt oder unvollstaendig ist.
JSON, Text und XML kommen unveraendert. Lange Inhalte kommen in Abschnitten: die Antwort
JSON, Text und XML kommen unveraendert. Brauchst du aus einer grossen JSON-Antwort nur
bestimmte Eintraege (z.B. eine Stadt), nimm "filter": dann kommen nur die Objekte, die den
Text enthalten - viel guenstiger als Blaettern. Lange Inhalte kommen in Abschnitten: die Antwort
nennt nextOffset - nur weiterlesen, wenn der Rest fuer den Auftrag wirklich gebraucht wird.
rss: Titel, Link, Datum und kurze Beschreibung je Eintrag ("limit" begrenzt die Anzahl).
@@ -65,6 +67,8 @@ public sealed class WebFetchTool : IAgentTool
"description": "fetch: auto (Standard) = Hauptinhalt als Markdown; full = ganzer Seitentext, nur wenn auto nicht reicht" },
"links": { "type": "boolean",
"description": "fetch: Linkziele als [Text](URL) mitliefern (Standard false - kostet auf linkreichen Seiten viel)" },
"filter": { "type": "string",
"description": "fetch, nur JSON/JSONP: nur Eintraege liefern, die diesen Text enthalten (ohne Gross-/Kleinschreibung), z.B. 'Berlin'" },
"offset": { "type": "integer",
"description": "fetch: Fortsetzung eines langen Inhalts - Wert aus nextOffset der vorigen Antwort" },
"limit": { "type": "integer",
@@ -152,7 +156,8 @@ public sealed class WebFetchTool : IAgentTool
GetInt(input, "offset") ?? 0,
GetConfigInt(config, "maxContentChars", WebInhalt.StandardMaxZeichen),
mitLinks: input.ValueKind == JsonValueKind.Object
&& input.TryGetProperty("links", out var l) && l.ValueKind == JsonValueKind.True);
&& input.TryGetProperty("links", out var l) && l.ValueKind == JsonValueKind.True,
filter: GetString(input, "filter"));
// Stand der Daten: Last-Modified oder das Datum aus der Seite. Nicht mehr der
// Date-Header - der ist die Uhrzeit des Servers beim Abruf, also fetchedAt.