diff --git a/crates/goose-sdk-types/src/custom_requests.rs b/crates/goose-sdk-types/src/custom_requests.rs index b90515977cd7..f9b0bd8924a1 100644 --- a/crates/goose-sdk-types/src/custom_requests.rs +++ b/crates/goose-sdk-types/src/custom_requests.rs @@ -1,4 +1,4 @@ -use agent_client_protocol::schema::{ContentBlock, McpServer}; +use agent_client_protocol::schema::{ContentBlock, McpServer, SessionInfo}; use agent_client_protocol::{JsonRpcRequest, JsonRpcResponse}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -474,6 +474,23 @@ pub struct DictationSecretDeleteRequest { pub provider: String, } +/// Return list-style metadata for a single session without loading the conversation. +#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)] +#[request( + method = "_goose/unstable/session/info", + response = GetSessionInfoResponse +)] +#[serde(rename_all = "camelCase")] +pub struct GetSessionInfoRequest { + pub session_id: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, JsonRpcResponse)] +#[serde(rename_all = "camelCase")] +pub struct GetSessionInfoResponse { + pub session: SessionInfo, +} + /// Update the project association for a session. #[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)] #[request(method = "_goose/unstable/session/project/update", response = EmptyResponse)] diff --git a/crates/goose/acp-meta.json b/crates/goose/acp-meta.json index 8d5be7fe34b8..27294da66c62 100644 --- a/crates/goose/acp-meta.json +++ b/crates/goose/acp-meta.json @@ -195,6 +195,11 @@ "requestType": "ImportSessionRequest_unstable", "responseType": "ImportSessionResponse_unstable" }, + { + "method": "_goose/unstable/session/info", + "requestType": "GetSessionInfoRequest_unstable", + "responseType": "GetSessionInfoResponse_unstable" + }, { "method": "_goose/unstable/elicitation/respond", "requestType": "ElicitationRespondRequest_unstable", diff --git a/crates/goose/acp-schema.json b/crates/goose/acp-schema.json index e818403b5b3a..97732c520210 100644 --- a/crates/goose/acp-schema.json +++ b/crates/goose/acp-schema.json @@ -2690,6 +2690,84 @@ "x-side": "agent", "x-method": "_goose/unstable/session/import" }, + "GetSessionInfoRequest_unstable": { + "type": "object", + "properties": { + "sessionId": { + "type": "string" + } + }, + "required": [ + "sessionId" + ], + "description": "Return list-style metadata for a single session without loading the conversation.", + "x-side": "agent", + "x-method": "_goose/unstable/session/info" + }, + "GetSessionInfoResponse_unstable": { + "type": "object", + "properties": { + "session": { + "$ref": "#/$defs/SessionInfo" + } + }, + "required": [ + "session" + ], + "x-side": "agent", + "x-method": "_goose/unstable/session/info" + }, + "SessionInfo": { + "type": "object", + "properties": { + "sessionId": { + "$ref": "#/$defs/SessionId", + "description": "Unique identifier for the session" + }, + "cwd": { + "type": "string", + "description": "The working directory for this session. Must be an absolute path." + }, + "additionalDirectories": { + "type": "array", + "items": { + "type": "string" + }, + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthoritative ordered additional workspace roots for this session. Each path must be absolute.\n\nWhen omitted or empty, there are no additional roots for the session." + }, + "title": { + "type": [ + "string", + "null" + ], + "description": "Human-readable title for the session" + }, + "updatedAt": { + "type": [ + "string", + "null" + ], + "description": "ISO 8601 timestamp of last activity" + }, + "_meta": { + "type": [ + "object", + "null" + ], + "additionalProperties": {}, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + } + }, + "required": [ + "sessionId", + "cwd" + ], + "description": "Information about a session returned by session/list" + }, + "SessionId": { + "type": "string", + "description": "A unique identifier for a conversation session between a client and agent.\n\nSessions maintain their own context, conversation history, and state,\nallowing multiple independent interactions with the same agent.\n\nSee protocol docs: [Session ID](https://agentclientprotocol.com/protocol/session-setup#session-id)" + }, "ElicitationRespondRequest_unstable": { "type": "object", "properties": { @@ -4041,6 +4119,15 @@ "description": "Params for _goose/unstable/session/import", "title": "ImportSessionRequest_unstable" }, + { + "allOf": [ + { + "$ref": "#/$defs/GetSessionInfoRequest_unstable" + } + ], + "description": "Params for _goose/unstable/session/info", + "title": "GetSessionInfoRequest_unstable" + }, { "allOf": [ { @@ -4476,6 +4563,14 @@ ], "title": "ImportSessionResponse_unstable" }, + { + "allOf": [ + { + "$ref": "#/$defs/GetSessionInfoResponse_unstable" + } + ], + "title": "GetSessionInfoResponse_unstable" + }, { "allOf": [ { diff --git a/crates/goose/src/acp/response_builder.rs b/crates/goose/src/acp/response_builder.rs index dfa7bfb7b423..41789bb81b72 100644 --- a/crates/goose/src/acp/response_builder.rs +++ b/crates/goose/src/acp/response_builder.rs @@ -5,8 +5,8 @@ use crate::session::Session; use agent_client_protocol::schema::{ AvailableCommand, AvailableCommandInput, AvailableCommandsUpdate, ModelId, ModelInfo, SessionConfigOption, SessionConfigOptionCategory, SessionConfigSelectOption, SessionId, - SessionMode, SessionModeId, SessionModeState, SessionModelState, SessionNotification, - SessionUpdate, UnstructuredCommandInput, + SessionInfo, SessionMode, SessionModeId, SessionModeState, SessionModelState, + SessionNotification, SessionUpdate, UnstructuredCommandInput, }; use agent_client_protocol::{Client, ConnectionTo}; use goose_providers::thinking::ThinkingEffort; @@ -21,6 +21,64 @@ pub(super) fn session_provider_selection(session: &Session) -> &str { .unwrap_or(DEFAULT_PROVIDER_ID) } +pub(super) fn session_meta(session: &Session) -> serde_json::Map { + let mut meta = serde_json::Map::new(); + meta.insert( + "messageCount".to_string(), + serde_json::Value::Number(session.message_count.into()), + ); + meta.insert( + "createdAt".to_string(), + serde_json::Value::String(session.created_at.to_rfc3339()), + ); + if let Some(ref archived_at) = session.archived_at { + meta.insert( + "archivedAt".to_string(), + serde_json::Value::String(archived_at.to_rfc3339()), + ); + } + meta.insert( + "userSetName".to_string(), + serde_json::Value::Bool(session.user_set_name), + ); + meta.insert( + "hasRecipe".to_string(), + serde_json::Value::Bool(session.recipe.is_some()), + ); + + if let Some(ref pid) = session.project_id { + meta.insert( + "projectId".to_string(), + serde_json::Value::String(pid.clone()), + ); + } + if let Some(ref provider) = session.provider_name { + meta.insert( + "providerId".to_string(), + serde_json::Value::String(provider.clone()), + ); + } + if let Some(ref mc) = session.model_config { + meta.insert( + "modelId".to_string(), + serde_json::Value::String(mc.model_name.clone()), + ); + } + meta +} + +pub(super) fn build_session_info(session: Session) -> SessionInfo { + let meta = session_meta(&session); + let title = session.display_title(); + let mut info = SessionInfo::new(SessionId::new(session.id), session.working_dir) + .updated_at(session.updated_at.to_rfc3339()) + .meta(meta); + if let Some(title) = title { + info = info.title(title); + } + info +} + pub(super) fn build_model_state( current_model: &str, inventory: &ProviderInventoryEntry, diff --git a/crates/goose/src/acp/server.rs b/crates/goose/src/acp/server.rs index 31df35f0dc33..1883fec3b66a 100644 --- a/crates/goose/src/acp/server.rs +++ b/crates/goose/src/acp/server.rs @@ -3,8 +3,8 @@ use crate::acp::custom_requests::*; use crate::acp::fs::AcpTools; pub(super) use crate::acp::response_builder::{ build_config_options, build_mode_state, build_model_state, build_provider_options, - build_session_setup_config, send_session_setup_notifications, session_provider_selection, - should_refresh_inventory_for_session_init, + build_session_info, build_session_setup_config, send_session_setup_notifications, session_meta, + session_provider_selection, should_refresh_inventory_for_session_init, }; use crate::acp::tools::AcpAwareToolMeta; use crate::acp::{PermissionDecision, ACP_CURRENT_MODEL}; @@ -222,52 +222,6 @@ pub(super) fn sid_short(id: &str) -> String { id.chars().take(8).collect() } -pub(super) fn session_meta(session: &Session) -> serde_json::Map { - let mut meta = serde_json::Map::new(); - meta.insert( - "messageCount".to_string(), - serde_json::Value::Number(session.message_count.into()), - ); - meta.insert( - "createdAt".to_string(), - serde_json::Value::String(session.created_at.to_rfc3339()), - ); - if let Some(ref archived_at) = session.archived_at { - meta.insert( - "archivedAt".to_string(), - serde_json::Value::String(archived_at.to_rfc3339()), - ); - } - meta.insert( - "userSetName".to_string(), - serde_json::Value::Bool(session.user_set_name), - ); - meta.insert( - "hasRecipe".to_string(), - serde_json::Value::Bool(session.recipe.is_some()), - ); - - if let Some(ref pid) = session.project_id { - meta.insert( - "projectId".to_string(), - serde_json::Value::String(pid.clone()), - ); - } - if let Some(ref provider) = session.provider_name { - meta.insert( - "providerId".to_string(), - serde_json::Value::String(provider.clone()), - ); - } - if let Some(ref mc) = session.model_config { - meta.insert( - "modelId".to_string(), - serde_json::Value::String(mc.model_name.clone()), - ); - } - meta -} - fn meta_string( meta: Option<&Meta>, key: &str, diff --git a/crates/goose/src/acp/server/custom_dispatch.rs b/crates/goose/src/acp/server/custom_dispatch.rs index 91c1377cfcee..943685b5d01b 100644 --- a/crates/goose/src/acp/server/custom_dispatch.rs +++ b/crates/goose/src/acp/server/custom_dispatch.rs @@ -321,6 +321,14 @@ impl GooseAcpAgent { self.on_import_session(req).await } + #[custom_method(GetSessionInfoRequest)] + async fn dispatch_get_session_info( + &self, + req: GetSessionInfoRequest, + ) -> Result { + self.on_get_session_info(req).await + } + #[custom_method(ElicitationRespondRequest)] async fn dispatch_elicitation_respond( &self, diff --git a/crates/goose/src/acp/server/list_sessions.rs b/crates/goose/src/acp/server/list_sessions.rs index eea716af1124..ada46233c8b9 100644 --- a/crates/goose/src/acp/server/list_sessions.rs +++ b/crates/goose/src/acp/server/list_sessions.rs @@ -1,10 +1,8 @@ -use super::{meta_string, session_meta, GooseAcpAgent, ResultExt}; +use super::{build_session_info, meta_string, GooseAcpAgent, ResultExt}; use crate::session::session_manager::{ SessionListCursor, SessionListFilters, SessionListPageQuery, SessionType, }; -use agent_client_protocol::schema::{ - ListSessionsRequest, ListSessionsResponse, Meta, SessionId, SessionInfo, -}; +use agent_client_protocol::schema::{ListSessionsRequest, ListSessionsResponse, Meta, SessionInfo}; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _}; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; @@ -180,21 +178,8 @@ impl GooseAcpAgent { }) .await .internal_err()?; - let session_infos: Vec = page - .sessions - .into_iter() - .map(|s| { - let meta = session_meta(&s); - let title = s.display_title(); - let mut info = SessionInfo::new(SessionId::new(s.id), s.working_dir) - .updated_at(s.updated_at.to_rfc3339()) - .meta(meta); - if let Some(t) = title { - info = info.title(t); - } - info - }) - .collect(); + let session_infos: Vec = + page.sessions.into_iter().map(build_session_info).collect(); let next_cursor = page .next_cursor .as_ref() diff --git a/crates/goose/src/acp/server/manage_sessions.rs b/crates/goose/src/acp/server/manage_sessions.rs index 8e5163bd17ac..a3382c208be5 100644 --- a/crates/goose/src/acp/server/manage_sessions.rs +++ b/crates/goose/src/acp/server/manage_sessions.rs @@ -117,6 +117,31 @@ impl GooseAcpAgent { }) } + pub(super) async fn on_get_session_info( + &self, + req: GetSessionInfoRequest, + ) -> Result { + let session_id = req.session_id.trim(); + if session_id.is_empty() { + return Err( + agent_client_protocol::Error::invalid_params().data("sessionId cannot be empty") + ); + } + + let session = self + .session_manager + .get_session(session_id, false) + .await + .map_err(|_| { + agent_client_protocol::Error::resource_not_found(Some(session_id.to_string())) + .data(format!("Session not found: {}", session_id)) + })?; + + Ok(GetSessionInfoResponse { + session: build_session_info(session), + }) + } + pub(super) async fn on_update_session_project( &self, req: UpdateSessionProjectRequest, diff --git a/crates/goose/tests/acp_server_test.rs b/crates/goose/tests/acp_server_test.rs index d1b254f1615a..2407d2062b9e 100644 --- a/crates/goose/tests/acp_server_test.rs +++ b/crates/goose/tests/acp_server_test.rs @@ -24,6 +24,7 @@ use common_tests::{ }; use goose::config::GooseMode; use goose::conversation::message::Message; +use goose::custom_requests::{GetSessionInfoRequest, GetSessionInfoResponse}; use goose::session::{SessionManager, SessionType}; use std::path::Path; @@ -99,6 +100,17 @@ async fn list_sessions_request( .map_err(Into::into) } +async fn get_session_info_request( + conn: &AcpServerConnection, + request: GetSessionInfoRequest, +) -> anyhow::Result { + conn.cx() + .send_request(request) + .block_task() + .await + .map_err(Into::into) +} + fn assert_invalid_params(error: anyhow::Error) { let acp_error = error.downcast::().unwrap(); assert_eq!(acp_error.code, ErrorCode::InvalidParams); @@ -287,6 +299,55 @@ fn test_list_sessions_invalid_params() { }); } +#[test] +fn test_get_session_info() { + run_test(async { + let data_root = tempfile::tempdir().unwrap(); + let cwd = Path::new("/tmp/acp-session-info"); + let session_manager = SessionManager::new(data_root.path().to_path_buf()); + let session = session_manager + .create_session( + cwd.to_path_buf(), + "Session info".to_string(), + SessionType::Acp, + GooseMode::default(), + ) + .await + .unwrap(); + session_manager + .add_message(&session.id, &Message::user().with_text("hello")) + .await + .unwrap(); + let conn = new_connection(data_root.path()).await; + + let response = get_session_info_request( + &conn, + GetSessionInfoRequest { + session_id: session.id.clone(), + }, + ) + .await + .unwrap(); + + assert_eq!( + response.session.session_id, + agent_client_protocol::schema::SessionId::new(session.id) + ); + assert_eq!(response.session.cwd, cwd.to_path_buf()); + assert_eq!(response.session.title.as_deref(), Some("Session info")); + assert!(response.session.updated_at.is_some()); + + let meta = response + .session + .meta + .expect("session info should include meta"); + assert!(meta.get("createdAt").and_then(|v| v.as_str()).is_some()); + assert_eq!(meta.get("messageCount"), Some(&serde_json::json!(1))); + assert_eq!(meta.get("userSetName"), Some(&serde_json::json!(false))); + assert_eq!(meta.get("hasRecipe"), Some(&serde_json::json!(false))); + }); +} + #[test] fn test_session_name_update_notification() { run_test(async { run_session_name_update_notification::().await }); diff --git a/ui/sdk/src/generated/client.gen.ts b/ui/sdk/src/generated/client.gen.ts index 27a00c33eeb8..72a22590f7df 100644 --- a/ui/sdk/src/generated/client.gen.ts +++ b/ui/sdk/src/generated/client.gen.ts @@ -52,6 +52,8 @@ import type { GetConfigExtensionsResponse_unstable, GetSessionExtensionsRequest_unstable, GetSessionExtensionsResponse_unstable, + GetSessionInfoRequest_unstable, + GetSessionInfoResponse_unstable, GetToolsRequest_unstable, GetToolsResponse_unstable, GooseSessionNotification_unstable, @@ -122,6 +124,7 @@ import { zGetAvailableExtensionsResponse_unstable, zGetConfigExtensionsResponse_unstable, zGetSessionExtensionsResponse_unstable, + zGetSessionInfoResponse_unstable, zGetToolsResponse_unstable, zGooseSessionNotification_unstable, zGooseToolCallResponse_unstable, @@ -561,6 +564,18 @@ export class GooseExtClient { ) as ImportSessionResponse_unstable; } + async sessionInfo_unstable( + params: GetSessionInfoRequest_unstable, + ): Promise { + const raw = await this.conn.extMethod( + "_goose/unstable/session/info", + params, + ); + return zGetSessionInfoResponse_unstable.parse( + raw, + ) as GetSessionInfoResponse_unstable; + } + async elicitationRespond_unstable( params: ElicitationRespondRequest_unstable, ): Promise { diff --git a/ui/sdk/src/generated/index.ts b/ui/sdk/src/generated/index.ts index 6ae520e74860..77d32c437591 100644 --- a/ui/sdk/src/generated/index.ts +++ b/ui/sdk/src/generated/index.ts @@ -1,6 +1,6 @@ // This file is auto-generated by @hey-api/openapi-ts -export type { AddConfigExtensionRequest_unstable, AddExtensionRequest_unstable, Annotations, ArchiveSessionRequest_unstable, AudioContent, BlobResourceContents, ContentBlock, CreateSourceRequest_unstable, CreateSourceResponse_unstable, CustomProviderConfigDto, CustomProviderCreateRequest_unstable, CustomProviderCreateResponse_unstable, CustomProviderDeleteRequest_unstable, CustomProviderDeleteResponse_unstable, CustomProviderReadRequest_unstable, CustomProviderReadResponse_unstable, CustomProviderUpdateRequest_unstable, CustomProviderUpdateResponse_unstable, DefaultsReadRequest_unstable, DefaultsReadResponse_unstable, DefaultsSaveRequest_unstable, DeleteSessionRequest, DeleteSourceRequest_unstable, DictationConfigRequest_unstable, DictationConfigResponse_unstable, DictationDownloadProgress, DictationLocalModelStatus, DictationModelCancelRequest_unstable, DictationModelDeleteRequest_unstable, DictationModelDownloadProgressRequest_unstable, DictationModelDownloadProgressResponse_unstable, DictationModelDownloadRequest_unstable, DictationModelOption, DictationModelSelectRequest_unstable, DictationModelsListRequest_unstable, DictationModelsListResponse_unstable, DictationProviderStatusEntry, DictationSecretDeleteRequest_unstable, DictationSecretSaveRequest_unstable, DictationTranscribeRequest_unstable, DictationTranscribeResponse_unstable, ElicitationRespondRequest_unstable, EmbeddedResource, EmbeddedResourceResource, EmptyResponse, EnvVariable, ExportSessionRequest_unstable, ExportSessionResponse_unstable, ExportSourceRequest_unstable, ExportSourceResponse_unstable, ExtNotification, ExtRequest, ExtResponse, GetAvailableExtensionsRequest_unstable, GetAvailableExtensionsResponse_unstable, GetConfigExtensionsRequest_unstable, GetConfigExtensionsResponse_unstable, GetSessionExtensionsRequest_unstable, GetSessionExtensionsResponse_unstable, GetToolsRequest_unstable, GetToolsResponse_unstable, GooseExtension, GooseExtensionEntry, GooseSessionNotification_unstable, GooseSessionUpdate, GooseToolCallRequest_unstable, GooseToolCallResponse_unstable, HttpHeader, ImageContent, ImportSessionRequest_unstable, ImportSessionResponse_unstable, ImportSourcesRequest_unstable, ImportSourcesResponse_unstable, Interaction, InteractionState, InteractionUpdate, ListProvidersRequest_unstable, ListProvidersResponse_unstable, ListSourcesRequest_unstable, ListSourcesResponse_unstable, McpServer, McpServerHttp, McpServerSse, McpServerStdio, OnboardingImportApplyRequest_unstable, OnboardingImportApplyResponse_unstable, OnboardingImportCandidate, OnboardingImportCounts, OnboardingImportScanRequest_unstable, OnboardingImportScanResponse_unstable, OnboardingImportSourceKind, PreferenceKey, PreferencesReadRequest_unstable, PreferencesReadResponse_unstable, PreferencesRemoveRequest_unstable, PreferencesSaveRequest_unstable, PreferenceValue, ProviderCatalogListRequest_unstable, ProviderCatalogListResponse_unstable, ProviderCatalogTemplateRequest_unstable, ProviderCatalogTemplateResponse_unstable, ProviderConfigAuthenticateRequest_unstable, ProviderConfigChangeResponse_unstable, ProviderConfigDeleteRequest_unstable, ProviderConfigFieldUpdate, ProviderConfigFieldValueDto, ProviderConfigKey, ProviderConfigReadRequest_unstable, ProviderConfigReadResponse_unstable, ProviderConfigSaveRequest_unstable, ProviderConfigStatusDto, ProviderConfigStatusRequest_unstable, ProviderConfigStatusResponse_unstable, ProviderInventoryEntryDto, ProviderInventoryModelDto, ProviderSetupCatalogEntryDto, ProviderSetupCatalogListRequest_unstable, ProviderSetupCatalogListResponse_unstable, ProviderSetupCategoryDto, ProviderSetupFieldDto, ProviderSetupGroupDto, ProviderSetupMethodDto, ProviderSupportedModelsListRequest_unstable, ProviderSupportedModelsListResponse_unstable, ProviderTemplateCapabilitiesDto, ProviderTemplateCatalogEntryDto, ProviderTemplateDto, ProviderTemplateModelDto, ReadResourceRequest_unstable, ReadResourceResponse_unstable, RefreshProviderInventoryRequest_unstable, RefreshProviderInventoryResponse_unstable, RefreshProviderInventorySkipDto, RefreshProviderInventorySkipReasonDto, RemoveConfigExtensionRequest_unstable, RemoveExtensionRequest_unstable, RenameSessionRequest_unstable, ResourceLink, Role, SessionSystemPromptMode, SessionUsageUpdate, SetConfigExtensionEnabledRequest_unstable, SetSessionSystemPromptRequest_unstable, SourceEntry, SourceScope, SourceType, StatusMessage, StatusMessageUpdate, SteerSessionRequest_unstable, SteerSessionResponse_unstable, TextContent, TextResourceContents, UnarchiveSessionRequest_unstable, UpdateSessionProjectRequest_unstable, UpdateSourceRequest_unstable, UpdateSourceResponse_unstable, UpdateWorkingDirRequest_unstable } from './types.gen.js'; +export type { AddConfigExtensionRequest_unstable, AddExtensionRequest_unstable, Annotations, ArchiveSessionRequest_unstable, AudioContent, BlobResourceContents, ContentBlock, CreateSourceRequest_unstable, CreateSourceResponse_unstable, CustomProviderConfigDto, CustomProviderCreateRequest_unstable, CustomProviderCreateResponse_unstable, CustomProviderDeleteRequest_unstable, CustomProviderDeleteResponse_unstable, CustomProviderReadRequest_unstable, CustomProviderReadResponse_unstable, CustomProviderUpdateRequest_unstable, CustomProviderUpdateResponse_unstable, DefaultsReadRequest_unstable, DefaultsReadResponse_unstable, DefaultsSaveRequest_unstable, DeleteSessionRequest, DeleteSourceRequest_unstable, DictationConfigRequest_unstable, DictationConfigResponse_unstable, DictationDownloadProgress, DictationLocalModelStatus, DictationModelCancelRequest_unstable, DictationModelDeleteRequest_unstable, DictationModelDownloadProgressRequest_unstable, DictationModelDownloadProgressResponse_unstable, DictationModelDownloadRequest_unstable, DictationModelOption, DictationModelSelectRequest_unstable, DictationModelsListRequest_unstable, DictationModelsListResponse_unstable, DictationProviderStatusEntry, DictationSecretDeleteRequest_unstable, DictationSecretSaveRequest_unstable, DictationTranscribeRequest_unstable, DictationTranscribeResponse_unstable, ElicitationRespondRequest_unstable, EmbeddedResource, EmbeddedResourceResource, EmptyResponse, EnvVariable, ExportSessionRequest_unstable, ExportSessionResponse_unstable, ExportSourceRequest_unstable, ExportSourceResponse_unstable, ExtNotification, ExtRequest, ExtResponse, GetAvailableExtensionsRequest_unstable, GetAvailableExtensionsResponse_unstable, GetConfigExtensionsRequest_unstable, GetConfigExtensionsResponse_unstable, GetSessionExtensionsRequest_unstable, GetSessionExtensionsResponse_unstable, GetSessionInfoRequest_unstable, GetSessionInfoResponse_unstable, GetToolsRequest_unstable, GetToolsResponse_unstable, GooseExtension, GooseExtensionEntry, GooseSessionNotification_unstable, GooseSessionUpdate, GooseToolCallRequest_unstable, GooseToolCallResponse_unstable, HttpHeader, ImageContent, ImportSessionRequest_unstable, ImportSessionResponse_unstable, ImportSourcesRequest_unstable, ImportSourcesResponse_unstable, Interaction, InteractionState, InteractionUpdate, ListProvidersRequest_unstable, ListProvidersResponse_unstable, ListSourcesRequest_unstable, ListSourcesResponse_unstable, McpServer, McpServerHttp, McpServerSse, McpServerStdio, OnboardingImportApplyRequest_unstable, OnboardingImportApplyResponse_unstable, OnboardingImportCandidate, OnboardingImportCounts, OnboardingImportScanRequest_unstable, OnboardingImportScanResponse_unstable, OnboardingImportSourceKind, PreferenceKey, PreferencesReadRequest_unstable, PreferencesReadResponse_unstable, PreferencesRemoveRequest_unstable, PreferencesSaveRequest_unstable, PreferenceValue, ProviderCatalogListRequest_unstable, ProviderCatalogListResponse_unstable, ProviderCatalogTemplateRequest_unstable, ProviderCatalogTemplateResponse_unstable, ProviderConfigAuthenticateRequest_unstable, ProviderConfigChangeResponse_unstable, ProviderConfigDeleteRequest_unstable, ProviderConfigFieldUpdate, ProviderConfigFieldValueDto, ProviderConfigKey, ProviderConfigReadRequest_unstable, ProviderConfigReadResponse_unstable, ProviderConfigSaveRequest_unstable, ProviderConfigStatusDto, ProviderConfigStatusRequest_unstable, ProviderConfigStatusResponse_unstable, ProviderInventoryEntryDto, ProviderInventoryModelDto, ProviderSetupCatalogEntryDto, ProviderSetupCatalogListRequest_unstable, ProviderSetupCatalogListResponse_unstable, ProviderSetupCategoryDto, ProviderSetupFieldDto, ProviderSetupGroupDto, ProviderSetupMethodDto, ProviderSupportedModelsListRequest_unstable, ProviderSupportedModelsListResponse_unstable, ProviderTemplateCapabilitiesDto, ProviderTemplateCatalogEntryDto, ProviderTemplateDto, ProviderTemplateModelDto, ReadResourceRequest_unstable, ReadResourceResponse_unstable, RefreshProviderInventoryRequest_unstable, RefreshProviderInventoryResponse_unstable, RefreshProviderInventorySkipDto, RefreshProviderInventorySkipReasonDto, RemoveConfigExtensionRequest_unstable, RemoveExtensionRequest_unstable, RenameSessionRequest_unstable, ResourceLink, Role, SessionId, SessionInfo, SessionSystemPromptMode, SessionUsageUpdate, SetConfigExtensionEnabledRequest_unstable, SetSessionSystemPromptRequest_unstable, SourceEntry, SourceScope, SourceType, StatusMessage, StatusMessageUpdate, SteerSessionRequest_unstable, SteerSessionResponse_unstable, TextContent, TextResourceContents, UnarchiveSessionRequest_unstable, UpdateSessionProjectRequest_unstable, UpdateSourceRequest_unstable, UpdateSourceResponse_unstable, UpdateWorkingDirRequest_unstable } from './types.gen.js'; export const GOOSE_EXT_METHODS = [ { @@ -198,6 +198,11 @@ export const GOOSE_EXT_METHODS = [ requestType: "ImportSessionRequest_unstable", responseType: "ImportSessionResponse_unstable", }, + { + method: "_goose/unstable/session/info", + requestType: "GetSessionInfoRequest_unstable", + responseType: "GetSessionInfoResponse_unstable", + }, { method: "_goose/unstable/elicitation/respond", requestType: "ElicitationRespondRequest_unstable", diff --git a/ui/sdk/src/generated/types.gen.ts b/ui/sdk/src/generated/types.gen.ts index 62dea2d35c77..1216f16fb46b 100644 --- a/ui/sdk/src/generated/types.gen.ts +++ b/ui/sdk/src/generated/types.gen.ts @@ -1134,6 +1134,69 @@ export type ImportSessionResponse_unstable = { messageCount: number; }; +/** + * Return list-style metadata for a single session without loading the conversation. + */ +export type GetSessionInfoRequest_unstable = { + sessionId: string; +}; + +export type GetSessionInfoResponse_unstable = { + session: SessionInfo; +}; + +/** + * Information about a session returned by session/list + */ +export type SessionInfo = { + /** + * Unique identifier for the session + */ + sessionId: SessionId; + /** + * The working directory for this session. Must be an absolute path. + */ + cwd: string; + /** + * **UNSTABLE** + * + * This capability is not part of the spec yet, and may be removed or changed at any point. + * + * Authoritative ordered additional workspace roots for this session. Each path must be absolute. + * + * When omitted or empty, there are no additional roots for the session. + */ + additionalDirectories?: Array; + /** + * Human-readable title for the session + */ + title?: string | null; + /** + * ISO 8601 timestamp of last activity + */ + updatedAt?: string | null; + /** + * The _meta property is reserved by ACP to allow clients and agents to attach additional + * metadata to their interactions. Implementations MUST NOT make assumptions about values at + * these keys. + * + * See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + */ + _meta?: { + [key: string]: unknown; + } | null; +}; + +/** + * A unique identifier for a conversation session between a client and agent. + * + * Sessions maintain their own context, conversation history, and state, + * allowing multiple independent interactions with the same agent. + * + * See protocol docs: [Session ID](https://agentclientprotocol.com/protocol/session-setup#session-id) + */ +export type SessionId = string; + /** * Submit a response for a pending MCP elicitation in an active session. */ @@ -1557,14 +1620,14 @@ export type InteractionUpdate = { export type ExtRequest = { id: string; method: string; - params?: AddExtensionRequest_unstable | RemoveExtensionRequest_unstable | GetToolsRequest_unstable | GooseToolCallRequest_unstable | ReadResourceRequest_unstable | UpdateWorkingDirRequest_unstable | SetSessionSystemPromptRequest_unstable | SteerSessionRequest_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 | PreferencesReadRequest_unstable | PreferencesSaveRequest_unstable | PreferencesRemoveRequest_unstable | DefaultsReadRequest_unstable | DefaultsSaveRequest_unstable | OnboardingImportScanRequest_unstable | OnboardingImportApplyRequest_unstable | ExportSessionRequest_unstable | ImportSessionRequest_unstable | ElicitationRespondRequest_unstable | UpdateSessionProjectRequest_unstable | RenameSessionRequest_unstable | ArchiveSessionRequest_unstable | UnarchiveSessionRequest_unstable | CreateSourceRequest_unstable | ListSourcesRequest_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 | { + params?: AddExtensionRequest_unstable | RemoveExtensionRequest_unstable | GetToolsRequest_unstable | GooseToolCallRequest_unstable | ReadResourceRequest_unstable | UpdateWorkingDirRequest_unstable | SetSessionSystemPromptRequest_unstable | SteerSessionRequest_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 | PreferencesReadRequest_unstable | PreferencesSaveRequest_unstable | PreferencesRemoveRequest_unstable | DefaultsReadRequest_unstable | DefaultsSaveRequest_unstable | OnboardingImportScanRequest_unstable | OnboardingImportApplyRequest_unstable | ExportSessionRequest_unstable | ImportSessionRequest_unstable | GetSessionInfoRequest_unstable | ElicitationRespondRequest_unstable | UpdateSessionProjectRequest_unstable | RenameSessionRequest_unstable | ArchiveSessionRequest_unstable | UnarchiveSessionRequest_unstable | CreateSourceRequest_unstable | ListSourcesRequest_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 | { [key: string]: unknown; } | null; }; export type ExtResponse = { id: string; - result?: EmptyResponse | GetToolsResponse_unstable | GooseToolCallResponse_unstable | ReadResourceResponse_unstable | SteerSessionResponse_unstable | GetConfigExtensionsResponse_unstable | GetAvailableExtensionsResponse_unstable | GetSessionExtensionsResponse_unstable | ListProvidersResponse_unstable | ProviderSupportedModelsListResponse_unstable | ProviderCatalogListResponse_unstable | ProviderSetupCatalogListResponse_unstable | ProviderCatalogTemplateResponse_unstable | CustomProviderCreateResponse_unstable | CustomProviderReadResponse_unstable | CustomProviderUpdateResponse_unstable | CustomProviderDeleteResponse_unstable | RefreshProviderInventoryResponse_unstable | ProviderConfigReadResponse_unstable | ProviderConfigStatusResponse_unstable | ProviderConfigChangeResponse_unstable | PreferencesReadResponse_unstable | DefaultsReadResponse_unstable | OnboardingImportScanResponse_unstable | OnboardingImportApplyResponse_unstable | ExportSessionResponse_unstable | ImportSessionResponse_unstable | CreateSourceResponse_unstable | ListSourcesResponse_unstable | UpdateSourceResponse_unstable | ExportSourceResponse_unstable | ImportSourcesResponse_unstable | DictationTranscribeResponse_unstable | DictationConfigResponse_unstable | DictationModelsListResponse_unstable | DictationModelDownloadProgressResponse_unstable | unknown; + result?: EmptyResponse | GetToolsResponse_unstable | GooseToolCallResponse_unstable | ReadResourceResponse_unstable | SteerSessionResponse_unstable | GetConfigExtensionsResponse_unstable | GetAvailableExtensionsResponse_unstable | GetSessionExtensionsResponse_unstable | ListProvidersResponse_unstable | ProviderSupportedModelsListResponse_unstable | ProviderCatalogListResponse_unstable | ProviderSetupCatalogListResponse_unstable | ProviderCatalogTemplateResponse_unstable | CustomProviderCreateResponse_unstable | CustomProviderReadResponse_unstable | CustomProviderUpdateResponse_unstable | CustomProviderDeleteResponse_unstable | RefreshProviderInventoryResponse_unstable | ProviderConfigReadResponse_unstable | ProviderConfigStatusResponse_unstable | ProviderConfigChangeResponse_unstable | PreferencesReadResponse_unstable | DefaultsReadResponse_unstable | OnboardingImportScanResponse_unstable | OnboardingImportApplyResponse_unstable | ExportSessionResponse_unstable | ImportSessionResponse_unstable | GetSessionInfoResponse_unstable | CreateSourceResponse_unstable | ListSourcesResponse_unstable | UpdateSourceResponse_unstable | ExportSourceResponse_unstable | ImportSourcesResponse_unstable | DictationTranscribeResponse_unstable | DictationConfigResponse_unstable | DictationModelsListResponse_unstable | DictationModelDownloadProgressResponse_unstable | unknown; } | { error: { code: number; diff --git a/ui/sdk/src/generated/zod.gen.ts b/ui/sdk/src/generated/zod.gen.ts index e40fb2d73701..b98f640e0e5f 100644 --- a/ui/sdk/src/generated/zod.gen.ts +++ b/ui/sdk/src/generated/zod.gen.ts @@ -1131,6 +1131,48 @@ export const zImportSessionResponse_unstable = z.object({ messageCount: z.number().int().gte(0) }); +/** + * Return list-style metadata for a single session without loading the conversation. + */ +export const zGetSessionInfoRequest_unstable = z.object({ + sessionId: z.string() +}); + +/** + * A unique identifier for a conversation session between a client and agent. + * + * Sessions maintain their own context, conversation history, and state, + * allowing multiple independent interactions with the same agent. + * + * See protocol docs: [Session ID](https://agentclientprotocol.com/protocol/session-setup#session-id) + */ +export const zSessionId = z.string(); + +/** + * Information about a session returned by session/list + */ +export const zSessionInfo = z.object({ + sessionId: zSessionId, + cwd: z.string(), + additionalDirectories: z.array(z.string()).optional(), + title: z.union([ + z.string(), + z.null() + ]).optional(), + updatedAt: z.union([ + z.string(), + z.null() + ]).optional(), + _meta: z.union([ + z.record(z.unknown()), + z.null() + ]).optional() +}); + +export const zGetSessionInfoResponse_unstable = z.object({ + session: zSessionInfo +}); + /** * Submit a response for a pending MCP elicitation in an active session. */ @@ -1592,6 +1634,7 @@ export const zExtRequest = z.object({ zOnboardingImportApplyRequest_unstable, zExportSessionRequest_unstable, zImportSessionRequest_unstable, + zGetSessionInfoRequest_unstable, zElicitationRespondRequest_unstable, zUpdateSessionProjectRequest_unstable, zRenameSessionRequest_unstable, @@ -1653,6 +1696,7 @@ export const zExtResponse = z.union([ zOnboardingImportApplyResponse_unstable, zExportSessionResponse_unstable, zImportSessionResponse_unstable, + zGetSessionInfoResponse_unstable, zCreateSourceResponse_unstable, zListSourcesResponse_unstable, zUpdateSourceResponse_unstable,