fix(runtime): detection non bloquante, bornée dans le temps, HTTP pour les profils locaux (#28)
Le first-run wizard restait figé : `CliAgentRuntime::detect` construisait un runtime tokio courant-thread via `futures_block_on` pour piloter un `ProcessSpawner` async. Appelé depuis le runtime async de Tauri, ce `block_on` imbriqué panique ; la commande IPC ne répond alors jamais, la promesse `detectProfiles` reste pendante et `busy` ne redescend plus. Ce commit s'attaque à la cause côté backend : - `AgentRuntime::detect` devient `async fn` (`#[async_trait]`) : le port cesse de mentir sur sa nature. Il pilote un spawner async, il est async. Le `futures_block_on` disparaît, et avec lui le runtime imbriqué. - La sonde CLI est bornée par `tokio::time::timeout(DETECTION_TIMEOUT)` : un binaire qui ne rend jamais la main dégrade la détection en `Err`, il ne gèle plus l'appelant. - Les profils `StructuredAdapter::OpenAiCompatible` n'ont pas de CLI à spawner : les sonder revenait à tester un binaire inexistant. Ils sont désormais sondés par un GET HTTP sur l'endpoint `/models` dérivé de `chat_http.endpoint`, borné par le même timeout. `DetectProfiles` séquence les `await` sur les candidats. Les fakes `AgentRuntime` des crates application/infrastructure/app-tauri suivent la nouvelle signature. Tests: cargo test -p domain (241), -p application (81), -p infrastructure (269), -p app-tauri (63+15) — verts. `rg futures_block_on crates` sans match. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -745,13 +745,14 @@ pub struct GraphCommit {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Launch/drive an AI CLI according to an [`AgentProfile`], handling context
|
||||
/// injection. CPU-bound and synchronous — kept plain `fn`.
|
||||
/// injection.
|
||||
#[async_trait]
|
||||
pub trait AgentRuntime: Send + Sync {
|
||||
/// Detects whether the profile's command is available.
|
||||
///
|
||||
/// # Errors
|
||||
/// [`RuntimeError`] on detection failure.
|
||||
fn detect(&self, profile: &AgentProfile) -> Result<bool, RuntimeError>;
|
||||
async fn detect(&self, profile: &AgentProfile) -> Result<bool, RuntimeError>;
|
||||
|
||||
/// Builds a [`SpawnSpec`] (command + args + injection plan) for launching
|
||||
/// the agent in `cwd` with the prepared context.
|
||||
|
||||
Reference in New Issue
Block a user