feat(planner): add permission-aware routing foundations

This commit is contained in:
Julien Denizot
2026-06-20 16:31:12 +02:00
parent ff49915a96
commit 913457fa66
4 changed files with 1592 additions and 5 deletions
Generated
+1
View File
@@ -251,6 +251,7 @@ version = "0.1.0"
dependencies = [
"enuxia-frappe-client",
"enuxia-hailo-client",
"serde",
"serde_json",
"thiserror",
]
+77 -1
View File
@@ -1,5 +1,9 @@
use clap::{Parser, Subcommand};
use enuxia_ai_core::{AnswerMode, AnswerStrategy, QueryOrchestrator, QueryPlan};
use enuxia_ai_core::{
AnswerMode, AnswerStrategy, QueryOrchestrator, QueryPlan, build_planner_doctype_catalog,
build_planner_doctype_catalog_for_module, build_planner_module_catalog,
select_module_with_model,
};
use enuxia_frappe_client::{FrappeClient, ListDocumentsRequest};
use enuxia_hailo_client::HailoClient;
use serde_json::{Map, Value};
@@ -65,6 +69,29 @@ enum FrappeCommand {
exposed_only: bool,
},
/// Affiche le catalogue léger de DocTypes fourni au planificateur.
PlannerCatalog,
/// Affiche le catalogue compact des modules exposés.
PlannerModules,
/// Demande au modèle de sélectionner un module autorisé.
PlannerSelectModule {
/// Question libre utilisée pour sélectionner le module.
question: String,
},
/// Affiche les DocTypes exposés d'un module précis.
PlannerDoctypes {
/// Application Frappe du module.
#[arg(long)]
app: String,
/// Nom du module Frappe.
#[arg(long)]
module: String,
},
/// Affiche les métadonnées autorisées d'un DocType.
Metadata {
/// Nom exact du DocType.
@@ -262,6 +289,55 @@ async fn run_frappe_command(
}
}
FrappeCommand::PlannerDoctypes { app, module } => {
let catalog = build_planner_doctype_catalog_for_module(client, &app, &module).await?;
println!("{}", serde_json::to_string_pretty(&catalog)?);
}
FrappeCommand::PlannerSelectModule { question } => {
let hailo = HailoClient::new(hailo_base_url, model)?;
let result = select_module_with_model(client, &hailo, &question).await?;
match &result.selection {
enuxia_ai_core::ModuleSelection::Selected { app, module } => {
println!("Décision : module sélectionné");
println!("Application : {app}");
println!("Module : {module}");
}
enuxia_ai_core::ModuleSelection::NoMatch => {
println!("Décision : aucune correspondance");
}
}
println!("Décision validée par Rust : oui");
println!(
"Appel au modèle : {}",
if result.model_called { "oui" } else { "non" },
);
eprintln!();
eprintln!("---");
eprintln!("Sortie brute : {}", result.raw_output);
eprintln!("Taille du prompt : {} caractères", result.prompt_chars,);
eprintln!("Tokens générés : {}", result.eval_count,);
eprintln!("Durée totale : {} ns", result.total_duration_ns,);
}
FrappeCommand::PlannerModules => {
let catalog = build_planner_module_catalog(client).await?;
println!("{}", serde_json::to_string_pretty(&catalog)?);
}
FrappeCommand::PlannerCatalog => {
let catalog = build_planner_doctype_catalog(client).await?;
println!("{}", serde_json::to_string_pretty(&catalog)?);
}
FrappeCommand::Metadata { doctype } => {
let result = client.doctype_metadata(&doctype).await?;
+1
View File
@@ -8,5 +8,6 @@ authors.workspace = true
[dependencies]
enuxia-frappe-client = { path = "../enuxia-frappe-client" }
enuxia-hailo-client = { path = "../enuxia-hailo-client" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "2.0.18"
File diff suppressed because it is too large Load Diff