mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-20 21:48:47 +02:00
Lot 42 : outils web de l'agent exécutés par la façade
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
This commit is contained in:
19 files changed
+4561
-7
No files matched your search
@@ -149,6 +149,12 @@ pub struct FakeGo {
|
||||
pub projsnaps: Mutex<std::collections::VecDeque<serde_json::Value>>,
|
||||
pub projsnap_refresh: Mutex<Option<serde_json::Value>>,
|
||||
pub projsnap_refreshes: Mutex<Vec<serde_json::Value>>,
|
||||
/// Moteur web intégré (lot 42) : réponses de /internal/v1/web/fetch par
|
||||
/// URL et de /internal/v1/web/search par « requête|limite » ; appels
|
||||
/// reçus (« fetch URL », « search requête|limite »).
|
||||
pub web_fetch: Mutex<HashMap<String, serde_json::Value>>,
|
||||
pub web_search: Mutex<HashMap<String, serde_json::Value>>,
|
||||
pub web_log: Mutex<Vec<String>>,
|
||||
}
|
||||
|
||||
impl FakeGo {
|
||||
@@ -505,6 +511,28 @@ async fn handle(st: Arc<FakeGo>, req: Request<Incoming>) -> Response<Full<Bytes>
|
||||
200,
|
||||
serde_json::json!({ "generating": *st.generating.lock().unwrap() }).to_string(),
|
||||
),
|
||||
"/internal/v1/web/fetch" | "/internal/v1/web/search" => {
|
||||
let fetch = path == "/internal/v1/web/fetch";
|
||||
let body = req.into_body().collect().await.unwrap().to_bytes();
|
||||
let v: serde_json::Value = serde_json::from_slice(&body).unwrap_or_default();
|
||||
let key = if fetch {
|
||||
v["url"].as_str().unwrap_or("").to_string()
|
||||
} else {
|
||||
format!("{}|{}", v["query"].as_str().unwrap_or(""), v["limit"])
|
||||
};
|
||||
st.web_log
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(format!("{} {key}", if fetch { "fetch" } else { "search" }));
|
||||
let map = if fetch { &st.web_fetch } else { &st.web_search };
|
||||
let out = map
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get(&key)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| serde_json::json!({ "error": format!("inconnu : {key}") }));
|
||||
resp(200, out.to_string())
|
||||
}
|
||||
"/internal/v1/web/reach/reset" => {
|
||||
*st.reach_resets.lock().unwrap() += 1;
|
||||
resp(204, "")
|
||||
|
||||
Reference in new issue
Block a user