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:
@ -3,11 +3,11 @@
|
||||
|
||||
mod helpers;
|
||||
|
||||
use domain::ids::AgentId;
|
||||
use domain::{
|
||||
Direction, GridCell, GridContainer, LayoutError, LayoutNode, LayoutTree, LeafCell,
|
||||
SplitContainer, WeightedChild,
|
||||
};
|
||||
use domain::ids::AgentId;
|
||||
use helpers::{node, session};
|
||||
|
||||
fn agent_id(n: u128) -> AgentId {
|
||||
@ -463,6 +463,36 @@ fn set_session_duplicate_across_leaves_rejected() {
|
||||
assert_eq!(err, LayoutError::DuplicateSession(session(100)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attach_session_attaches_background_session_to_leaf() {
|
||||
let tree = two_leaves(None, None);
|
||||
let out = tree.attach_session(node(2), session(100)).unwrap();
|
||||
assert_eq!(session_for(&out, node(1)), None);
|
||||
assert_eq!(session_for(&out, node(2)), Some(session(100)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attach_session_moves_visible_session_to_target_leaf() {
|
||||
let tree = two_leaves(Some(100), None);
|
||||
let out = tree.attach_session(node(2), session(100)).unwrap();
|
||||
assert_eq!(session_for(&out, node(1)), None);
|
||||
assert_eq!(session_for(&out, node(2)), Some(session(100)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attach_session_same_leaf_is_idempotent() {
|
||||
let tree = two_leaves(Some(100), None);
|
||||
let out = tree.attach_session(node(1), session(100)).unwrap();
|
||||
assert_eq!(out, tree);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attach_session_rejects_target_occupied_by_other_session() {
|
||||
let tree = two_leaves(Some(100), Some(200));
|
||||
let err = tree.attach_session(node(2), session(100)).unwrap_err();
|
||||
assert_eq!(err, LayoutError::CrossContainer);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// set_cell_agent (#3: per-cell agent)
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -503,7 +533,9 @@ fn set_cell_agent_is_immutable_source_unchanged() {
|
||||
#[test]
|
||||
fn set_cell_agent_missing_leaf_is_node_not_found() {
|
||||
let tree = single(1, None);
|
||||
let err = tree.set_cell_agent(node(404), Some(agent_id(1))).unwrap_err();
|
||||
let err = tree
|
||||
.set_cell_agent(node(404), Some(agent_id(1)))
|
||||
.unwrap_err();
|
||||
assert_eq!(err, LayoutError::NodeNotFound(node(404)));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user