mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-16 19:59:56 +02:00
Les outils web des tours de la façade (web_search, web_images, web_open,
web_read, web_grep) ne passent plus par /tool/exec du Go : src/webtools.rs
porte chat_internet_tools.go, chat_internet.go et chat_web_images.go. Le
cache des pages (10 min, clé MD5 des options comme le Go) est dans la
façade ; client Crawl4AI au corps près, réponses lues comme json.Unmarshal ;
résultats DuckDuckGo tirés du markdown (uddg, entités, extraits) ;
recherche d'images avec le jeton vqd et les cookies gardés par hôte ;
web_grep sur les regex du Go, erreurs au texte de regexp.
Le moteur intégré lit le HTML avec go-readability et html-to-markdown, que
rien en Rust ne reproduit au caractère près : la conversion d'une page et la
lecture des résultats restent au Go, derrière /internal/v1/web/fetch et
/internal/v1/web/search (sans état). web_screenshot reste au Go.
Le traducteur go_regex refuse la répétition d'une répétition et les comptes
au-delà de 1000, et rend littéral un « { » qui n'ouvre pas de répétition,
comme le Go (motifs retry_patterns compris).
Parité : journal de 74 appels tiré du Go (parity_web_tools_test.go →
tests/parity_web/outils.json : résultats, requêtes reçues par les faux
Crawl4AI et DuckDuckGo, pages demandées au moteur intégré), rejoué par
tests/webtools.rs ; un tour de la façade qui ouvre une page (tests/lot6.rs) ;
TestInternalMoteurWebIntegre côté Go.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
53 lines
1.6 KiB
Go
53 lines
1.6 KiB
Go
package loki
|
|
|
|
import "net/http"
|
|
|
|
// API interne du moteur web intégré (lot 42 de la migration Rust).
|
|
//
|
|
// La façade exécute les outils web de ses tours (web_search, web_images,
|
|
// web_open, web_read, web_grep) : cache des pages, client Crawl4AI, lecture
|
|
// des résultats, mise en forme. Le moteur intégré lit le HTML avec
|
|
// go-readability, html-to-markdown et le parseur HTML5 de x/net : rien en
|
|
// Rust ne les reproduit au caractère près, ils restent donc ici, derrière
|
|
// deux appels sans état.
|
|
//
|
|
// POST /internal/v1/web/fetch {"url":"…"}
|
|
// → {"markdown":"…"} | {"error":"…"}
|
|
// POST /internal/v1/web/search {"query":"…","limit":8}
|
|
// → {"results":[{"title":"…","url":"…","snippet":"…"}]} | {"error":"…"}
|
|
|
|
func handleInternalWebFetch(w http.ResponseWriter, r *http.Request) {
|
|
var in struct {
|
|
URL string `json:"url"`
|
|
}
|
|
if !readInternalJSON(w, r, &in) {
|
|
return
|
|
}
|
|
md, err := goFetchMarkdown(in.URL)
|
|
if err != nil {
|
|
sendJSON(w, http.StatusOK, map[string]any{"error": err.Error()})
|
|
return
|
|
}
|
|
sendJSON(w, http.StatusOK, map[string]any{"markdown": md})
|
|
}
|
|
|
|
func handleInternalWebSearch(w http.ResponseWriter, r *http.Request) {
|
|
var in struct {
|
|
Query string `json:"query"`
|
|
Limit int `json:"limit"`
|
|
}
|
|
if !readInternalJSON(w, r, &in) {
|
|
return
|
|
}
|
|
results, err := goSearch(in.Query, in.Limit)
|
|
if err != nil {
|
|
sendJSON(w, http.StatusOK, map[string]any{"error": err.Error()})
|
|
return
|
|
}
|
|
out := make([]map[string]string, 0, len(results))
|
|
for _, r := range results {
|
|
out = append(out, map[string]string{"title": r.Title, "url": r.URL, "snippet": r.Snippet})
|
|
}
|
|
sendJSON(w, http.StatusOK, map[string]any{"results": out})
|
|
}
|