From cec7e7f6a6d51cd084cbafe86abde375e8f23d03 Mon Sep 17 00:00:00 2001 From: Lifei Zhou Date: Thu, 25 Jun 2026 21:14:04 +1000 Subject: [PATCH 1/2] removed unnecessary call setRecipeParams for acp enabled path --- ui/desktop/src/acp/chatSessionController.ts | 39 +-------------------- ui/desktop/src/components/BaseChat.tsx | 3 +- ui/desktop/src/hooks/useAcpChatSession.ts | 11 ++---- 3 files changed, 6 insertions(+), 47 deletions(-) diff --git a/ui/desktop/src/acp/chatSessionController.ts b/ui/desktop/src/acp/chatSessionController.ts index af8a88bc9d56..cb0bf9db09b6 100644 --- a/ui/desktop/src/acp/chatSessionController.ts +++ b/ui/desktop/src/acp/chatSessionController.ts @@ -1,5 +1,5 @@ import { v7 as uuidv7 } from 'uuid'; -import { updateSessionUserRecipeValues, type Message, type Session } from '../api'; +import type { Message, Session } from '../api'; import type { GooseExtension } from '@aaif/goose-sdk'; import { AppEvents } from '../constants/events'; import { ChatState } from '../types/chatState'; @@ -57,11 +57,6 @@ export interface AcpChatSessionController { editType: 'fork' | 'edit' | undefined, options: AcpSubmitMessageOptions ): Promise; - setRecipeUserParams( - sessionId: string, - userRecipeValues: Record, - options: AcpSnapshotOptions - ): Promise; } function createAcpCreditsExhaustedMessage(error: AcpCreditsExhaustedError): Message { @@ -271,42 +266,10 @@ async function updateMessage( } } -async function setRecipeUserParams( - sessionId: string, - userRecipeValues: Record, - options: AcpSnapshotOptions -): Promise { - const currentSession = - options.getCurrentSnapshot()?.session ?? acpChatSessionStore.getSnapshot(sessionId)?.session; - - if (currentSession) { - await updateSessionUserRecipeValues({ - path: { - session_id: sessionId, - }, - body: { - userRecipeValues, - }, - throwOnError: true, - }); - const updatedSession = { - ...currentSession, - user_recipe_values: userRecipeValues, - }; - acpChatSessionActions.setSessionMetadata(sessionId, updatedSession); - } else { - acpChatSessionActions.setSessionLoadError( - sessionId, - "can't call setRecipeParams without a session" - ); - } -} - export const acpChatSessionController: AcpChatSessionController = { createSession, loadSession, submitMessage, stop, updateMessage, - setRecipeUserParams, }; diff --git a/ui/desktop/src/components/BaseChat.tsx b/ui/desktop/src/components/BaseChat.tsx index 5261a592a3b8..7e23fa148a53 100644 --- a/ui/desktop/src/components/BaseChat.tsx +++ b/ui/desktop/src/components/BaseChat.tsx @@ -554,7 +554,8 @@ export default function BaseChat({ /> )} - {recipe?.parameters && + {!USE_ACP_CHAT && + recipe?.parameters && recipe.parameters.length > 0 && !session?.user_recipe_values && session?.session_type !== 'scheduled' && ( diff --git a/ui/desktop/src/hooks/useAcpChatSession.ts b/ui/desktop/src/hooks/useAcpChatSession.ts index 0b2d62d08911..6940f15dc5ec 100644 --- a/ui/desktop/src/hooks/useAcpChatSession.ts +++ b/ui/desktop/src/hooks/useAcpChatSession.ts @@ -263,14 +263,9 @@ export function useAcpChatSession({ [getCurrentSnapshot, sessionId] ); - const setRecipeUserParams = useCallback( - async (user_recipe_values: Record) => { - await acpChatSessionController.setRecipeUserParams(sessionId, user_recipe_values, { - getCurrentSnapshot, - }); - }, - [getCurrentSnapshot, sessionId] - ); + const setRecipeUserParams = useCallback((_userRecipeValues: Record) => { + return Promise.reject(new Error('ACP recipe parameters are handled during session creation')); + }, []); useEffect(() => { if (session) { From 397559eb93fe7dc1335465e5285f189b28ef72af Mon Sep 17 00:00:00 2001 From: Lifei Zhou Date: Thu, 25 Jun 2026 22:51:57 +1000 Subject: [PATCH 2/2] used acp get SessionInfo --- ui/desktop/src/acp/__tests__/sessions.test.ts | 38 ++++++++++++++++++- ui/desktop/src/acp/sessions.ts | 6 +++ ui/desktop/src/hooks/useNavigationSessions.ts | 24 ++++++++---- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/ui/desktop/src/acp/__tests__/sessions.test.ts b/ui/desktop/src/acp/__tests__/sessions.test.ts index f53457254b58..c6ca72620be2 100644 --- a/ui/desktop/src/acp/__tests__/sessions.test.ts +++ b/ui/desktop/src/acp/__tests__/sessions.test.ts @@ -1,7 +1,7 @@ import type { SessionInfo } from '@agentclientprotocol/sdk'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { getAcpClient } from '../acpConnection'; -import { acpLoadSession, sessionInfoToSession } from '../sessions'; +import { acpGetSessionListItem, acpLoadSession, sessionInfoToSession } from '../sessions'; vi.mock('../acpConnection', () => ({ getAcpClient: vi.fn(), @@ -69,4 +69,40 @@ describe('ACP sessions', () => { 'claude-sonnet-4-5' ); }); + + it('returns a list item from ACP session info', async () => { + const client = { + goose: { + sessionInfo_unstable: vi.fn().mockResolvedValue({ + session: sessionInfo({ + title: 'Subagent session', + _meta: { + createdAt: '2026-01-01T00:00:00Z', + lastMessageAt: '2026-01-01T00:01:00Z', + messageCount: 3, + sessionType: 'sub_agent', + providerId: 'anthropic', + modelId: 'claude-sonnet-4-5', + }, + }), + }), + }, + }; + vi.mocked(getAcpClient).mockResolvedValue( + client as unknown as Awaited> + ); + + const item = await acpGetSessionListItem('session-1'); + + expect(client.goose.sessionInfo_unstable).toHaveBeenCalledWith({ sessionId: 'session-1' }); + expect(item).toMatchObject({ + id: 'session-1', + name: 'Subagent session', + workingDir: '/tmp', + messageCount: 3, + lastMessageAt: '2026-01-01T00:01:00Z', + providerId: 'anthropic', + modelId: 'claude-sonnet-4-5', + }); + }); }); diff --git a/ui/desktop/src/acp/sessions.ts b/ui/desktop/src/acp/sessions.ts index 549cea15ef15..8d8d885d8125 100644 --- a/ui/desktop/src/acp/sessions.ts +++ b/ui/desktop/src/acp/sessions.ts @@ -168,6 +168,12 @@ export async function acpListRecentSessions(maxSessions: number): Promise { + const client = await getAcpClient(); + const response = await client.goose.sessionInfo_unstable({ sessionId }); + return sessionInfoToListItem(response.session); +} + export async function acpLoadSession(sessionId: string): Promise { const pendingLoad = inFlightSessionLoads.get(sessionId); if (pendingLoad) { diff --git a/ui/desktop/src/hooks/useNavigationSessions.ts b/ui/desktop/src/hooks/useNavigationSessions.ts index b623356aa823..569ee7e1e3e6 100644 --- a/ui/desktop/src/hooks/useNavigationSessions.ts +++ b/ui/desktop/src/hooks/useNavigationSessions.ts @@ -1,15 +1,21 @@ import { useState, useEffect, useRef, useCallback } from 'react'; import { useNavigate, useLocation, useSearchParams } from 'react-router-dom'; -import { getSession } from '../api'; import { useChatContext } from '../contexts/ChatContext'; import { getSessionDisplayName } from '../sessions'; import { AppEvents } from '../constants/events'; import type { Session } from '../api'; -import { acpListRecentSessions, type SessionListItem } from '../acp/sessions'; +import { + acpGetSessionListItem, + acpListRecentSessions, + type SessionListItem, +} from '../acp/sessions'; const MAX_RECENT_SESSIONS = 25; -export function prependUnique(prev: SessionListItem[], session: SessionListItem): SessionListItem[] { +export function prependUnique( + prev: SessionListItem[], + session: SessionListItem +): SessionListItem[] { if (prev.some((s) => s.id === session.id)) return prev; return [session, ...prev].slice(0, MAX_RECENT_SESSIONS); } @@ -74,11 +80,13 @@ export function useNavigationSessions() { if (!activeSessionId) return; if (recentSessions.some((s) => s.id === activeSessionId)) return; - getSession({ path: { session_id: activeSessionId }, throwOnError: false }).then((response) => { - if (!response.data) return; - const item = sessionToListItem(response.data as Session); - setRecentSessions((prev) => prependUnique(prev, item)); - }); + acpGetSessionListItem(activeSessionId) + .then((item) => { + setRecentSessions((prev) => prependUnique(prev, item)); + }) + .catch((error) => { + console.error('Failed to fetch active session:', error); + }); }, [activeSessionId, recentSessions]); useEffect(() => {