feat: replace subagent and skills with unified summon extension (#6964)

Signed-off-by: Travis Longwell <travis@block.xyz>
This commit is contained in:
tlongwell-block
2026-02-10 14:13:38 -05:00
committed by GitHub
parent 1168d7d9b1
commit 7ea19f5c83
26 changed files with 2616 additions and 1935 deletions
@@ -97,7 +97,10 @@ mod tests {
input_config.additional_system_prompt,
Some("test_instructions my_value".to_string())
);
assert!(recipe.extensions.is_none());
assert!(recipe
.extensions
.as_ref()
.is_none_or(|e| e.iter().all(|ext| ext.name() == "summon")));
assert!(settings.is_some());
let settings = settings.unwrap();
@@ -162,7 +165,10 @@ mod tests {
input_config.additional_system_prompt,
Some("test_instructions my_value".to_string())
);
assert!(recipe.extensions.is_none());
assert!(recipe
.extensions
.as_ref()
.is_none_or(|e| e.iter().all(|ext| ext.name() == "summon")));
assert!(settings.is_some());
let settings = settings.unwrap();
+12 -5
View File
@@ -600,11 +600,7 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
let recipe = session_config.recipe.as_ref();
agent
.apply_recipe_components(
recipe.and_then(|r| r.sub_recipes.clone()),
recipe.and_then(|r| r.response.clone()),
true,
)
.apply_recipe_components(recipe.and_then(|r| r.response.clone()), true)
.await;
let new_provider = match create(&resolved.provider_name, resolved.model_config).await {
@@ -643,6 +639,17 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
process::exit(1);
});
if let Some(recipe) = session_config.recipe.clone() {
if let Err(e) = session_manager
.update(&session_id)
.recipe(Some(recipe))
.apply()
.await
{
tracing::warn!("Failed to store recipe on session: {}", e);
}
}
if session_config.resume {
handle_resumed_session_workdir(&agent, &session_id, session_config.interactive).await;
}
+1 -1
View File
@@ -21,8 +21,8 @@ use tokio_util::task::AbortOnDropHandle;
pub use self::export::message_to_markdown;
pub use builder::{build_session, SessionBuilderConfig};
use console::Color;
use goose::agents::subagent_handler::SUBAGENT_TOOL_REQUEST_TYPE;
use goose::agents::AgentEvent;
use goose::agents::SUBAGENT_TOOL_REQUEST_TYPE;
use goose::permission::permission_confirmation::PrincipalType;
use goose::permission::Permission;
use goose::permission::PermissionConfirmation;
+7 -6
View File
@@ -314,8 +314,9 @@ fn render_tool_request(req: &ToolRequest, theme: Theme, debug: bool) {
Ok(call) => match call.name.to_string().as_str() {
"developer__text_editor" => render_text_editor_request(call, debug),
"developer__shell" => render_shell_request(call, debug),
"code_execution__execute" => render_execute_code_request(call, debug),
"subagent" => render_subagent_request(call, debug),
"execute" | "execute_code" => render_execute_code_request(call, debug),
"delegate" => render_delegate_request(call, debug),
"subagent" => render_delegate_request(call, debug),
"todo__write" => render_todo_request(call, debug),
_ => render_default_request(call, debug),
},
@@ -555,12 +556,12 @@ fn render_execute_code_request(call: &CallToolRequestParams, debug: bool) {
println!();
}
fn render_subagent_request(call: &CallToolRequestParams, debug: bool) {
fn render_delegate_request(call: &CallToolRequestParams, debug: bool) {
print_tool_header(call);
if let Some(args) = &call.arguments {
if let Some(Value::String(subrecipe)) = args.get("subrecipe") {
println!("{}: {}", style("subrecipe").dim(), style(subrecipe).cyan());
if let Some(Value::String(source)) = args.get("source") {
println!("{}: {}", style("source").dim(), style(source).cyan());
}
if let Some(Value::String(instructions)) = args.get("instructions") {
@@ -581,7 +582,7 @@ fn render_subagent_request(call: &CallToolRequestParams, debug: bool) {
print_params(&Some(params.clone()), 1, debug);
}
let skip_keys = ["subrecipe", "instructions", "parameters"];
let skip_keys = ["source", "instructions", "parameters"];
let mut other_args = serde_json::Map::new();
for (k, v) in args {
if !skip_keys.contains(&k.as_str()) {