mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-19 21:18:20 +02:00
Lot 23 : sonde de gabarit en Rust (avec LOKI_CHAT=rust)
Port de chat_tplprobe.go : la façade sonde le gabarit du moteur après ses complétions (/health, /props, /apply-template), avec les verdicts preserves_history, prefix_stable et renders_reasoning, le cache par build/modèle/gabarit/forme et la relance bornée. - l'écho du raisonnement suit le verdict de la sonde (echo_policy_for) ; - NUDGE_IN_TOOL ne garde plus la conversation au Go : le rappel de budget va dans le dernier résultat d'outil quand le préfixe n'est pas stable ; - le Go lit le verdict de la façade (/internal/facade/v1/chat/tpl) quand elle tient la conversation. Parité : parity_tplprobe_test.go tire du Go un journal d'échanges rejoué octet pour octet par tests/tplprobe.rs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
17 files changed
+5006
-22
No files matched your search
@@ -39,7 +39,7 @@ use super::wire::{
|
||||
ChatEndpoint, ChatPayloadOpts, EchoRefusals, EffortFallbacks, IMG_REF_SCHEME,
|
||||
build_chat_payload, content_parts, part_image_url, wire_messages,
|
||||
};
|
||||
use crate::store::Store;
|
||||
use crate::store::{BK_STATE, Store};
|
||||
|
||||
/// Taille au-delà de laquelle le cache d'images oublie les plus anciennes
|
||||
/// (`imgCacheMax`).
|
||||
@@ -284,6 +284,8 @@ pub struct ChatShared {
|
||||
pub compact_memory: CompactMemory,
|
||||
pub images: ImageCache,
|
||||
pub patterns: Arc<RetryPatterns>,
|
||||
/// Sonde de gabarit (`chat_tplprobe.go`) : derniers verdicts et cache.
|
||||
pub tpl: Arc<super::tplprobe::TplProbe>,
|
||||
}
|
||||
|
||||
/// Ce que la compaction sait du tour.
|
||||
@@ -490,6 +492,39 @@ impl TurnHost for GoTurnHost {
|
||||
(self.queued)()
|
||||
}
|
||||
|
||||
fn prefix_unstable(
|
||||
&self,
|
||||
tools: &[Tool],
|
||||
kwargs: Option<&Map<String, Value>>,
|
||||
effort: &str,
|
||||
) -> bool {
|
||||
let shape = super::tplprobe::Shape::new(tools, kwargs, effort);
|
||||
self.shared.tpl.caps_for(false, &shape).is_some_and(|r| {
|
||||
r.prefix_stable == super::wire::TplTri::No
|
||||
&& !r.model.is_empty()
|
||||
&& r.model == super::wire::reasoning_echo_model(&self.cfg)
|
||||
})
|
||||
}
|
||||
|
||||
/// Fil principal seulement (`perfMain`) : une tâche ou un sous-agent ne
|
||||
/// déclenche pas la sonde.
|
||||
fn completed(&self, tools: &[Tool], kwargs: Option<&Map<String, Value>>, effort: &str) {
|
||||
if self.compact.main_conv.is_empty() {
|
||||
return;
|
||||
}
|
||||
let shape = super::tplprobe::Shape::new(tools, kwargs, effort);
|
||||
let (shared, port) = (self.shared.clone(), self.port);
|
||||
tokio::spawn(async move {
|
||||
let key = shared.store.get_str(BK_STATE, "api_key").await;
|
||||
let env = super::tplprobe::Env {
|
||||
external: false,
|
||||
port: port.into(),
|
||||
key,
|
||||
};
|
||||
shared.tpl.kick(env, shape);
|
||||
});
|
||||
}
|
||||
|
||||
async fn prepare_images(&self, msgs: &[Message]) {
|
||||
self.shared.images.prefetch(&self.shared.store, msgs).await;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user