Lot 6 : le tour branché sur le moteur, les outils et la base (chat::host)

GoTurnHost est le TurnHost de la façade : envoi par EngineHttp (clé de
l'endpoint, pannes classées comme friendlyLLMError), outils par l'API du Go
avec leurs suites (capture, aperçu, image relayée), résultats complets
confiés à l'écrivain des discussions (id « <discussion>.<aléa> »),
compaction par Compactor avec un résumeur qui interroge le moteur
(EngineSummarizer) et l'archive recall du Go (StoreRecall), images jointes
lues sur disque et ouvertes par le Go, en cache borné à 64 Mio.

RecallArchive devient asynchrone ; la boucle consulte la mémoire des
refus de compaction avant d'annoncer une compaction en cours de tour.

Écarts : pas de résumé en continuation (état du slot tenu par le Go), ni
conseil de cache, ni garde d'écriture du mode Code.

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-15 10:34:15 +00:00
1 parent e114ba3800
commit fea055fd52
7 files changed
+843 -7

No files matched your search

+22
View File
@@ -169,6 +169,28 @@ impl Store {
.await
}
/// Archive un bloc verbatim pour l'outil recall (`archiveRecallBlock`,
/// numéroté par le Go) et rend son id (« r7 »).
pub async fn recall_archive(
&self,
label: &str,
role: &str,
content: &str,
) -> Result<String, String> {
let v = self
.internal_json(
Method::POST,
"/internal/v1/recall/archive",
Some(&serde_json::json!({ "label": label, "role": role, "content": content })),
)
.await?;
v.get("id")
.and_then(|i| i.as_str())
.filter(|i| !i.is_empty())
.map(str::to_string)
.ok_or_else(|| format!("archive recall : réponse sans id {v}"))
}
/// Valeur brute ; `Ok(None)` = absente, `Err` = pas pu lire (à distinguer
/// pour les secrets : comme `getBytesErr`).
pub async fn get(&self, bucket: &str, key: &str) -> Result<Option<Vec<u8>>, String> {