feat(acp): allow session/new to request a Hidden session via _meta.hidden (#10811)

Signed-off-by: Matt Toohey <contact@matttoohey.com>
This commit is contained in:
Matt Toohey
2026-07-30 15:56:17 +10:00
committed by GitHub
parent 2caab70eaf
commit 2694fff7e3
+81 -4
View File
@@ -31,10 +31,7 @@ impl GooseAcpAgent {
validate_absolute_cwd(&args.cwd)?;
let config = Config::global();
let project_id = meta_string(args.meta.as_ref(), "projectId")?;
let session_type = match meta_string(args.meta.as_ref(), "client")? {
Some(_) => SessionType::User,
None => SessionType::Acp,
};
let session_type = session_type_from_meta(args.meta.as_ref())?;
let current_mode: GooseMode = config.get_goose_mode().unwrap_or_default();
let recipe = self.resolve_recipe_from_meta(args.meta.as_ref()).await?;
let session_name = match recipe.as_ref() {
@@ -251,6 +248,30 @@ fn model_config_from_recipe_settings(
.internal_err_ctx("Failed to build model config from recipe settings")
}
fn session_type_from_meta(
meta: Option<&Meta>,
) -> Result<SessionType, agent_client_protocol::Error> {
if meta_bool(meta, "hidden")? {
return Ok(SessionType::Hidden);
}
Ok(match meta_string(meta, "client")? {
Some(_) => SessionType::User,
None => SessionType::Acp,
})
}
fn meta_bool(meta: Option<&Meta>, key: &str) -> Result<bool, agent_client_protocol::Error> {
let Some(value) = meta.and_then(|m| m.get(key)) else {
return Ok(false);
};
if value.is_null() {
return Ok(false);
}
value.as_bool().ok_or_else(|| {
agent_client_protocol::Error::invalid_params().data(format!("{key} must be a boolean"))
})
}
fn meta_goose_extensions(
meta: Option<&Meta>,
) -> Result<Option<Vec<GooseExtension>>, agent_client_protocol::Error> {
@@ -266,3 +287,59 @@ fn meta_goose_extensions(
agent_client_protocol::Error::invalid_params().data(format!("enabledExtensions: {e}"))
})
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
fn meta(value: serde_json::Value) -> Meta {
match value {
serde_json::Value::Object(map) => map,
other => panic!("expected object, got {other}"),
}
}
#[test]
fn hidden_meta_yields_hidden_session() {
let meta = meta(json!({ "hidden": true }));
assert_eq!(
session_type_from_meta(Some(&meta)).unwrap(),
SessionType::Hidden
);
}
#[test]
fn hidden_overrides_client() {
let meta = meta(json!({ "hidden": true, "client": "desktop" }));
assert_eq!(
session_type_from_meta(Some(&meta)).unwrap(),
SessionType::Hidden
);
}
#[test]
fn absent_hidden_preserves_acp() {
assert_eq!(session_type_from_meta(None).unwrap(), SessionType::Acp);
let meta = meta(json!({ "hidden": false }));
assert_eq!(
session_type_from_meta(Some(&meta)).unwrap(),
SessionType::Acp
);
}
#[test]
fn non_bool_hidden_is_rejected() {
let meta = meta(json!({ "hidden": "yes", "client": "desktop" }));
assert!(session_type_from_meta(Some(&meta)).is_err());
}
#[test]
fn client_meta_yields_user_session() {
let meta = meta(json!({ "client": "desktop" }));
assert_eq!(
session_type_from_meta(Some(&meta)).unwrap(),
SessionType::User
);
}
}