Lot 32 : images gardées (KEEP_TURN_IMAGES) dans le tour de la façade

KEEP_TURN_IMAGES ne garde plus la conversation au Go. L'état du tour vit
dans la façade ; les fichiers et la vision restent au Go.

Go (facade_keepimg.go) :
- /internal/v1/turn/keepimg : vision réellement active, budget des images
  gardées ;
- /internal/v1/turn/keepimg/store : une image relayée rangée par
  référence (refRelayImage), relue à l'octet près.

Rust :
- chat/keepimg.rs : port de keepImages (image à l'essai, mesure par le
  moteur répartie au prorata des octets, budget, publication, fin de tour).
- La boucle du tour : budget demandé pour le fil principal, image rangée
  par le Go, historique réécrit publié sans les relais non gardés ; les
  images gardées partent avant tout résumé (filet réactif, en cours de
  tour, fenêtre pleine).
- Début et fin de tour : retirées si le contexte le demande ou si elles
  ne doivent plus partir (clé retirée, vision absente).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
Claude committed 2026-10-16 02:30:59 +00:00
1 parent a005626e66
commit f79b74dac3
17 files changed
+1435 -37

No files matched your search

+27 -1
View File
@@ -132,6 +132,11 @@ pub struct FakeGo {
/// reçues (« conv main »).
pub turn_side_live: Mutex<bool>,
pub turn_slots: Mutex<Vec<String>>,
/// Message relayé par chaque outil exécuté ici (image d'une capture).
pub tool_relay: Mutex<Option<serde_json::Value>>,
/// /internal/v1/turn/keepimg : vision active ; rangements reçus.
pub keep_vision: Mutex<bool>,
pub keep_stores: Mutex<Vec<serde_json::Value>>,
}
impl FakeGo {
@@ -648,11 +653,14 @@ async fn handle(st: Arc<FakeGo>, req: Request<Incoming>) -> Response<Full<Bytes>
let result = by_name
.or_else(|| st.tool_result.lock().unwrap().clone())
.unwrap_or_else(|| format!("exec:{}", v["name"].as_str().unwrap()));
let out = serde_json::json!({
let mut out = serde_json::json!({
"label": v["args"]["command"],
"result": result,
"caps_agent": v["caps"]["Agent"],
});
if let Some(r) = st.tool_relay.lock().unwrap().clone() {
out["relay"] = r;
}
resp(200, out.to_string())
}
"/internal/v1/oai/route" => {
@@ -687,6 +695,24 @@ async fn handle(st: Arc<FakeGo>, req: Request<Incoming>) -> Response<Full<Bytes>
}
resp(200, r#"{"ticket":7}"#)
}
"/internal/v1/turn/keepimg" => {
let v = serde_json::json!({
"vision": *st.keep_vision.lock().unwrap(),
"budget": 3276,
});
resp(200, v.to_string())
}
"/internal/v1/turn/keepimg/store" => {
let body = req.into_body().collect().await.unwrap().to_bytes();
let v: serde_json::Value = serde_json::from_slice(&body).unwrap();
let mut msg = v["msg"].clone();
st.keep_stores.lock().unwrap().push(msg.clone());
msg["content"][1]["image_url"]["url"] = serde_json::json!("loki-img:k1.png");
resp(
200,
serde_json::json!({ "ok": true, "msg": msg, "weight": 4 }).to_string(),
)
}
"/internal/v1/turn/slot" => {
let body = req.into_body().collect().await.unwrap().to_bytes();
let v: serde_json::Value = serde_json::from_slice(&body).unwrap();