feat(memory): config embedders (LOT C2) + suggestion contextuelle (LOT C3) + contexte projet partagé
- LOT C2 (§14.5.3) : use cases de configuration des embedders déclaratifs (List/Save/Delete + DescribeEmbedderEngines : modèles ONNX recommandés, environnement local détecté, stratégies compilées). UI EmbedderSettings. - LOT C3 (§14.5.5) : suggestion contextuelle best-effort à l'activation quand la mémoire dépasse le budget de recall sans embedder configuré (event EmbedderSuggested, anti-spam 1×/session, « ne plus demander »). - Contexte projet partagé .ideai/CONTEXT.md (model-agnostic) injecté à tous les agents/profils au lancement, avant la persona. UI ProjectContextPanel. Tests : backend workspace vert (0 échec) ; frontend 306/306. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -128,19 +128,21 @@ impl TerminalSessions {
|
||||
})
|
||||
}
|
||||
|
||||
/// Lists every currently-live agent and the cell hosting it.
|
||||
/// Lists every currently-live agent, its current host cell and session id.
|
||||
///
|
||||
/// One `(AgentId, NodeId)` pair per session tagged [`SessionKind::Agent`].
|
||||
/// One `(AgentId, NodeId, SessionId)` tuple per session tagged [`SessionKind::Agent`].
|
||||
/// Used by the `list_live_agents` query so the UI can disable an agent that
|
||||
/// is already running elsewhere (it cannot be launched in a second cell).
|
||||
#[must_use]
|
||||
pub fn live_agents(&self) -> Vec<(AgentId, NodeId)> {
|
||||
pub fn live_agents(&self) -> Vec<(AgentId, NodeId, SessionId)> {
|
||||
self.entries
|
||||
.lock()
|
||||
.map(|m| {
|
||||
m.values()
|
||||
.filter_map(|e| match e.session.kind {
|
||||
SessionKind::Agent { agent_id } => Some((agent_id, e.session.node_id)),
|
||||
SessionKind::Agent { agent_id } => {
|
||||
Some((agent_id, e.session.node_id, e.session.id))
|
||||
}
|
||||
SessionKind::Plain => None,
|
||||
})
|
||||
.collect()
|
||||
@ -148,6 +150,28 @@ impl TerminalSessions {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Rebinds a live agent session to a new visible layout node without
|
||||
/// respawning the CLI process.
|
||||
///
|
||||
/// This is the application-level "cell is a view" operation: closing a cell
|
||||
/// can leave an agent running in the background, and later opening that agent
|
||||
/// in another cell updates only the view binding (`node_id`). The PTY handle,
|
||||
/// session id, scrollback and process stay untouched.
|
||||
#[must_use]
|
||||
pub fn rebind_agent_node(
|
||||
&self,
|
||||
agent_id: &AgentId,
|
||||
node_id: NodeId,
|
||||
) -> Option<TerminalSession> {
|
||||
self.entries.lock().ok().and_then(|mut m| {
|
||||
let entry = m.values_mut().find(
|
||||
|e| matches!(e.session.kind, SessionKind::Agent { agent_id: a } if &a == agent_id),
|
||||
)?;
|
||||
entry.session.node_id = node_id;
|
||||
Some(entry.session.clone())
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the [`PtyHandle`]s of every currently-registered session.
|
||||
///
|
||||
/// Used at application shutdown to kill all live PTYs cleanly (the
|
||||
|
||||
@ -67,10 +67,7 @@ impl OpenTerminal {
|
||||
/// # Errors
|
||||
/// - [`AppError::Invalid`] for a non-absolute cwd or a zero-sized terminal,
|
||||
/// - [`AppError::Process`] if the PTY fails to spawn.
|
||||
pub async fn execute(
|
||||
&self,
|
||||
input: OpenTerminalInput,
|
||||
) -> Result<OpenTerminalOutput, AppError> {
|
||||
pub async fn execute(&self, input: OpenTerminalInput) -> Result<OpenTerminalOutput, AppError> {
|
||||
let cwd = ProjectPath::new(input.cwd).map_err(|e| AppError::Invalid(e.to_string()))?;
|
||||
let size =
|
||||
PtySize::new(input.rows, input.cols).map_err(|e| AppError::Invalid(e.to_string()))?;
|
||||
|
||||
Reference in New Issue
Block a user