diff --git a/crates/aionui-ai-agent/src/registry.rs b/crates/aionui-ai-agent/src/registry.rs index 4ac21bb4e..7e167efe7 100644 --- a/crates/aionui-ai-agent/src/registry.rs +++ b/crates/aionui-ai-agent/src/registry.rs @@ -1631,7 +1631,7 @@ mod tests { assert_eq!(pi.agent_source_info.binary_name.as_deref(), Some("pi")); assert_eq!(pi.agent_source_info.bridge_binary.as_deref(), Some("npx")); assert_eq!(pi.native_skills_dirs.as_deref(), Some(&[".pi/skills".to_owned()][..])); - assert!(!pi.team_capable); + assert!(pi.team_capable); assert_eq!(pi.yolo_id, None); assert_eq!( pi.handshake diff --git a/crates/aionui-db/migrations/031_enable_acp_builtin_team_cli_fallback.sql b/crates/aionui-db/migrations/031_enable_acp_builtin_team_cli_fallback.sql new file mode 100644 index 000000000..1e4b99a9f --- /dev/null +++ b/crates/aionui-db/migrations/031_enable_acp_builtin_team_cli_fallback.sql @@ -0,0 +1,23 @@ +-- Let the runtime infer team capability for all builtin ACP agents +-- instead of blocking them with a blanket team_capable_override:false. +-- +-- Migrations 023 (Pi), 025 (ACP Registry npx + binary agents), and 029 +-- (Mimo Code) all seed behavior_policy with team_capable_override:false +-- as a conservative default. This blocks every external ACP agent from +-- joining teams, even when supports_team_cli_fallback() would naturally +-- return true for agents that don't declare shell:false or cli:false in +-- their handshake. +-- +-- The correct gate is the runtime inference in is_team_capable(): +-- ─ supports_team_mcp() for agents with MCP transport (stdio/http) +-- ─ supports_team_cli_fallback() for agents that can execute shell +-- commands (true unless caps explicitly disable shell/cli) +-- +-- Removing the override lets each agent's actual capabilities decide. +-- Agents that later gain MCP support will automatically use the richer +-- Mcp transport via team_tool_transport(). +UPDATE agent_metadata +SET behavior_policy = json_remove(behavior_policy, '$.team_capable_override'), + updated_at = unixepoch('now','subsec') * 1000 +WHERE agent_source = 'builtin' + AND agent_type = 'acp'; diff --git a/crates/aionui-db/tests/pi_acp_agent_migration.rs b/crates/aionui-db/tests/pi_acp_agent_migration.rs index c664a6136..537009f8b 100644 --- a/crates/aionui-db/tests/pi_acp_agent_migration.rs +++ b/crates/aionui-db/tests/pi_acp_agent_migration.rs @@ -22,7 +22,10 @@ async fn pi_acp_builtin_metadata_is_seeded() { let behavior_policy: serde_json::Value = serde_json::from_str(pi.behavior_policy.as_deref().expect("seeded behavior policy")).unwrap(); - assert_eq!(behavior_policy["team_capable_override"], false); + assert!( + behavior_policy.get("team_capable_override").is_none(), + "team_capable_override should be absent (removed by migration 031)" + ); let capabilities: serde_json::Value = serde_json::from_str(pi.agent_capabilities.as_deref().expect("seeded capabilities")).unwrap(); diff --git a/crates/aionui-db/tests/registry_binary_agents_migration.rs b/crates/aionui-db/tests/registry_binary_agents_migration.rs index 2c9e85f80..879ddaf0d 100644 --- a/crates/aionui-db/tests/registry_binary_agents_migration.rs +++ b/crates/aionui-db/tests/registry_binary_agents_migration.rs @@ -28,6 +28,9 @@ async fn verified_registry_binary_agents_store_stable_registry_identity() { assert!(source.get("distribution").is_none()); assert!(source.get("version").is_none()); let policy: serde_json::Value = serde_json::from_str(row.behavior_policy.as_deref().unwrap()).unwrap(); - assert_eq!(policy["team_capable_override"], false); + assert!( + policy.get("team_capable_override").is_none(), + "{backend} team_capable_override should be absent" + ); } } diff --git a/crates/aionui-db/tests/registry_npx_agents_migration.rs b/crates/aionui-db/tests/registry_npx_agents_migration.rs index c32b360d2..be5bda1ff 100644 --- a/crates/aionui-db/tests/registry_npx_agents_migration.rs +++ b/crates/aionui-db/tests/registry_npx_agents_migration.rs @@ -73,6 +73,9 @@ async fn verified_registry_npx_agents_use_stable_packages_and_conservative_team_ assert_eq!(source["binary_name"], binary_name, "{backend} binary_name"); assert_eq!(source["bridge_binary"], "npx", "{backend} bridge_binary"); let policy: serde_json::Value = serde_json::from_str(row.behavior_policy.as_deref().unwrap()).unwrap(); - assert_eq!(policy["team_capable_override"], false, "{backend} team policy"); + assert!( + policy.get("team_capable_override").is_none(), + "{backend} team_capable_override should be absent" + ); } }