KI-Chat: Web-Recherche ueber Ollama Web Search
Der Assistent kannte bisher nur die Datenbank. Fragen wie "Was muss ich ueber die Firma wissen?" konnte er damit nicht beantworten - Groesse, Produkte, News, Kultur stehen nirgends in der Bewerbung. Zwei neue Werkzeuge (web_suche, web_seite_lesen) ueber die Web-Search-API von ollama.com. Sie authentifizieren sich mit demselben OLLAMA_API_KEY, den der Benutzer fuer Chat und Dokumente ohnehin hinterlegt hat: keine zusaetzliche Konfiguration. Anders als /api/chat haengt die Websuche nicht an OLLAMA_HOST - wer rein lokal chattet, hat schlicht keine Websuche, der Rest laeuft unveraendert weiter. - Tool-Runden 4 -> 8: Bewerbung holen, suchen, Seiten lesen, antworten lief vorher ins Limit, statt zu antworten. - Antworten der Websuche hart gedeckelt, sie wandern sonst in jeder weiteren Runde erneut ins Kontextfenster. - Status-Label zeigt, wonach gesucht wird - sonst sieht der Nutzer nicht, ob die richtige Firma erwischt wurde. - Nackte URLs im Chat sind klickbar: Belege nennt das Modell meist als reine URL, nicht als Markdown-Link. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+23
-3
@@ -28,17 +28,37 @@
|
||||
// targets are restricted to http(s)/mailto/relative so a `javascript:` URL
|
||||
// from the model cannot become a clickable XSS vector, and the URL is stripped
|
||||
// of characters that could break out of the href attribute.
|
||||
function link(url, label) {
|
||||
const safe = String(url).trim().replace(/["'<>`\\]/g, '');
|
||||
return `<a href="${safe}" target="_blank" rel="noopener noreferrer">${label}</a>`;
|
||||
}
|
||||
|
||||
function inlineFmt(t) {
|
||||
return t
|
||||
// Fertige <a>-Tags werden geparkt, damit die Autolink-Regel unten nicht in
|
||||
// eine bereits gebaute href hineinläuft und den Tag zerlegt.
|
||||
const parked = [];
|
||||
const park = (html) => `\u0000${parked.push(html) - 1}\u0000`;
|
||||
|
||||
let s = t
|
||||
.replace(/`([^`]+)`/g, '<code>$1</code>')
|
||||
.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
|
||||
.replace(/(^|[^*])\*([^*]+)\*/g, '$1<em>$2</em>')
|
||||
.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (m, label, url) => {
|
||||
const u = String(url).trim();
|
||||
if (u && !/^(https?:|mailto:|\/|#)/i.test(u)) return m;
|
||||
const safe = u.replace(/["'<>`\\]/g, '');
|
||||
return `<a href="${safe}" target="_blank" rel="noopener noreferrer">${label}</a>`;
|
||||
return park(link(u, label));
|
||||
});
|
||||
|
||||
// Nackte Quellen-URLs klickbar machen — bei Web-Recherchen nennt der
|
||||
// Assistent Belege oft als reine URL, nicht als Markdown-Link. Nur http(s),
|
||||
// und Satzzeichen am Ende gehören zum Satz, nicht zur Adresse.
|
||||
s = s.replace(/https?:\/\/[^\s<>"'`\u0000]+/g, (u) => {
|
||||
const m = u.match(/[.,;:!?)\]]+$/);
|
||||
const rein = m ? u.slice(0, -m[0].length) : u;
|
||||
return park(link(rein, rein)) + (m ? m[0] : '');
|
||||
});
|
||||
|
||||
return s.replace(/\u0000(\d+)\u0000/g, (m, i) => parked[Number(i)]);
|
||||
}
|
||||
|
||||
function renderMarkdown(src) {
|
||||
|
||||
Reference in New Issue
Block a user