feat(cross-project): découverte et contact inter-projets — tools MCP idea_project_{list,read_context,list_agents,ask_agent,cancel_agent}, permission contactable par agent + default_contactable persistée dans les templates, routage orchestrator par projectId+agentId — #260 (tests ciblés verts, QA en attente)
This commit is contained in:
@ -540,6 +540,7 @@ mod open_project_template_tests {
|
||||
default_agent_name: None,
|
||||
default_system_permissions: None,
|
||||
default_mcp_tool_policy: None,
|
||||
default_contactable: false,
|
||||
})
|
||||
.await
|
||||
.expect("template is created")
|
||||
|
||||
@ -78,6 +78,8 @@ impl TemplateToolProvider for AppTemplateToolProvider {
|
||||
"defaultMcpToolPermissions",
|
||||
"defaultMcpToolPolicy",
|
||||
)?,
|
||||
default_contactable: optional_bool(&arguments, "defaultContactable")?
|
||||
.unwrap_or(false),
|
||||
})
|
||||
.await
|
||||
.map_err(template_error)?;
|
||||
@ -160,6 +162,17 @@ fn optional_string<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
fn optional_bool(value: &Value, key: &str) -> Result<Option<bool>, TemplateToolError> {
|
||||
match value.get(key) {
|
||||
None | Some(Value::Null) => Ok(None),
|
||||
Some(Value::Bool(value)) => Ok(Some(*value)),
|
||||
Some(_) => Err(TemplateToolError::new(
|
||||
"invalid",
|
||||
format!("field `{key}` must be a boolean"),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn optional_json_value<T>(arguments: &Value, key: &str) -> Result<Option<T>, TemplateToolError>
|
||||
where
|
||||
T: serde::de::DeserializeOwned,
|
||||
@ -317,6 +330,7 @@ mod tests {
|
||||
"defaultAgentName": "Base Agent",
|
||||
"defaultSystemPermissions": { "network": "allow" },
|
||||
"defaultMcpToolPermissions": { "allowedTools": ["idea_template_read"] },
|
||||
"defaultContactable": true,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
@ -332,6 +346,7 @@ mod tests {
|
||||
created["defaultMcpToolPermissions"],
|
||||
json!({ "allowedTools": ["idea_template_read"] })
|
||||
);
|
||||
assert_eq!(created["defaultContactable"], true);
|
||||
|
||||
let read = provider
|
||||
.handle_template_tool(
|
||||
@ -353,6 +368,7 @@ mod tests {
|
||||
read["defaultMcpToolPermissions"],
|
||||
json!({ "allowedTools": ["idea_template_read"] })
|
||||
);
|
||||
assert_eq!(read["defaultContactable"], true);
|
||||
|
||||
let listed = provider
|
||||
.handle_template_tool(&project(), "agent", "idea_template_list", json!({}))
|
||||
@ -370,6 +386,7 @@ mod tests {
|
||||
"content": "v2",
|
||||
"defaultSystemPermissions": { "network": "deny" },
|
||||
"defaultMcpToolPermissions": { "allowedTools": ["idea_template_update"] },
|
||||
"defaultContactable": false,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
@ -385,6 +402,7 @@ mod tests {
|
||||
updated["defaultMcpToolPermissions"],
|
||||
json!({ "allowedTools": ["idea_template_update"] })
|
||||
);
|
||||
assert_eq!(updated["defaultContactable"], false);
|
||||
assert_eq!(
|
||||
store
|
||||
.get(TemplateId::from_uuid(
|
||||
|
||||
Reference in New Issue
Block a user