feat(acp): add _goose/unstable/session/extensions/apply method (#11081)
Signed-off-by: Matt Toohey <contact@matttoohey.com>
This commit is contained in:
@@ -45,6 +45,25 @@ pub struct RemoveSessionExtensionRequest {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
/// Recreate the session's provider, keeping its current provider and model,
|
||||
/// so that the session's current extension list takes effect.
|
||||
///
|
||||
/// Useful after adding or removing session extensions when the provider
|
||||
/// forwards extensions to a downstream session (ACP harness providers such as
|
||||
/// claude-acp and codex-acp). Those providers snapshot the extension list when
|
||||
/// they are built, so extension changes only reach them on rebuild: the
|
||||
/// provider is replaced with a new instance whose downstream session is
|
||||
/// created with the updated extension list.
|
||||
///
|
||||
/// Providers that don't forward extensions pick up extension changes
|
||||
/// immediately; for them this call is not required.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(method = "_goose/unstable/session/extensions/apply", response = EmptyResponse)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplySessionExtensionsRequest {
|
||||
pub session_id: String,
|
||||
}
|
||||
|
||||
/// List all tools available in a session.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(method = "_goose/unstable/tools/list", response = GetToolsResponse)]
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
"requestType": "RemoveSessionExtensionRequest_unstable",
|
||||
"responseType": "EmptyResponse"
|
||||
},
|
||||
{
|
||||
"method": "_goose/unstable/session/extensions/apply",
|
||||
"requestType": "ApplySessionExtensionsRequest_unstable",
|
||||
"responseType": "EmptyResponse"
|
||||
},
|
||||
{
|
||||
"method": "_goose/unstable/tools/list",
|
||||
"requestType": "GetToolsRequest_unstable",
|
||||
|
||||
@@ -452,6 +452,20 @@
|
||||
"x-side": "agent",
|
||||
"x-method": "_goose/unstable/session/extensions/remove"
|
||||
},
|
||||
"ApplySessionExtensionsRequest_unstable": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"sessionId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"sessionId"
|
||||
],
|
||||
"description": "Recreate the session's provider, keeping its current provider and model,\nso that the session's current extension list takes effect.\n\nUseful after adding or removing session extensions when the provider\nforwards extensions to a downstream session (ACP harness providers such as\nclaude-acp and codex-acp). Those providers snapshot the extension list when\nthey are built, so extension changes only reach them on rebuild: the\nprovider is replaced with a new instance whose downstream session is\ncreated with the updated extension list.\n\nProviders that don't forward extensions pick up extension changes\nimmediately; for them this call is not required.",
|
||||
"x-side": "agent",
|
||||
"x-method": "_goose/unstable/session/extensions/apply"
|
||||
},
|
||||
"GetToolsRequest_unstable": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -6917,6 +6931,15 @@
|
||||
"description": "Params for _goose/unstable/session/extensions/remove",
|
||||
"title": "RemoveSessionExtensionRequest_unstable"
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ApplySessionExtensionsRequest_unstable"
|
||||
}
|
||||
],
|
||||
"description": "Params for _goose/unstable/session/extensions/apply",
|
||||
"title": "ApplySessionExtensionsRequest_unstable"
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
|
||||
@@ -12,5 +12,5 @@ pub mod transport;
|
||||
pub use common::{map_permission_response, PermissionDecision};
|
||||
pub use goose_sdk_types::{custom_notifications, custom_requests};
|
||||
pub use provider::{
|
||||
extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
resolve_extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ use tokio::sync::{mpsc, oneshot, Mutex as TokioMutex};
|
||||
use tokio_util::compat::{TokioAsyncReadCompatExt as _, TokioAsyncWriteCompatExt as _};
|
||||
|
||||
use crate::acp::{map_permission_response, PermissionDecision};
|
||||
use crate::config::{ExtensionConfig, GooseMode};
|
||||
use crate::config::{Config, ExtensionConfig, GooseMode};
|
||||
use crate::context_mgmt::format_message_for_compacting;
|
||||
use crate::conversation::message::{Message, MessageContent, TOOL_META_EXTERNAL_DISPATCH_KEY};
|
||||
use crate::conversation::Conversation;
|
||||
@@ -1435,7 +1435,33 @@ fn select_mode_id(candidates: &[String], modes: Option<&SessionModeState>) -> Op
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extension_configs_to_mcp_servers(configs: &[ExtensionConfig]) -> Vec<McpServer> {
|
||||
/// Extension configs are persisted unresolved: secrets stay in the keyring behind
|
||||
/// `env_keys`, and uris/headers may still hold `${VAR}` placeholders. Resolve them
|
||||
/// before handing the servers to the downstream agent, which launches them itself
|
||||
/// and so needs the real values. An extension that fails to resolve (e.g. a stale
|
||||
/// `env_keys` entry with no stored secret) is logged and skipped rather than
|
||||
/// failing the whole provider build, matching how the local extension path
|
||||
/// contains load errors to the one extension.
|
||||
pub async fn resolve_extension_configs_to_mcp_servers(
|
||||
configs: Vec<ExtensionConfig>,
|
||||
config: &Config,
|
||||
) -> Vec<McpServer> {
|
||||
let mut resolved = Vec::with_capacity(configs.len());
|
||||
for extension in configs {
|
||||
let name = extension.name();
|
||||
match extension.resolve(config).await {
|
||||
Ok(extension) => resolved.push(extension),
|
||||
Err(error) => tracing::warn!(
|
||||
extension = %name,
|
||||
%error,
|
||||
"skipping extension that failed to resolve; it will not be forwarded to the ACP agent"
|
||||
),
|
||||
}
|
||||
}
|
||||
extension_configs_to_mcp_servers(&resolved)
|
||||
}
|
||||
|
||||
fn extension_configs_to_mcp_servers(configs: &[ExtensionConfig]) -> Vec<McpServer> {
|
||||
let mut servers = Vec::new();
|
||||
|
||||
for config in configs {
|
||||
@@ -2597,6 +2623,112 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_resolve_extension_configs_to_mcp_servers_fills_in_secrets() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let config = Config::new_with_file_secrets(
|
||||
dir.path().join("config.yaml"),
|
||||
dir.path().join("secrets.yaml"),
|
||||
)
|
||||
.unwrap();
|
||||
config
|
||||
.set("GITHUB_TOKEN", &"ghp_xxxxxxxxxxxx", true)
|
||||
.unwrap();
|
||||
|
||||
let servers = resolve_extension_configs_to_mcp_servers(
|
||||
vec![
|
||||
ExtensionConfig::Stdio {
|
||||
name: "github-stdio".into(),
|
||||
description: String::new(),
|
||||
cmd: "/path/to/github-mcp-server".into(),
|
||||
args: vec![],
|
||||
envs: Envs::default(),
|
||||
env_keys: vec!["GITHUB_TOKEN".into()],
|
||||
timeout: None,
|
||||
cwd: None,
|
||||
bundled: None,
|
||||
available_tools: vec![],
|
||||
},
|
||||
ExtensionConfig::StreamableHttp {
|
||||
name: "github-http".into(),
|
||||
description: String::new(),
|
||||
uri: "https://api.githubcopilot.com/mcp/".into(),
|
||||
envs: Envs::default(),
|
||||
env_keys: vec!["GITHUB_TOKEN".into()],
|
||||
headers: HashMap::from([(
|
||||
"Authorization".into(),
|
||||
"Bearer ${GITHUB_TOKEN}".into(),
|
||||
)]),
|
||||
timeout: None,
|
||||
socket: None,
|
||||
bundled: None,
|
||||
available_tools: vec![],
|
||||
},
|
||||
],
|
||||
&config,
|
||||
)
|
||||
.await;
|
||||
|
||||
let McpServer::Stdio(stdio) = &servers[0] else {
|
||||
panic!("expected stdio server");
|
||||
};
|
||||
assert_eq!(stdio.env.len(), 1);
|
||||
assert_eq!(stdio.env[0].name, "GITHUB_TOKEN");
|
||||
assert_eq!(stdio.env[0].value, "ghp_xxxxxxxxxxxx");
|
||||
|
||||
let McpServer::Http(http) = &servers[1] else {
|
||||
panic!("expected http server");
|
||||
};
|
||||
assert_eq!(http.headers[0].value, "Bearer ghp_xxxxxxxxxxxx");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_resolve_extension_configs_to_mcp_servers_skips_unresolvable() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let config = Config::new_with_file_secrets(
|
||||
dir.path().join("config.yaml"),
|
||||
dir.path().join("secrets.yaml"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let servers = resolve_extension_configs_to_mcp_servers(
|
||||
vec![
|
||||
ExtensionConfig::Stdio {
|
||||
name: "missing-secret".into(),
|
||||
description: String::new(),
|
||||
cmd: "/path/to/server".into(),
|
||||
args: vec![],
|
||||
envs: Envs::default(),
|
||||
env_keys: vec!["NEVER_STORED_KEY".into()],
|
||||
timeout: None,
|
||||
cwd: None,
|
||||
bundled: None,
|
||||
available_tools: vec![],
|
||||
},
|
||||
ExtensionConfig::Stdio {
|
||||
name: "resolvable".into(),
|
||||
description: String::new(),
|
||||
cmd: "/path/to/server".into(),
|
||||
args: vec![],
|
||||
envs: Envs::default(),
|
||||
env_keys: vec![],
|
||||
timeout: None,
|
||||
cwd: None,
|
||||
bundled: None,
|
||||
available_tools: vec![],
|
||||
},
|
||||
],
|
||||
&config,
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_eq!(servers.len(), 1);
|
||||
let McpServer::Stdio(stdio) = &servers[0] else {
|
||||
panic!("expected stdio server");
|
||||
};
|
||||
assert_eq!(stdio.name, "resolvable");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sse_skips() {
|
||||
let config = ExtensionConfig::Sse {
|
||||
|
||||
@@ -45,6 +45,14 @@ impl GooseAcpAgent {
|
||||
self.on_remove_session_extension(req).await
|
||||
}
|
||||
|
||||
#[custom_method(ApplySessionExtensionsRequest)]
|
||||
async fn dispatch_apply_session_extensions(
|
||||
&self,
|
||||
req: ApplySessionExtensionsRequest,
|
||||
) -> Result<EmptyResponse, agent_client_protocol::Error> {
|
||||
self.on_apply_session_extensions(req).await
|
||||
}
|
||||
|
||||
#[custom_method(GetToolsRequest)]
|
||||
async fn dispatch_get_tools(
|
||||
&self,
|
||||
|
||||
@@ -31,6 +31,28 @@ impl GooseAcpAgent {
|
||||
Ok(EmptyResponse {})
|
||||
}
|
||||
|
||||
pub(super) async fn on_apply_session_extensions(
|
||||
&self,
|
||||
req: ApplySessionExtensionsRequest,
|
||||
) -> Result<EmptyResponse, agent_client_protocol::Error> {
|
||||
let session_id = &req.session_id;
|
||||
let agent = self.get_session_agent(session_id).await?;
|
||||
let provider = agent
|
||||
.provider()
|
||||
.await
|
||||
.internal_err_ctx("Failed to get provider")?;
|
||||
let provider_name = provider.get_name().to_string();
|
||||
let model_config = agent
|
||||
.model_config_for_session(session_id)
|
||||
.await
|
||||
.internal_err_ctx("Failed to resolve model config")?;
|
||||
agent
|
||||
.recreate_provider_for_session(session_id, &provider_name, model_config)
|
||||
.await
|
||||
.internal_err_ctx("Failed to recreate provider")?;
|
||||
Ok(EmptyResponse {})
|
||||
}
|
||||
|
||||
pub(super) async fn on_get_config_extensions(
|
||||
&self,
|
||||
) -> Result<GetConfigExtensionsResponse, agent_client_protocol::Error> {
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::acp::{
|
||||
extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
resolve_extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
};
|
||||
use crate::config::search_path::SearchPaths;
|
||||
use crate::config::{Config, GooseMode};
|
||||
@@ -75,7 +75,7 @@ impl ProviderDef for AmpAcpProvider {
|
||||
env: vec![],
|
||||
env_remove: vec![],
|
||||
work_dir: working_dir,
|
||||
mcp_servers: extension_configs_to_mcp_servers(&extensions),
|
||||
mcp_servers: resolve_extension_configs_to_mcp_servers(extensions, config).await,
|
||||
session_mode_id: mode_mapping[&goose_mode].first().cloned(),
|
||||
session_config_options: vec![],
|
||||
model_config_option_id: None,
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::acp::{
|
||||
extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
resolve_extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
};
|
||||
use crate::config::search_path::SearchPaths;
|
||||
use crate::config::{Config, GooseMode};
|
||||
@@ -79,7 +79,7 @@ impl ProviderDef for ClaudeAcpProvider {
|
||||
// Prevent nested-session detection in claude-agent-acp (wraps Claude Code)
|
||||
env_remove: vec!["CLAUDECODE".to_string()],
|
||||
work_dir: working_dir,
|
||||
mcp_servers: extension_configs_to_mcp_servers(&extensions),
|
||||
mcp_servers: resolve_extension_configs_to_mcp_servers(extensions, config).await,
|
||||
session_mode_id: mode_mapping[&goose_mode].first().cloned(),
|
||||
session_config_options: vec![],
|
||||
// claude-agent-acp advertises the model as a "model" select
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::acp::{
|
||||
extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
resolve_extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
};
|
||||
use crate::config::search_path::SearchPaths;
|
||||
use crate::config::{Config, GooseMode};
|
||||
@@ -61,7 +61,7 @@ impl ProviderDef for CodexAcpProvider {
|
||||
.with_npm()
|
||||
.resolve(CODEX_ACP_PROVIDER_NAME)?;
|
||||
let goose_mode = config.get_goose_mode().unwrap_or(GooseMode::Auto);
|
||||
let mcp_servers = extension_configs_to_mcp_servers(&extensions);
|
||||
let mcp_servers = resolve_extension_configs_to_mcp_servers(extensions, config).await;
|
||||
|
||||
let mode_mapping = HashMap::from([
|
||||
(GooseMode::Auto, vec!["agent-full-access".to_string()]),
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::acp::{
|
||||
extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
resolve_extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
};
|
||||
use crate::config::search_path::SearchPaths;
|
||||
use crate::config::{Config, GooseMode};
|
||||
@@ -89,7 +89,7 @@ impl ProviderDef for CopilotAcpProvider {
|
||||
env: vec![],
|
||||
env_remove: vec![],
|
||||
work_dir: working_dir,
|
||||
mcp_servers: extension_configs_to_mcp_servers(&extensions),
|
||||
mcp_servers: resolve_extension_configs_to_mcp_servers(extensions, config).await,
|
||||
session_mode_id: mode_mapping[&goose_mode].first().cloned(),
|
||||
session_config_options,
|
||||
model_config_option_id: Some("model".to_string()),
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::acp::{
|
||||
extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
resolve_extension_configs_to_mcp_servers, AcpProvider, AcpProviderConfig, ACP_CURRENT_MODEL,
|
||||
};
|
||||
use crate::config::search_path::SearchPaths;
|
||||
use crate::config::{Config, GooseMode};
|
||||
@@ -78,7 +78,7 @@ impl ProviderDef for PiAcpProvider {
|
||||
env: vec![],
|
||||
env_remove: vec![],
|
||||
work_dir: working_dir,
|
||||
mcp_servers: extension_configs_to_mcp_servers(&extensions),
|
||||
mcp_servers: resolve_extension_configs_to_mcp_servers(extensions, config).await,
|
||||
session_mode_id: None,
|
||||
session_config_options,
|
||||
model_config_option_id: Some("model".to_string()),
|
||||
|
||||
@@ -397,6 +397,35 @@ fn test_custom_session_extensions_add_list_remove() {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_custom_session_extensions_apply_recreates_provider() {
|
||||
write_acp_global_config(DEFAULT_ACP_TEST_CONFIG);
|
||||
run_test(async move {
|
||||
let openai = OpenAiFixture::new(vec![], Arc::new(EnforceSessionId::default())).await;
|
||||
let mut conn = AcpServerConnection::new(TestConnectionConfig::default(), openai).await;
|
||||
|
||||
let SessionData { session, .. } = conn.new_session().await.unwrap();
|
||||
let session_id = session.session_id().0.clone();
|
||||
|
||||
let result = send_custom(
|
||||
conn.cx(),
|
||||
"_goose/unstable/session/extensions/apply",
|
||||
serde_json::json!({ "sessionId": session_id.clone() }),
|
||||
)
|
||||
.await;
|
||||
assert!(result.is_ok(), "expected ok, got: {:?}", result);
|
||||
|
||||
let result = send_custom(
|
||||
conn.cx(),
|
||||
"_goose/unstable/session/extensions/apply",
|
||||
serde_json::json!({ "sessionId": "missing-session" }),
|
||||
)
|
||||
.await;
|
||||
assert!(result.is_err(), "apply for unknown session should fail");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_custom_get_available_extensions() {
|
||||
|
||||
@@ -11,6 +11,7 @@ import type { Client } from "@agentclientprotocol/sdk";
|
||||
import type {
|
||||
AddConfigExtensionRequest_unstable,
|
||||
AddSessionExtensionRequest_unstable,
|
||||
ApplySessionExtensionsRequest_unstable,
|
||||
AppsDeleteRequest_unstable,
|
||||
AppsDeleteResponse_unstable,
|
||||
AppsExportRequest_unstable,
|
||||
@@ -297,6 +298,15 @@ export class GooseExtClient {
|
||||
);
|
||||
}
|
||||
|
||||
async sessionExtensionsApply_unstable(
|
||||
params: ApplySessionExtensionsRequest_unstable,
|
||||
): Promise<void> {
|
||||
await this.conn.extMethod(
|
||||
"_goose/unstable/session/extensions/apply",
|
||||
params,
|
||||
);
|
||||
}
|
||||
|
||||
async toolsList_unstable(
|
||||
params: GetToolsRequest_unstable,
|
||||
): Promise<GetToolsResponse_unstable> {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -254,6 +254,24 @@ export type RemoveSessionExtensionRequest_unstable = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Recreate the session's provider, keeping its current provider and model,
|
||||
* so that the session's current extension list takes effect.
|
||||
*
|
||||
* Useful after adding or removing session extensions when the provider
|
||||
* forwards extensions to a downstream session (ACP harness providers such as
|
||||
* claude-acp and codex-acp). Those providers snapshot the extension list when
|
||||
* they are built, so extension changes only reach them on rebuild: the
|
||||
* provider is replaced with a new instance whose downstream session is
|
||||
* created with the updated extension list.
|
||||
*
|
||||
* Providers that don't forward extensions pick up extension changes
|
||||
* immediately; for them this call is not required.
|
||||
*/
|
||||
export type ApplySessionExtensionsRequest_unstable = {
|
||||
sessionId: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* List all tools available in a session.
|
||||
*/
|
||||
@@ -2637,7 +2655,7 @@ export type RecipeParamsAction = 'submit' | 'cancel';
|
||||
export type ExtRequest = {
|
||||
id: string;
|
||||
method: string;
|
||||
params?: AddSessionExtensionRequest_unstable | RemoveSessionExtensionRequest_unstable | GetToolsRequest_unstable | SetToolPermissionsRequest_unstable | GooseToolCallRequest_unstable | ReadResourceRequest_unstable | AppsListRequest_unstable | AppsExportRequest_unstable | AppsImportRequest_unstable | AppsDeleteRequest_unstable | UpdateWorkingDirRequest_unstable | SetSessionSystemPromptRequest_unstable | SteerSessionRequest_unstable | DiagnosticsGetRequest_unstable | ListPromptsRequest_unstable | GetPromptRequest_unstable | SavePromptRequest_unstable | ResetPromptRequest_unstable | DeleteSessionRequest | GetConfigExtensionsRequest_unstable | GetAvailableExtensionsRequest_unstable | AddConfigExtensionRequest_unstable | RemoveConfigExtensionRequest_unstable | SetConfigExtensionEnabledRequest_unstable | GetSessionExtensionsRequest_unstable | ListProvidersRequest_unstable | ProviderSupportedModelsListRequest_unstable | ProviderCatalogListRequest_unstable | ProviderSetupCatalogListRequest_unstable | ProviderCatalogTemplateRequest_unstable | CustomProviderCreateRequest_unstable | CustomProviderReadRequest_unstable | CustomProviderUpdateRequest_unstable | CustomProviderDeleteRequest_unstable | RefreshProviderInventoryRequest_unstable | ProviderConfigReadRequest_unstable | ProviderConfigStatusRequest_unstable | ProviderConfigSaveRequest_unstable | ProviderConfigDeleteRequest_unstable | ProviderConfigAuthenticateRequest_unstable | ProviderSecretsListRequest_unstable | ProviderSecretDeleteRequest_unstable | CanonicalModelInfoRequest_unstable | PreferencesReadRequest_unstable | PreferencesSaveRequest_unstable | PreferencesRemoveRequest_unstable | ConfigReadRequest_unstable | ConfigUpsertRequest_unstable | ConfigRemoveRequest_unstable | ConfigReadAllRequest_unstable | DefaultsReadRequest_unstable | DefaultsSaveRequest_unstable | DefaultsClearRequest_unstable | OnboardingImportScanRequest_unstable | OnboardingImportApplyRequest_unstable | ExportSessionRequest_unstable | ImportSessionRequest_unstable | ShareSessionNostrRequest_unstable | EncodeRecipeRequest_unstable | DecodeRecipeRequest_unstable | ScanRecipeRequest_unstable | ListRecipesRequest_unstable | DeleteRecipeRequest_unstable | ScheduleRecipeRequest_unstable | SetRecipeSlashCommandRequest_unstable | SaveRecipeRequest_unstable | ParseRecipeRequest_unstable | RecipeToYamlRequest_unstable | ListSchedulesRequest_unstable | ListScheduleSessionsRequest_unstable | CreateScheduleRequest_unstable | DeleteScheduleRequest_unstable | PauseScheduleRequest_unstable | UnpauseScheduleRequest_unstable | UpdateScheduleRequest_unstable | RunScheduleNowRequest_unstable | KillRunningJobRequest_unstable | InspectRunningJobRequest_unstable | GetSessionInfoRequest_unstable | TruncateSessionConversationRequest_unstable | UpdateSessionProjectRequest_unstable | RenameSessionRequest_unstable | ArchiveSessionRequest_unstable | UnarchiveSessionRequest_unstable | CreateSourceRequest_unstable | ListSourcesRequest_unstable | ListAgentMentionsRequest_unstable | ListSlashCommandsRequest_unstable | UpdateSourceRequest_unstable | DeleteSourceRequest_unstable | ExportSourceRequest_unstable | ImportSourcesRequest_unstable | DictationTranscribeRequest_unstable | DictationConfigRequest_unstable | DictationSecretSaveRequest_unstable | DictationSecretDeleteRequest_unstable | DictationModelsListRequest_unstable | DictationModelDownloadRequest_unstable | DictationModelDownloadProgressRequest_unstable | DictationModelCancelRequest_unstable | DictationModelDeleteRequest_unstable | DictationModelSelectRequest_unstable | LocalInferenceModelsListRequest_unstable | LocalInferenceModelDownloadRequest_unstable | LocalInferenceModelDownloadProgressRequest_unstable | LocalInferenceModelDownloadCancelRequest_unstable | LocalInferenceModelDeleteRequest_unstable | LocalInferenceModelEvictRequest_unstable | LocalInferenceModelSettingsReadRequest_unstable | LocalInferenceModelSettingsUpdateRequest_unstable | LocalInferenceHuggingFaceSearchRequest_unstable | LocalInferenceHuggingFaceRepoVariantsRequest_unstable | LocalInferenceBuiltinChatTemplatesListRequest_unstable | {
|
||||
params?: AddSessionExtensionRequest_unstable | RemoveSessionExtensionRequest_unstable | ApplySessionExtensionsRequest_unstable | GetToolsRequest_unstable | SetToolPermissionsRequest_unstable | GooseToolCallRequest_unstable | ReadResourceRequest_unstable | AppsListRequest_unstable | AppsExportRequest_unstable | AppsImportRequest_unstable | AppsDeleteRequest_unstable | UpdateWorkingDirRequest_unstable | SetSessionSystemPromptRequest_unstable | SteerSessionRequest_unstable | DiagnosticsGetRequest_unstable | ListPromptsRequest_unstable | GetPromptRequest_unstable | SavePromptRequest_unstable | ResetPromptRequest_unstable | DeleteSessionRequest | GetConfigExtensionsRequest_unstable | GetAvailableExtensionsRequest_unstable | AddConfigExtensionRequest_unstable | RemoveConfigExtensionRequest_unstable | SetConfigExtensionEnabledRequest_unstable | GetSessionExtensionsRequest_unstable | ListProvidersRequest_unstable | ProviderSupportedModelsListRequest_unstable | ProviderCatalogListRequest_unstable | ProviderSetupCatalogListRequest_unstable | ProviderCatalogTemplateRequest_unstable | CustomProviderCreateRequest_unstable | CustomProviderReadRequest_unstable | CustomProviderUpdateRequest_unstable | CustomProviderDeleteRequest_unstable | RefreshProviderInventoryRequest_unstable | ProviderConfigReadRequest_unstable | ProviderConfigStatusRequest_unstable | ProviderConfigSaveRequest_unstable | ProviderConfigDeleteRequest_unstable | ProviderConfigAuthenticateRequest_unstable | ProviderSecretsListRequest_unstable | ProviderSecretDeleteRequest_unstable | CanonicalModelInfoRequest_unstable | PreferencesReadRequest_unstable | PreferencesSaveRequest_unstable | PreferencesRemoveRequest_unstable | ConfigReadRequest_unstable | ConfigUpsertRequest_unstable | ConfigRemoveRequest_unstable | ConfigReadAllRequest_unstable | DefaultsReadRequest_unstable | DefaultsSaveRequest_unstable | DefaultsClearRequest_unstable | OnboardingImportScanRequest_unstable | OnboardingImportApplyRequest_unstable | ExportSessionRequest_unstable | ImportSessionRequest_unstable | ShareSessionNostrRequest_unstable | EncodeRecipeRequest_unstable | DecodeRecipeRequest_unstable | ScanRecipeRequest_unstable | ListRecipesRequest_unstable | DeleteRecipeRequest_unstable | ScheduleRecipeRequest_unstable | SetRecipeSlashCommandRequest_unstable | SaveRecipeRequest_unstable | ParseRecipeRequest_unstable | RecipeToYamlRequest_unstable | ListSchedulesRequest_unstable | ListScheduleSessionsRequest_unstable | CreateScheduleRequest_unstable | DeleteScheduleRequest_unstable | PauseScheduleRequest_unstable | UnpauseScheduleRequest_unstable | UpdateScheduleRequest_unstable | RunScheduleNowRequest_unstable | KillRunningJobRequest_unstable | InspectRunningJobRequest_unstable | GetSessionInfoRequest_unstable | TruncateSessionConversationRequest_unstable | UpdateSessionProjectRequest_unstable | RenameSessionRequest_unstable | ArchiveSessionRequest_unstable | UnarchiveSessionRequest_unstable | CreateSourceRequest_unstable | ListSourcesRequest_unstable | ListAgentMentionsRequest_unstable | ListSlashCommandsRequest_unstable | UpdateSourceRequest_unstable | DeleteSourceRequest_unstable | ExportSourceRequest_unstable | ImportSourcesRequest_unstable | DictationTranscribeRequest_unstable | DictationConfigRequest_unstable | DictationSecretSaveRequest_unstable | DictationSecretDeleteRequest_unstable | DictationModelsListRequest_unstable | DictationModelDownloadRequest_unstable | DictationModelDownloadProgressRequest_unstable | DictationModelCancelRequest_unstable | DictationModelDeleteRequest_unstable | DictationModelSelectRequest_unstable | LocalInferenceModelsListRequest_unstable | LocalInferenceModelDownloadRequest_unstable | LocalInferenceModelDownloadProgressRequest_unstable | LocalInferenceModelDownloadCancelRequest_unstable | LocalInferenceModelDeleteRequest_unstable | LocalInferenceModelEvictRequest_unstable | LocalInferenceModelSettingsReadRequest_unstable | LocalInferenceModelSettingsUpdateRequest_unstable | LocalInferenceHuggingFaceSearchRequest_unstable | LocalInferenceHuggingFaceRepoVariantsRequest_unstable | LocalInferenceBuiltinChatTemplatesListRequest_unstable | {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
};
|
||||
|
||||
@@ -208,6 +208,24 @@ export const zRemoveSessionExtensionRequest_unstable = z.object({
|
||||
name: z.string()
|
||||
});
|
||||
|
||||
/**
|
||||
* Recreate the session's provider, keeping its current provider and model,
|
||||
* so that the session's current extension list takes effect.
|
||||
*
|
||||
* Useful after adding or removing session extensions when the provider
|
||||
* forwards extensions to a downstream session (ACP harness providers such as
|
||||
* claude-acp and codex-acp). Those providers snapshot the extension list when
|
||||
* they are built, so extension changes only reach them on rebuild: the
|
||||
* provider is replaced with a new instance whose downstream session is
|
||||
* created with the updated extension list.
|
||||
*
|
||||
* Providers that don't forward extensions pick up extension changes
|
||||
* immediately; for them this call is not required.
|
||||
*/
|
||||
export const zApplySessionExtensionsRequest_unstable = z.object({
|
||||
sessionId: z.string()
|
||||
});
|
||||
|
||||
/**
|
||||
* List all tools available in a session.
|
||||
*/
|
||||
@@ -2832,6 +2850,7 @@ export const zExtRequest = z.object({
|
||||
z.union([
|
||||
zAddSessionExtensionRequest_unstable,
|
||||
zRemoveSessionExtensionRequest_unstable,
|
||||
zApplySessionExtensionsRequest_unstable,
|
||||
zGetToolsRequest_unstable,
|
||||
zSetToolPermissionsRequest_unstable,
|
||||
zGooseToolCallRequest_unstable,
|
||||
|
||||
Reference in New Issue
Block a user