diff --git a/ui/desktop/src/__tests__/createSession.test.ts b/ui/desktop/src/__tests__/createSession.test.ts index 053fdc183..70899e4bb 100644 --- a/ui/desktop/src/__tests__/createSession.test.ts +++ b/ui/desktop/src/__tests__/createSession.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { createSession } from '../sessions'; -import type { ExtensionConfig, Session } from '../api'; +import type { ExtensionConfig } from '../types/extensions'; +import type { Session } from '../types/session'; import type { FixedExtensionEntry } from '../components/ConfigContext'; import type { GooseExtension, GooseExtensionEntry } from '@aaif/goose-sdk'; import { getConfiguredGooseExtensions } from '../acp/extensions'; diff --git a/ui/desktop/src/__tests__/sessions.test.ts b/ui/desktop/src/__tests__/sessions.test.ts index e865e2019..42d564460 100644 --- a/ui/desktop/src/__tests__/sessions.test.ts +++ b/ui/desktop/src/__tests__/sessions.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect } from 'vitest'; import { getSessionDisplayName, shouldShowNewChatTitle } from '../sessions'; import { prependUnique } from '../hooks/useNavigationSessions'; -import type { Session } from '../api'; import type { SessionListItem } from '../acp/sessions'; +import type { Session } from '../types/session'; // Helper to build a minimal Session object for testing. function makeSession(overrides: Partial = {}): Session { diff --git a/ui/desktop/src/acp/__tests__/chatNotifications.test.ts b/ui/desktop/src/acp/__tests__/chatNotifications.test.ts index 8d1258e44..71d83482a 100644 --- a/ui/desktop/src/acp/__tests__/chatNotifications.test.ts +++ b/ui/desktop/src/acp/__tests__/chatNotifications.test.ts @@ -1,8 +1,8 @@ import type { SessionNotification } from '@agentclientprotocol/sdk'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { Session } from '../../api'; import { AppEvents } from '../../constants/events'; import { ChatState } from '../../types/chatState'; +import type { Session } from '../../types/session'; import { maybeHandlePlatformEvent } from '../../utils/platform_events'; import { handleAcpSessionNotification } from '../chatNotifications'; import type { AcpChatSessionSnapshot } from '../chatSessionStore'; diff --git a/ui/desktop/src/acp/__tests__/chatSessionController.test.ts b/ui/desktop/src/acp/__tests__/chatSessionController.test.ts index 9f9ad0c7f..2c2dfc155 100644 --- a/ui/desktop/src/acp/__tests__/chatSessionController.test.ts +++ b/ui/desktop/src/acp/__tests__/chatSessionController.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { Message, Session } from '../../api'; +import type { Message } from '../../types/message'; import { ChatState } from '../../types/chatState'; +import type { Session } from '../../types/session'; import { acpChatSessionController } from '../chatSessionController'; import { acpChatSessionActions, diff --git a/ui/desktop/src/acp/__tests__/chatSessionStore.test.ts b/ui/desktop/src/acp/__tests__/chatSessionStore.test.ts index 68502de09..90bcf0e7a 100644 --- a/ui/desktop/src/acp/__tests__/chatSessionStore.test.ts +++ b/ui/desktop/src/acp/__tests__/chatSessionStore.test.ts @@ -5,8 +5,9 @@ import type { } from '@agentclientprotocol/sdk'; import { act, renderHook } from '@testing-library/react'; import { afterEach, describe, expect, it } from 'vitest'; -import type { Message, Session } from '../../api'; +import type { Message } from '../../types/message'; import { ChatState } from '../../types/chatState'; +import type { Session } from '../../types/session'; import { acpElicitationUserInputRequestId, acpChatSessionActions, diff --git a/ui/desktop/src/acp/__tests__/mcp-apps.test.ts b/ui/desktop/src/acp/__tests__/mcp-apps.test.ts index baa0fab87..704c4b5b2 100644 --- a/ui/desktop/src/acp/__tests__/mcp-apps.test.ts +++ b/ui/desktop/src/acp/__tests__/mcp-apps.test.ts @@ -127,6 +127,7 @@ describe('ACP MCP app helpers', () => { { name: 'weather__refresh', description: 'Refresh weather', + parameters: [], inputSchema: { type: 'object', properties: { @@ -137,6 +138,7 @@ describe('ACP MCP app helpers', () => { { name: 'calendar__refresh', description: 'Refresh calendar', + parameters: [], inputSchema: { type: 'object' }, }, ], @@ -150,7 +152,7 @@ describe('ACP MCP app helpers', () => { name: 'weather__refresh', description: 'Refresh weather', parameters: [], - input_schema: { + inputSchema: { type: 'object', properties: { city: { type: 'string' }, diff --git a/ui/desktop/src/acp/__tests__/prompt.test.ts b/ui/desktop/src/acp/__tests__/prompt.test.ts index b758737ef..e4f104bbf 100644 --- a/ui/desktop/src/acp/__tests__/prompt.test.ts +++ b/ui/desktop/src/acp/__tests__/prompt.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { Message } from '../../api'; +import type { Message } from '../../types/message'; import { messageToAcpPromptContent } from '../prompt'; describe('messageToAcpPromptContent', () => { diff --git a/ui/desktop/src/acp/__tests__/sessionNotificationAdapter.test.ts b/ui/desktop/src/acp/__tests__/sessionNotificationAdapter.test.ts index 098839155..22e054677 100644 --- a/ui/desktop/src/acp/__tests__/sessionNotificationAdapter.test.ts +++ b/ui/desktop/src/acp/__tests__/sessionNotificationAdapter.test.ts @@ -1,8 +1,7 @@ import type { GooseSessionNotification_unstable } from '@aaif/goose-sdk'; import type { RequestPermissionRequest, SessionNotification } from '@agentclientprotocol/sdk'; import { describe, expect, it } from 'vitest'; -import type { Message, MessageContent } from '../../api'; -import type { NotificationEvent } from '../../types/message'; +import type { Message, NotificationEvent } from '../../types/message'; import { createAcpSessionNotificationAdapter, type AcpChatStateChange, @@ -97,7 +96,7 @@ function expectOnlyNotificationChange(chatStateChanges: AcpChatStateChange[]): N return chatStateChange.notification; } -function firstContent(message: Message): MessageContent { +function firstContent(message: Message): Message['content'][number] { const content = message.content[0]; expect(content).toBeDefined(); return content; diff --git a/ui/desktop/src/acp/adapter/elicitations.ts b/ui/desktop/src/acp/adapter/elicitations.ts index 7c3cfa140..c93faa551 100644 --- a/ui/desktop/src/acp/adapter/elicitations.ts +++ b/ui/desktop/src/acp/adapter/elicitations.ts @@ -1,4 +1,4 @@ -import type { Message } from '../../api'; +import type { Message } from '../../types/message'; import type { AcpElicitationRequest } from '../elicitationRequests'; import { type AcpChatStateChange, diff --git a/ui/desktop/src/acp/adapter/messages.ts b/ui/desktop/src/acp/adapter/messages.ts index 9a287e83b..a5634b685 100644 --- a/ui/desktop/src/acp/adapter/messages.ts +++ b/ui/desktop/src/acp/adapter/messages.ts @@ -2,7 +2,7 @@ import type { ContentBlock as AcpContentBlock, SessionNotification, } from '@agentclientprotocol/sdk'; -import type { Message, MessageContent } from '../../api'; +import type { ContentBlock, Message } from '../../types/message'; import { type AcpChatStateChange, type AdapterState, @@ -11,6 +11,8 @@ import { messagesChange, } from './shared'; +type StreamedContentBlock = Extract; + export function applyContentChunk( state: AdapterState, role: Message['role'], @@ -91,7 +93,9 @@ export function applyThoughtChunk( return messagesChange(state); } -function messageContentFromAcpContentBlock(content: AcpContentBlock): MessageContent | undefined { +function messageContentFromAcpContentBlock( + content: AcpContentBlock +): StreamedContentBlock | undefined { switch (content.type) { case 'text': return { @@ -151,7 +155,10 @@ function lastMergeableMessageWithRole( return lastMessage; } -function hasImageContent(message: Message, image: Extract) { +function hasImageContent( + message: Message, + image: Extract +) { return message.content.some( (content) => content.type === 'image' && content.data === image.data && content.mimeType === image.mimeType @@ -173,7 +180,7 @@ function messagesChangeWithLocalSteerConfirmation( function reconcileLocalSteerTextChunk( state: AdapterState, message: Message, - content: MessageContent, + content: StreamedContentBlock, isSteerChunk: boolean | undefined ): boolean { if (!isSteerChunk || !message.metadata.steer || message.role !== 'user') { diff --git a/ui/desktop/src/acp/adapter/shared.ts b/ui/desktop/src/acp/adapter/shared.ts index 3c98c18fb..073962701 100644 --- a/ui/desktop/src/acp/adapter/shared.ts +++ b/ui/desktop/src/acp/adapter/shared.ts @@ -1,6 +1,6 @@ import type { ToolCall, ToolCallUpdate } from '@agentclientprotocol/sdk'; -import type { Message, TokenState } from '../../api'; -import type { NotificationEvent } from '../../types/message'; +import type { TokenState } from '../../types/chat'; +import type { Message, NotificationEvent } from '../../types/message'; export type AcpChatStateChange = | { type: 'messages'; messages: Message[] } diff --git a/ui/desktop/src/acp/adapter/tools.ts b/ui/desktop/src/acp/adapter/tools.ts index 3567c0dd3..7b9af6b76 100644 --- a/ui/desktop/src/acp/adapter/tools.ts +++ b/ui/desktop/src/acp/adapter/tools.ts @@ -3,7 +3,8 @@ import type { ToolCall, ToolCallUpdate, } from '@agentclientprotocol/sdk'; -import type { ContentBlock as ApiContentBlock, Message } from '../../api'; +import type { Message } from '../../types/message'; +import type { ContentBlock as GooseContentBlock } from '../../types/message'; import { findMessageForChunk } from './messages'; import { toolNotificationChange } from './toolNotifications'; import { @@ -190,8 +191,8 @@ function toolResultValue( }; } -function toolResultContent(update: ToolCallUpdate): ApiContentBlock[] { - const content: ApiContentBlock[] = []; +function toolResultContent(update: ToolCallUpdate): GooseContentBlock[] { + const content: GooseContentBlock[] = []; for (const item of update.content ?? []) { if (item.type !== 'content') { @@ -215,7 +216,9 @@ function toolResultContent(update: ToolCallUpdate): ApiContentBlock[] { return []; } -function apiContentBlockFromAcpContentBlock(content: AcpContentBlock): ApiContentBlock | undefined { +function apiContentBlockFromAcpContentBlock( + content: AcpContentBlock +): GooseContentBlock | undefined { switch (content.type) { case 'text': return { @@ -260,7 +263,7 @@ function apiContentBlockFromAcpContentBlock(content: AcpContentBlock): ApiConten function apiResourceContentsFromAcpResource( resource: Extract['resource'] -): Extract['resource'] { +): Extract['resource'] { if ('text' in resource) { return { uri: resource.uri, @@ -303,7 +306,7 @@ interface DesktopMcpAppMeta extends Record { } type ToolResultValue = { - content: ApiContentBlock[]; + content: GooseContentBlock[]; structuredContent?: unknown; isError: boolean; _meta?: DesktopMcpAppMeta; diff --git a/ui/desktop/src/acp/chatSessionController.ts b/ui/desktop/src/acp/chatSessionController.ts index f7f2363fd..36cc4ffa6 100644 --- a/ui/desktop/src/acp/chatSessionController.ts +++ b/ui/desktop/src/acp/chatSessionController.ts @@ -1,11 +1,15 @@ import { v7 as uuidv7 } from 'uuid'; -import type { Message, Session } from '../api'; import type { GooseExtension } from '@aaif/goose-sdk'; import { AppEvents } from '../constants/events'; import { ChatState } from '../types/chatState'; +import type { Session } from '../types/session'; import { errorMessage } from '../utils/conversionUtils'; import { showExtensionLoadResults } from '../utils/extensionErrorUtils'; -import { createUserMessage, getPendingToolConfirmationIds } from '../types/message'; +import { + createUserMessage, + getPendingToolConfirmationIds, + type Message, +} from '../types/message'; import { acpChatSessionActions, acpChatSessionStore, diff --git a/ui/desktop/src/acp/chatSessionStore.ts b/ui/desktop/src/acp/chatSessionStore.ts index c7901543a..c93f78c5d 100644 --- a/ui/desktop/src/acp/chatSessionStore.ts +++ b/ui/desktop/src/acp/chatSessionStore.ts @@ -1,9 +1,10 @@ import { useEffect, useState } from 'react'; import type { GooseSessionNotification_unstable } from '@aaif/goose-sdk'; import type { RequestPermissionRequest, SessionNotification } from '@agentclientprotocol/sdk'; -import type { Message, Session, TokenState } from '../api'; +import type { TokenState } from '../types/chat'; import { ChatState } from '../types/chatState'; -import type { NotificationEvent } from '../types/message'; +import type { Message, NotificationEvent } from '../types/message'; +import type { Session } from '../types/session'; import { createAcpSessionNotificationAdapter, type AcpChatStateChange, diff --git a/ui/desktop/src/acp/diagnostics.ts b/ui/desktop/src/acp/diagnostics.ts index 553ca8352..7c50806df 100644 --- a/ui/desktop/src/acp/diagnostics.ts +++ b/ui/desktop/src/acp/diagnostics.ts @@ -1,7 +1,5 @@ import { getAcpClient } from './acpConnection'; -import type { DiagnosticsReport } from '../api'; - -export type DiagnosticsLevel = 'summary' | 'full'; +import type { DiagnosticsLevel, DiagnosticsReport } from '../types/diagnostics'; export async function getDiagnosticsReport( sessionId: string, diff --git a/ui/desktop/src/acp/extensions.ts b/ui/desktop/src/acp/extensions.ts index fccc35a75..72e1efd2b 100644 --- a/ui/desktop/src/acp/extensions.ts +++ b/ui/desktop/src/acp/extensions.ts @@ -1,4 +1,4 @@ -import type { ExtensionConfig, ExtensionEntry } from '../api'; +import type { ExtensionConfig, ExtensionEntry } from '../types/extensions'; import type { GooseExtension, GooseExtensionEntry } from '@aaif/goose-sdk'; import { getAcpClient } from './acpConnection'; @@ -115,7 +115,7 @@ export function extensionConfigToGooseExtension(config: ExtensionConfig): GooseE case 'stdio': return { type: 'mcp', - server: { name: config.name, command: config.cmd, args: config.args, env: [] }, + server: { name: config.name, command: config.cmd, args: config.args ?? [], env: [] }, envKeys: config.env_keys ?? [], description: config.description, timeout: config.timeout, diff --git a/ui/desktop/src/acp/mcp-apps.ts b/ui/desktop/src/acp/mcp-apps.ts index f5280a460..66021215b 100644 --- a/ui/desktop/src/acp/mcp-apps.ts +++ b/ui/desktop/src/acp/mcp-apps.ts @@ -1,8 +1,10 @@ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'; -import type { GooseApp, ToolInfo } from '../api'; +import type { ToolListItem } from '@aaif/goose-sdk'; +import type { GooseApp } from '../types/apps'; import { getAcpClient } from './acpConnection'; type JsonRecord = Record; +export type McpAppTool = ToolListItem; export type McpAppResourceResponse = { uri: string; mimeType: string | null; @@ -60,20 +62,6 @@ function flattenReadResourceResult(result: unknown, fallbackUri: string): McpApp }; } -function acpToolToToolInfo(value: unknown): ToolInfo | null { - if (!isRecord(value)) return null; - const name = stringField(value, 'name'); - if (!name) return null; - - const inputSchema = value.inputSchema ?? value.input_schema; - return { - name, - description: stringField(value, 'description') ?? '', - parameters: [], - input_schema: isRecord(inputSchema) ? inputSchema : undefined, - }; -} - function acpApp(value: unknown): GooseApp | null { if (!isRecord(value)) return null; return value as GooseApp; @@ -99,10 +87,10 @@ export async function importMcpApp(html: string): Promise { export async function listMcpAppTools( sessionId: string, extensionName?: string -): Promise { +): Promise { const client = await getAcpClient(); const response = await client.goose.toolsList_unstable({ sessionId }); - const tools = response.tools.map(acpToolToToolInfo).filter((tool): tool is ToolInfo => !!tool); + const tools = response.tools; if (!extensionName) return tools; const prefix = `${extensionName}__`; diff --git a/ui/desktop/src/acp/permissionRequests.ts b/ui/desktop/src/acp/permissionRequests.ts index 9beed3a6b..fbfc9a180 100644 --- a/ui/desktop/src/acp/permissionRequests.ts +++ b/ui/desktop/src/acp/permissionRequests.ts @@ -1,5 +1,5 @@ import type { RequestPermissionRequest, RequestPermissionResponse } from '@agentclientprotocol/sdk'; -import type { Permission } from '../api'; +import type { Permission } from '../types/permissions'; import { acpChatSessionActions, acpPermissionUserInputRequestId } from './chatSessionStore'; interface PendingPermissionRequest { diff --git a/ui/desktop/src/acp/prompt.ts b/ui/desktop/src/acp/prompt.ts index 5c84af2f8..23e3c287c 100644 --- a/ui/desktop/src/acp/prompt.ts +++ b/ui/desktop/src/acp/prompt.ts @@ -1,6 +1,6 @@ import type { ContentBlock, PromptResponse } from '@agentclientprotocol/sdk'; import type { SteerSessionRequest_unstable, SteerSessionResponse_unstable } from '@aaif/goose-sdk'; -import type { Message } from '../api'; +import type { Message } from '../types/message'; import { getAcpClient } from './acpConnection'; export async function acpPromptSession( diff --git a/ui/desktop/src/acp/providers.ts b/ui/desktop/src/acp/providers.ts index e2e2100ce..c7be5b885 100644 --- a/ui/desktop/src/acp/providers.ts +++ b/ui/desktop/src/acp/providers.ts @@ -6,7 +6,8 @@ import type { ProviderTemplateCatalogEntryDto, ProviderTemplateDto, } from '@aaif/goose-sdk'; -import type { ProviderDetails, ThinkingEffort, UpdateCustomProviderRequest } from '../api'; +import type { ProviderDetails, ThinkingEffort } from '../api'; +import type { UpdateCustomProviderRequest } from '../types/providers'; import { getAcpClient } from './acpConnection'; export type { CanonicalModelInfoDto, ProviderSecretDto }; diff --git a/ui/desktop/src/acp/session-extensions.ts b/ui/desktop/src/acp/session-extensions.ts index 364214db3..9a894e422 100644 --- a/ui/desktop/src/acp/session-extensions.ts +++ b/ui/desktop/src/acp/session-extensions.ts @@ -1,4 +1,4 @@ -import type { ExtensionConfig } from '../api'; +import type { ExtensionConfig } from '../types/extensions'; import { getAcpClient } from './acpConnection'; import { extensionConfigToGooseExtension, gooseExtensionToExtensionConfig } from './extensions'; diff --git a/ui/desktop/src/acp/sessionNotificationAdapter.ts b/ui/desktop/src/acp/sessionNotificationAdapter.ts index 27d7d566a..d881d5923 100644 --- a/ui/desktop/src/acp/sessionNotificationAdapter.ts +++ b/ui/desktop/src/acp/sessionNotificationAdapter.ts @@ -1,6 +1,6 @@ import type { GooseSessionNotification_unstable } from '@aaif/goose-sdk'; import type { RequestPermissionRequest, SessionNotification } from '@agentclientprotocol/sdk'; -import type { Message } from '../api'; +import type { Message } from '../types/message'; import { applyElicitationRequest as applyElicitationRequestToState, applyElicitationStatus as applyElicitationStatusToState, diff --git a/ui/desktop/src/acp/sessions.ts b/ui/desktop/src/acp/sessions.ts index 15f302ecd..dc1c18321 100644 --- a/ui/desktop/src/acp/sessions.ts +++ b/ui/desktop/src/acp/sessions.ts @@ -8,7 +8,8 @@ import type { import type { GooseExtension, SessionImportSource } from '@aaif/goose-sdk'; import { getAcpClient } from './acpConnection'; import { DEFAULT_CHAT_TITLE } from '../contexts/ChatContext'; -import type { ExtensionLoadResult, Session } from '../api'; +import type { ExtensionLoadResult } from '../types/extensions'; +import type { Session } from '../types/session'; import type { Recipe } from '../recipe'; interface GooseSessionInfoMeta { diff --git a/ui/desktop/src/components/BaseChat.tsx b/ui/desktop/src/components/BaseChat.tsx index c38a463e0..e6e3bf8f3 100644 --- a/ui/desktop/src/components/BaseChat.tsx +++ b/ui/desktop/src/components/BaseChat.tsx @@ -10,7 +10,6 @@ import ChatInput from './ChatInput'; import { ChatInputCard } from './ChatInputCard'; import { ScrollArea, ScrollAreaHandle } from './ui/scroll-area'; import { useFileDrop } from '../hooks/useFileDrop'; -import { Message } from '../api'; import { ChatState } from '../types/chatState'; import { ChatType } from '../types/chat'; import { useIsMobile } from '../hooks/use-mobile'; @@ -23,9 +22,13 @@ import { RecipeHeader } from './RecipeHeader'; import { RecipeWarningModal } from './ui/RecipeWarningModal'; import { scanRecipe } from '../recipe'; import type { Recipe } from '../recipe'; -import { UserInput } from '../types/message'; import RecipeActivities from './recipes/RecipeActivities'; -import { getThinkingMessage, getTextAndImageContent } from '../types/message'; +import { + getThinkingMessage, + getTextAndImageContent, + type Message, + type UserInput, +} from '../types/message'; import { substituteParameters } from '../utils/parameterSubstitution'; import { useAutoSubmit } from '../hooks/useAutoSubmit'; import { Goose } from './icons'; diff --git a/ui/desktop/src/components/ChatInput.tsx b/ui/desktop/src/components/ChatInput.tsx index 89f6e55d1..73e0881d1 100644 --- a/ui/desktop/src/components/ChatInput.tsx +++ b/ui/desktop/src/components/ChatInput.tsx @@ -27,7 +27,7 @@ import { Recipe } from '../recipe'; import { MessageQueue, QueuedMessage } from './MessageQueue'; import { detectInterruption } from '../utils/interruptionDetector'; import { DiagnosticsModal } from './ui/Diagnostics'; -import { Message } from '../api'; +import type { Message } from '../types/message'; import { getInitialWorkingDir } from '../utils/workingDir'; import { getPredefinedModelsFromEnv } from './settings/models/predefinedModelsUtils'; import { trackFileAttached, trackVoiceDictation, trackDiagnosticsOpened } from '../utils/analytics'; diff --git a/ui/desktop/src/components/ConfigContext.tsx b/ui/desktop/src/components/ConfigContext.tsx index 2672a397f..adf0bb36c 100644 --- a/ui/desktop/src/components/ConfigContext.tsx +++ b/ui/desktop/src/components/ConfigContext.tsx @@ -9,9 +9,10 @@ import { } from '../acp/extensions'; import { pruneDeprecatedBundledExtensions, syncBundledExtensions } from './settings/extensions'; import { nameToKey } from './settings/extensions/utils'; -import type { ConfigResponse, ProviderDetails, ExtensionConfig } from '../api'; +import type { ConfigResponse, ProviderDetails } from '../api'; +import type { ExtensionConfig } from '../types/extensions'; -export type { ExtensionConfig } from '../api/types.gen'; +export type { ExtensionConfig } from '../types/extensions'; // Define a local version that matches the structure of the imported one export type FixedExtensionEntry = ExtensionConfig & { diff --git a/ui/desktop/src/components/ElicitationRequest.test.tsx b/ui/desktop/src/components/ElicitationRequest.test.tsx index 3479e54e1..1b5e529b9 100644 --- a/ui/desktop/src/components/ElicitationRequest.test.tsx +++ b/ui/desktop/src/components/ElicitationRequest.test.tsx @@ -1,7 +1,7 @@ import { act, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { describe, expect, it, vi } from 'vitest'; -import type { ActionRequired } from '../api'; +import type { ActionRequired } from '../types/message'; import { IntlTestWrapper } from '../i18n/test-utils'; import ElicitationRequest from './ElicitationRequest'; diff --git a/ui/desktop/src/components/ElicitationRequest.tsx b/ui/desktop/src/components/ElicitationRequest.tsx index 9a6e48817..bfe66867a 100644 --- a/ui/desktop/src/components/ElicitationRequest.tsx +++ b/ui/desktop/src/components/ElicitationRequest.tsx @@ -1,5 +1,5 @@ import { useState, useEffect, useRef } from 'react'; -import { ActionRequired } from '../api'; +import type { ActionRequired } from '../types/message'; import { defineMessages, useIntl } from '../i18n'; import { Button } from './ui/button'; import JsonSchemaForm from './ui/JsonSchemaForm'; diff --git a/ui/desktop/src/components/ExtensionInstallModal.tsx b/ui/desktop/src/components/ExtensionInstallModal.tsx index 2db0299ab..8628aa317 100644 --- a/ui/desktop/src/components/ExtensionInstallModal.tsx +++ b/ui/desktop/src/components/ExtensionInstallModal.tsx @@ -11,7 +11,7 @@ import { import { Button } from './ui/button'; import { extractExtensionName } from './settings/extensions/utils'; import { addExtensionFromDeepLink } from './settings/extensions/deeplink'; -import type { ExtensionConfig } from '../api/types.gen'; +import type { ExtensionConfig } from '../types/extensions'; import { View, ViewOptions } from '../utils/navigationUtils'; import { useConfig } from './ConfigContext'; import { toastService } from '../toasts'; diff --git a/ui/desktop/src/components/GooseMessage.tsx b/ui/desktop/src/components/GooseMessage.tsx index c0d512016..2bc9544f0 100644 --- a/ui/desktop/src/components/GooseMessage.tsx +++ b/ui/desktop/src/components/GooseMessage.tsx @@ -15,8 +15,8 @@ import { getAnyToolConfirmationData, ToolConfirmationData, NotificationEvent, + type Message, } from '../types/message'; -import { Message } from '../api'; import ToolCallConfirmation from './ToolCallConfirmation'; import ElicitationRequest from './ElicitationRequest'; import MessageCopyLink from './MessageCopyLink'; diff --git a/ui/desktop/src/components/McpApps/McpAppRenderer.tsx b/ui/desktop/src/components/McpApps/McpAppRenderer.tsx index 27c5de93c..3be26aa12 100644 --- a/ui/desktop/src/components/McpApps/McpAppRenderer.tsx +++ b/ui/desktop/src/components/McpApps/McpAppRenderer.tsx @@ -367,7 +367,7 @@ export default function McpAppRenderer({ const tool: Tool = { name: toolName, description: match.description || undefined, - inputSchema: (match.input_schema as Tool['inputSchema']) ?? { type: 'object' as const }, + inputSchema: (match.inputSchema as Tool['inputSchema']) ?? { type: 'object' as const }, }; toolDefRef.current = tool; setMcpTool(tool); diff --git a/ui/desktop/src/components/McpApps/toolsCache.ts b/ui/desktop/src/components/McpApps/toolsCache.ts index 6c8af77df..3c7bff067 100644 --- a/ui/desktop/src/components/McpApps/toolsCache.ts +++ b/ui/desktop/src/components/McpApps/toolsCache.ts @@ -9,10 +9,9 @@ * automatically coalesce into a single network call. */ -import type { ToolInfo } from '../../api/types.gen'; -import { listMcpAppTools } from '../../acp/mcp-apps'; +import { listMcpAppTools, type McpAppTool } from '../../acp/mcp-apps'; -type ToolsList = Array; +type ToolsList = Array; const cache = new Map>(); diff --git a/ui/desktop/src/components/ProgressiveMessageList.tsx b/ui/desktop/src/components/ProgressiveMessageList.tsx index 9cb402873..0a5b094ad 100644 --- a/ui/desktop/src/components/ProgressiveMessageList.tsx +++ b/ui/desktop/src/components/ProgressiveMessageList.tsx @@ -16,7 +16,6 @@ import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { defineMessages, useIntl } from '../i18n'; -import { Message, SystemNotificationContent } from '../api'; import GooseMessage from './GooseMessage'; import UserMessage from './UserMessage'; import { @@ -27,7 +26,7 @@ import { CreditsExhaustedNotification, getCreditsExhaustedNotification, } from './context_management/CreditsExhaustedNotification'; -import { NotificationEvent } from '../types/message'; +import type { Message, NotificationEvent, SystemNotificationContent } from '../types/message'; import LoadingGoose from './LoadingGoose'; import { ChatType } from '../types/chat'; import { identifyConsecutiveToolCalls, isInChain } from '../utils/toolCallChaining'; diff --git a/ui/desktop/src/components/SessionActionsHeader.tsx b/ui/desktop/src/components/SessionActionsHeader.tsx index 3ff57405a..dd9f0e5db 100644 --- a/ui/desktop/src/components/SessionActionsHeader.tsx +++ b/ui/desktop/src/components/SessionActionsHeader.tsx @@ -4,8 +4,8 @@ import { toast } from 'react-toastify'; import { AppEvents } from '../constants/events'; import { defineMessages, useIntl } from '../i18n'; import { acpExportSession, acpForkSession, acpRenameSession } from '../acp/sessions'; -import type { Session } from '../api'; import { getSessionDisplayName } from '../sessions'; +import type { Session } from '../types/session'; import { errorMessage } from '../utils/conversionUtils'; import { cn } from '../utils'; import { Button } from './ui/button'; diff --git a/ui/desktop/src/components/ToolApprovalButtons.tsx b/ui/desktop/src/components/ToolApprovalButtons.tsx index e0cd8c97d..5dcfbce04 100644 --- a/ui/desktop/src/components/ToolApprovalButtons.tsx +++ b/ui/desktop/src/components/ToolApprovalButtons.tsx @@ -1,6 +1,6 @@ import { useState, useEffect } from 'react'; import { Button } from './ui/button'; -import { Permission } from '../api'; +import type { Permission } from '../types/permissions'; import { resolveAcpPermissionRequest } from '../acp/permissionRequests'; import { defineMessages, useIntl } from '../i18n'; diff --git a/ui/desktop/src/components/ToolCallConfirmation.tsx b/ui/desktop/src/components/ToolCallConfirmation.tsx index a91f75955..97d95ef2d 100644 --- a/ui/desktop/src/components/ToolCallConfirmation.tsx +++ b/ui/desktop/src/components/ToolCallConfirmation.tsx @@ -1,4 +1,4 @@ -import { ActionRequired } from '../api'; +import type { ActionRequired } from '../types/message'; import { defineMessages, useIntl } from '../i18n'; import { snakeToTitleCase } from '../utils'; import ToolApprovalButtons from './ToolApprovalButtons'; diff --git a/ui/desktop/src/components/ToolCallWithResponse.tsx b/ui/desktop/src/components/ToolCallWithResponse.tsx index 1df98cfe8..1f0235483 100644 --- a/ui/desktop/src/components/ToolCallWithResponse.tsx +++ b/ui/desktop/src/components/ToolCallWithResponse.tsx @@ -16,7 +16,7 @@ import { LoadingStatus } from './ui/Dot'; import { ChevronRight, ExternalLink } from 'lucide-react'; import { TooltipWrapper } from './settings/providers/subcomponents/buttons/TooltipWrapper'; import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'; -import type { ContentBlock } from '../api'; +import type { ContentBlock } from '../types/message'; import McpAppRenderer from './McpApps/McpAppRenderer'; import ToolApprovalButtons from './ToolApprovalButtons'; diff --git a/ui/desktop/src/components/UserMessage.tsx b/ui/desktop/src/components/UserMessage.tsx index 77a0f446b..eafefb438 100644 --- a/ui/desktop/src/components/UserMessage.tsx +++ b/ui/desktop/src/components/UserMessage.tsx @@ -1,8 +1,7 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import ImagePreview from './ImagePreview'; import MarkdownContent from './MarkdownContent'; -import { getTextAndImageContent } from '../types/message'; -import { Message } from '../api'; +import { getTextAndImageContent, type Message } from '../types/message'; import MessageCopyLink from './MessageCopyLink'; import { formatMessageTimestamp } from '../utils/timeUtils'; import Edit from './icons/Edit'; diff --git a/ui/desktop/src/components/apps/AppsView.tsx b/ui/desktop/src/components/apps/AppsView.tsx index af5aebe4a..c3cc353fd 100644 --- a/ui/desktop/src/components/apps/AppsView.tsx +++ b/ui/desktop/src/components/apps/AppsView.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { MainPanelLayout } from '../Layout/MainPanelLayout'; import { Button } from '../ui/button'; import { Download, Play, Upload } from 'lucide-react'; -import type { GooseApp } from '../../api'; +import type { GooseApp } from '../../types/apps'; import { exportMcpApp, importMcpApp, listMcpApps } from '../../acp/mcp-apps'; import { useChatContext } from '../../contexts/ChatContext'; import { formatAppName } from '../../utils/conversionUtils'; diff --git a/ui/desktop/src/components/bottom_menu/BottomMenuExtensionSelection.tsx b/ui/desktop/src/components/bottom_menu/BottomMenuExtensionSelection.tsx index 0648e01bc..e6836cc06 100644 --- a/ui/desktop/src/components/bottom_menu/BottomMenuExtensionSelection.tsx +++ b/ui/desktop/src/components/bottom_menu/BottomMenuExtensionSelection.tsx @@ -3,7 +3,7 @@ import { useConfig, type FixedExtensionEntry } from '../ConfigContext'; import { toastService } from '../../toasts'; import { formatExtensionName } from '../settings/extensions/subcomponents/ExtensionList'; import { nameToKey } from '../settings/extensions/utils'; -import { ExtensionConfig, getSessionExtensions } from '../../api'; +import type { ExtensionConfig } from '../../types/extensions'; import { getSessionExtensions as getAcpSessionExtensions } from '../../acp/session-extensions'; import { addToAgent, removeFromAgent } from '../settings/extensions/agent-api'; import { defineMessages, useIntl } from '../../i18n'; @@ -60,7 +60,7 @@ interface BottomMenuExtensionSelectionProps { onNextChatExtensionDraftChange?: (draft: NextChatExtensionDraft) => void; } -type GetSessionExtensionsSignal = Parameters[0]['signal']; +type GetSessionExtensionsSignal = { aborted: boolean }; const EXTENSION_SORT_DELAY_MS = 800; diff --git a/ui/desktop/src/components/context_management/CreditsExhaustedNotification.tsx b/ui/desktop/src/components/context_management/CreditsExhaustedNotification.tsx index 45c83b646..10427567f 100644 --- a/ui/desktop/src/components/context_management/CreditsExhaustedNotification.tsx +++ b/ui/desktop/src/components/context_management/CreditsExhaustedNotification.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { AlertTriangle, ExternalLink } from 'lucide-react'; -import { Message, SystemNotificationContent } from '../../api'; +import type { Message, SystemNotificationContent } from '../../types/message'; import { WEB_PROTOCOLS } from '../../utils/urlSecurity'; import { defineMessages, useIntl } from '../../i18n'; diff --git a/ui/desktop/src/components/context_management/SystemNotificationInline.tsx b/ui/desktop/src/components/context_management/SystemNotificationInline.tsx index ee8732bb2..d0dcbbe1b 100644 --- a/ui/desktop/src/components/context_management/SystemNotificationInline.tsx +++ b/ui/desktop/src/components/context_management/SystemNotificationInline.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Message, SystemNotificationContent } from '../../api'; +import type { Message, SystemNotificationContent } from '../../types/message'; interface SystemNotificationInlineProps { notification: SystemNotificationContent; diff --git a/ui/desktop/src/components/extensions/ExtensionsView.tsx b/ui/desktop/src/components/extensions/ExtensionsView.tsx index b1606a5c4..b0a3c549a 100644 --- a/ui/desktop/src/components/extensions/ExtensionsView.tsx +++ b/ui/desktop/src/components/extensions/ExtensionsView.tsx @@ -1,6 +1,6 @@ import { View, ViewOptions } from '../../utils/navigationUtils'; import ExtensionsSection from '../settings/extensions/ExtensionsSection'; -import { ExtensionConfig } from '../../api'; +import type { ExtensionConfig } from '../../types/extensions'; import { MainPanelLayout } from '../Layout/MainPanelLayout'; import { Button } from '../ui/button'; import { Plus } from 'lucide-react'; diff --git a/ui/desktop/src/components/onboarding/ProviderSelector.tsx b/ui/desktop/src/components/onboarding/ProviderSelector.tsx index ccb6031c3..ec202cde0 100644 --- a/ui/desktop/src/components/onboarding/ProviderSelector.tsx +++ b/ui/desktop/src/components/onboarding/ProviderSelector.tsx @@ -1,6 +1,7 @@ import { useState, useEffect, useMemo } from 'react'; -import { ProviderDetails, UpdateCustomProviderRequest } from '../../api'; +import type { ProviderDetails } from '../../api'; import { acpCreateCustomProviderFromRequest, acpListProviderDetails } from '../../acp/providers'; +import type { UpdateCustomProviderRequest } from '../../types/providers'; import { Select } from '../ui/Select'; import ProviderConfigForm from './ProviderConfigForm'; import LocalModelPicker from './LocalModelPicker'; diff --git a/ui/desktop/src/components/sessions/SessionViewComponents.tsx b/ui/desktop/src/components/sessions/SessionViewComponents.tsx index d1e8c29fe..693a55eb0 100644 --- a/ui/desktop/src/components/sessions/SessionViewComponents.tsx +++ b/ui/desktop/src/components/sessions/SessionViewComponents.tsx @@ -12,9 +12,9 @@ import { getThinkingContent, ToolRequestMessageContent, ToolResponseMessageContent, + type Message, } from '../../types/message'; import { formatMessageTimestamp } from '../../utils/timeUtils'; -import { Message } from '../../api'; const i18n = defineMessages({ errorLoadingDetails: { diff --git a/ui/desktop/src/components/settings/SettingsView.tsx b/ui/desktop/src/components/settings/SettingsView.tsx index 7b8d70251..1b0a7d03e 100644 --- a/ui/desktop/src/components/settings/SettingsView.tsx +++ b/ui/desktop/src/components/settings/SettingsView.tsx @@ -6,7 +6,7 @@ import ExternalBackendSection from './app/ExternalBackendSection'; import AppSettingsSection from './app/AppSettingsSection'; import ConfigSettings from './config/ConfigSettings'; import PromptsSettingsSection from './PromptsSettingsSection'; -import { ExtensionConfig } from '../../api'; +import type { ExtensionConfig } from '../../types/extensions'; import { MainPanelLayout } from '../Layout/MainPanelLayout'; import { Bot, diff --git a/ui/desktop/src/components/settings/extensions/ExtensionsSection.tsx b/ui/desktop/src/components/settings/extensions/ExtensionsSection.tsx index 6a26391cc..a55e30732 100644 --- a/ui/desktop/src/components/settings/extensions/ExtensionsSection.tsx +++ b/ui/desktop/src/components/settings/extensions/ExtensionsSection.tsx @@ -15,7 +15,7 @@ import { } from './utils'; import { activateExtensionDefault, deleteExtension, toggleExtensionDefault } from './index'; -import { ExtensionConfig } from '../../../api/types.gen'; +import type { ExtensionConfig } from '../../../types/extensions'; const i18n = defineMessages({ addCustomExtension: { diff --git a/ui/desktop/src/components/settings/extensions/agent-api.ts b/ui/desktop/src/components/settings/extensions/agent-api.ts index dec6c3639..27ba11bad 100644 --- a/ui/desktop/src/components/settings/extensions/agent-api.ts +++ b/ui/desktop/src/components/settings/extensions/agent-api.ts @@ -1,5 +1,5 @@ import { toastService } from '../../../toasts'; -import { ExtensionConfig } from '../../../api'; +import type { ExtensionConfig } from '../../../types/extensions'; import { addSessionExtension, removeSessionExtension } from '../../../acp/session-extensions'; import { errorMessage } from '../../../utils/conversionUtils'; import { diff --git a/ui/desktop/src/components/settings/extensions/bundled-extensions.ts b/ui/desktop/src/components/settings/extensions/bundled-extensions.ts index 332d1dfba..04dd4e95c 100644 --- a/ui/desktop/src/components/settings/extensions/bundled-extensions.ts +++ b/ui/desktop/src/components/settings/extensions/bundled-extensions.ts @@ -1,4 +1,4 @@ -import type { ExtensionConfig } from '../../../api/types.gen'; +import type { ExtensionConfig } from '../../../types/extensions'; import { FixedExtensionEntry } from '../../ConfigContext'; import bundledExtensionsData from './bundled-extensions.json'; import deprecatedBundledExtensionsData from './deprecated-bundled-extensions.json'; diff --git a/ui/desktop/src/components/settings/extensions/deeplink.ts b/ui/desktop/src/components/settings/extensions/deeplink.ts index f8d59b40c..fe3f98c7e 100644 --- a/ui/desktop/src/components/settings/extensions/deeplink.ts +++ b/ui/desktop/src/components/settings/extensions/deeplink.ts @@ -1,4 +1,4 @@ -import type { ExtensionConfig } from '../../../api'; +import type { ExtensionConfig } from '../../../types/extensions'; import { toastService } from '../../../toasts'; import { DEFAULT_EXTENSION_TIMEOUT } from './utils'; diff --git a/ui/desktop/src/components/settings/extensions/extension-manager.ts b/ui/desktop/src/components/settings/extensions/extension-manager.ts index 1b3c23537..005fe6c80 100644 --- a/ui/desktop/src/components/settings/extensions/extension-manager.ts +++ b/ui/desktop/src/components/settings/extensions/extension-manager.ts @@ -1,4 +1,4 @@ -import type { ExtensionConfig } from '../../../api/types.gen'; +import type { ExtensionConfig } from '../../../types/extensions'; import { toastService } from '../../../toasts'; import { trackExtensionAdded, diff --git a/ui/desktop/src/components/settings/extensions/subcomponents/ExtensionList.tsx b/ui/desktop/src/components/settings/extensions/subcomponents/ExtensionList.tsx index 40aff0b5b..e9e3d92d5 100644 --- a/ui/desktop/src/components/settings/extensions/subcomponents/ExtensionList.tsx +++ b/ui/desktop/src/components/settings/extensions/subcomponents/ExtensionList.tsx @@ -1,6 +1,6 @@ import ExtensionItem from './ExtensionItem'; import builtInExtensionsData from '../../../../built-in-extensions.json'; -import { ExtensionConfig } from '../../../../api'; +import type { ExtensionConfig } from '../../../../types/extensions'; import { FixedExtensionEntry } from '../../../ConfigContext'; import { combineCmdAndArgs } from '../utils'; import { defineMessages, useIntl } from '../../../../i18n'; @@ -164,7 +164,7 @@ export function getSubtitle(config: ExtensionConfig) { default: return { description: config.description || null, - command: 'cmd' in config ? combineCmdAndArgs(config.cmd, config.args) : null, + command: 'cmd' in config ? combineCmdAndArgs(config.cmd, config.args ?? []) : null, }; } } diff --git a/ui/desktop/src/components/settings/extensions/utils.ts b/ui/desktop/src/components/settings/extensions/utils.ts index 05f0dc3e7..a4eb77ee4 100644 --- a/ui/desktop/src/components/settings/extensions/utils.ts +++ b/ui/desktop/src/components/settings/extensions/utils.ts @@ -1,5 +1,5 @@ import type { FixedExtensionEntry } from '../../ConfigContext'; -import type { ExtensionConfig } from '../../../api/types.gen'; +import type { ExtensionConfig } from '../../../types/extensions'; import { parse as parseShellQuote } from 'shell-quote'; // Default extension timeout in seconds @@ -110,7 +110,7 @@ export function extensionToFormData(extension: FixedExtensionEntry): ExtensionFo extension.type === 'platform' ? 'stdio' : extension.type, - cmd: extension.type === 'stdio' ? combineCmdAndArgs(extension.cmd, extension.args) : undefined, + cmd: extension.type === 'stdio' ? combineCmdAndArgs(extension.cmd, extension.args ?? []) : undefined, endpoint: extension.type === 'streamable_http' || extension.type === 'sse' ? (extension.uri ?? undefined) diff --git a/ui/desktop/src/components/settings/models/bottom_bar/ModelsBottomBar.tsx b/ui/desktop/src/components/settings/models/bottom_bar/ModelsBottomBar.tsx index 5e5ee609d..5db18972a 100644 --- a/ui/desktop/src/components/settings/models/bottom_bar/ModelsBottomBar.tsx +++ b/ui/desktop/src/components/settings/models/bottom_bar/ModelsBottomBar.tsx @@ -15,7 +15,7 @@ import { getModelDisplayName } from '../predefinedModelsUtils'; import { ModelSettingsPanel } from '../../localInference/ModelSettingsPanel'; import { ScrollArea } from '../../../ui/scroll-area'; import { defineMessages, useIntl } from '../../../../i18n'; -import type { Message } from '../../../../api'; +import type { Message } from '../../../../types/message'; const i18n = defineMessages({ selectModel: { diff --git a/ui/desktop/src/components/settings/permission/PermissionModal.tsx b/ui/desktop/src/components/settings/permission/PermissionModal.tsx index 748456c14..01dbf85ca 100644 --- a/ui/desktop/src/components/settings/permission/PermissionModal.tsx +++ b/ui/desktop/src/components/settings/permission/PermissionModal.tsx @@ -1,7 +1,6 @@ import { useEffect, useMemo, useState } from 'react'; import { Button } from '../../ui/button'; import { ChevronDownIcon, SlidersHorizontal, AlertCircle } from 'lucide-react'; -import { PermissionLevel } from '../../../api'; import { listTools, setToolPermissions } from '../../../acp/permissions'; import type { ToolListItem, ToolPermissionLevel } from '../../../acp/permissions'; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '../../ui/dialog'; @@ -80,7 +79,7 @@ export default function PermissionModal({ extensionName, onClose }: PermissionMo { value: 'always_allow', label: intl.formatMessage(i18n.alwaysAllow) }, { value: 'ask_before', label: intl.formatMessage(i18n.askBefore) }, { value: 'never_allow', label: intl.formatMessage(i18n.neverAllow) }, - ] as { value: PermissionLevel; label: string }[]; + ] as { value: ToolPermissionLevel; label: string }[]; const chatContext = useChatContext(); const sessionId = chatContext?.chat.sessionId || ''; @@ -126,7 +125,7 @@ export default function PermissionModal({ extensionName, onClose }: PermissionMo fetchTools(); }, [extensionName, sessionId]); - const handleSettingChange = (toolName: string, newPermission: PermissionLevel) => { + const handleSettingChange = (toolName: string, newPermission: ToolPermissionLevel) => { setUpdatedPermissions((prev) => ({ ...prev, [toolName]: newPermission, @@ -243,7 +242,7 @@ export default function PermissionModal({ extensionName, onClose }: PermissionMo - handleSettingChange(tool.name, option.value as PermissionLevel) + handleSettingChange(tool.name, option.value) } > {option.label} diff --git a/ui/desktop/src/components/settings/providers/ProviderGrid.tsx b/ui/desktop/src/components/settings/providers/ProviderGrid.tsx index 86a5327e8..4175b375d 100644 --- a/ui/desktop/src/components/settings/providers/ProviderGrid.tsx +++ b/ui/desktop/src/components/settings/providers/ProviderGrid.tsx @@ -2,8 +2,9 @@ import React, { memo, useMemo, useCallback, useState } from 'react'; import { ProviderCard } from './subcomponents/ProviderCard'; import CardContainer from './subcomponents/CardContainer'; import ProviderConfigurationModal from './modal/ProviderConfigurationModal'; -import { ProviderDetails, UpdateCustomProviderRequest } from '../../../api'; +import type { ProviderDetails } from '../../../api'; import type { CustomProviderConfigDto } from '@aaif/goose-sdk'; +import type { UpdateCustomProviderRequest } from '../../../types/providers'; import { acpCreateCustomProviderFromRequest, acpGetCustomProvider, diff --git a/ui/desktop/src/components/settings/providers/modal/subcomponents/forms/CustomProviderForm.tsx b/ui/desktop/src/components/settings/providers/modal/subcomponents/forms/CustomProviderForm.tsx index c7afa25e4..087ff54ed 100644 --- a/ui/desktop/src/components/settings/providers/modal/subcomponents/forms/CustomProviderForm.tsx +++ b/ui/desktop/src/components/settings/providers/modal/subcomponents/forms/CustomProviderForm.tsx @@ -3,7 +3,7 @@ import { Input } from '../../../../../ui/input'; import { Select } from '../../../../../ui/Select'; import { Button } from '../../../../../ui/button'; import { SecureStorageNotice } from '../SecureStorageNotice'; -import { UpdateCustomProviderRequest } from '../../../../../../api'; +import type { UpdateCustomProviderRequest } from '../../../../../../types/providers'; import type { ProviderTemplateDto } from '@aaif/goose-sdk'; import { Plus, X, Trash2, AlertTriangle, ExternalLink, Search, Settings } from 'lucide-react'; import { cn } from '../../../../../../utils'; diff --git a/ui/desktop/src/hooks/useAutoSubmit.test.tsx b/ui/desktop/src/hooks/useAutoSubmit.test.tsx index fce4395b5..324729f94 100644 --- a/ui/desktop/src/hooks/useAutoSubmit.test.tsx +++ b/ui/desktop/src/hooks/useAutoSubmit.test.tsx @@ -4,8 +4,8 @@ import { MemoryRouter } from 'react-router-dom'; import type { PropsWithChildren } from 'react'; import { useAutoSubmit } from './useAutoSubmit'; import { ChatState } from '../types/chatState'; -import type { Session } from '../api'; import type { UserInput } from '../types/message'; +import type { Session } from '../types/session'; function makeSession(overrides: Partial = {}): Session { return { diff --git a/ui/desktop/src/hooks/useAutoSubmit.ts b/ui/desktop/src/hooks/useAutoSubmit.ts index 2d41c9077..b03c9ca35 100644 --- a/ui/desktop/src/hooks/useAutoSubmit.ts +++ b/ui/desktop/src/hooks/useAutoSubmit.ts @@ -1,10 +1,9 @@ import { AppEvents } from '../constants/events'; import { useCallback, useEffect, useRef } from 'react'; import { useSearchParams } from 'react-router-dom'; -import { Session } from '../api'; -import { Message } from '../api'; import { ChatState } from '../types/chatState'; -import { UserInput } from '../types/message'; +import type { Message, UserInput } from '../types/message'; +import type { Session } from '../types/session'; /** * Auto-submit scenarios: diff --git a/ui/desktop/src/hooks/useChatSession.ts b/ui/desktop/src/hooks/useChatSession.ts index 1b1fc1537..1611c95de 100644 --- a/ui/desktop/src/hooks/useChatSession.ts +++ b/ui/desktop/src/hooks/useChatSession.ts @@ -3,9 +3,15 @@ import { defineMessages, useIntl } from '../i18n'; import { AppEvents } from '../constants/events'; import { ChatState } from '../types/chatState'; -import { Message, Session, TokenState } from '../api'; +import type { TokenState } from '../types/chat'; +import type { Session } from '../types/session'; -import { createUserMessage, NotificationEvent, UserInput } from '../types/message'; +import { + createUserMessage, + type Message, + type NotificationEvent, + type UserInput, +} from '../types/message'; import { errorMessage } from '../utils/conversionUtils'; import type { UseChatSessionParams, UseChatSessionResult } from './useChatSessionTypes'; import { resolveAcpElicitationRequest } from '../acp/elicitationRequests'; diff --git a/ui/desktop/src/hooks/useChatSessionTypes.ts b/ui/desktop/src/hooks/useChatSessionTypes.ts index c40470497..3fc6f0421 100644 --- a/ui/desktop/src/hooks/useChatSessionTypes.ts +++ b/ui/desktop/src/hooks/useChatSessionTypes.ts @@ -1,6 +1,7 @@ -import type { Message, Session, TokenState } from '../api'; import type { ChatState } from '../types/chatState'; -import type { NotificationEvent, UserInput } from '../types/message'; +import type { TokenState } from '../types/chat'; +import type { Message, NotificationEvent, UserInput } from '../types/message'; +import type { Session } from '../types/session'; export interface UseChatSessionParams { sessionId: string; diff --git a/ui/desktop/src/hooks/useNavigationSessions.ts b/ui/desktop/src/hooks/useNavigationSessions.ts index 569ee7e1e..4629f95f3 100644 --- a/ui/desktop/src/hooks/useNavigationSessions.ts +++ b/ui/desktop/src/hooks/useNavigationSessions.ts @@ -3,7 +3,7 @@ import { useNavigate, useLocation, useSearchParams } from 'react-router-dom'; import { useChatContext } from '../contexts/ChatContext'; import { getSessionDisplayName } from '../sessions'; import { AppEvents } from '../constants/events'; -import type { Session } from '../api'; +import type { Session } from '../types/session'; import { acpGetSessionListItem, acpListRecentSessions, diff --git a/ui/desktop/src/main.ts b/ui/desktop/src/main.ts index 29c7bf57b..c91bb31ed 100644 --- a/ui/desktop/src/main.ts +++ b/ui/desktop/src/main.ts @@ -49,7 +49,7 @@ import { import { UPDATES_ENABLED } from './updates'; import './utils/recipeHash'; import { Client } from './api/client'; -import { GooseApp } from './api'; +import type { GooseApp } from './types/apps'; import installExtension, { REACT_DEVELOPER_TOOLS } from 'electron-devtools-installer'; import { BLOCKED_PROTOCOLS, WEB_PROTOCOLS } from './utils/urlSecurity'; import { buildCSP } from './utils/csp'; diff --git a/ui/desktop/src/preload.ts b/ui/desktop/src/preload.ts index 4effe64f9..231995f4a 100644 --- a/ui/desktop/src/preload.ts +++ b/ui/desktop/src/preload.ts @@ -1,6 +1,6 @@ import Electron, { contextBridge, ipcRenderer, webUtils } from 'electron'; import { Recipe } from './recipe'; -import { GooseApp } from './api'; +import type { GooseApp } from './types/apps'; import type { Settings, SettingKey } from './utils/settings'; import { defaultSettings } from './utils/settings'; diff --git a/ui/desktop/src/sessions.ts b/ui/desktop/src/sessions.ts index 49c7f90b1..18ad1e670 100644 --- a/ui/desktop/src/sessions.ts +++ b/ui/desktop/src/sessions.ts @@ -1,4 +1,5 @@ -import { Session, ExtensionConfig } from './api'; +import type { Session } from './types/session'; +import type { ExtensionConfig } from './types/extensions'; import { DEFAULT_CHAT_TITLE } from './contexts/ChatContext'; import type { setViewType } from './hooks/useNavigation'; import type { FixedExtensionEntry } from './components/ConfigContext'; diff --git a/ui/desktop/src/types/apps.ts b/ui/desktop/src/types/apps.ts new file mode 100644 index 000000000..311d2e10f --- /dev/null +++ b/ui/desktop/src/types/apps.ts @@ -0,0 +1,46 @@ +export type CspMetadata = { + baseUriDomains?: string[] | null; + connectDomains?: string[] | null; + frameDomains?: string[] | null; + resourceDomains?: string[] | null; +}; + +export type PermissionsMetadata = { + camera?: boolean; + clipboardWrite?: boolean; + geolocation?: boolean; + microphone?: boolean; +}; + +export type UiMetadata = { + csp?: CspMetadata | null; + domain?: string | null; + permissions?: PermissionsMetadata; + prefersBorder?: boolean | null; +}; + +export type ResourceMetadata = { + ui?: UiMetadata | null; +}; + +export type McpAppResource = { + _meta?: ResourceMetadata | null; + blob?: string | null; + description?: string | null; + mimeType: string; + name: string; + text?: string | null; + uri: string; +}; + +export type WindowProps = { + height?: number; + resizable?: boolean; + width?: number; +}; + +export type GooseApp = McpAppResource & + WindowProps & { + mcpServers?: string[]; + prd?: string | null; + }; diff --git a/ui/desktop/src/types/chat.ts b/ui/desktop/src/types/chat.ts index 358e728f5..32e007c74 100644 --- a/ui/desktop/src/types/chat.ts +++ b/ui/desktop/src/types/chat.ts @@ -1,5 +1,19 @@ import { Recipe } from '../recipe'; -import { Message } from '../api'; +import type { Message } from './message'; + +export type TokenState = { + accumulatedCacheReadTokens?: number; + accumulatedCacheWriteTokens?: number; + accumulatedCost?: number | null; + accumulatedInputTokens: number; + accumulatedOutputTokens: number; + accumulatedTotalTokens: number; + cacheReadTokens?: number; + cacheWriteTokens?: number; + inputTokens: number; + outputTokens: number; + totalTokens: number; +}; export interface ChatType { sessionId: string; diff --git a/ui/desktop/src/types/diagnostics.ts b/ui/desktop/src/types/diagnostics.ts new file mode 100644 index 000000000..05fc285b6 --- /dev/null +++ b/ui/desktop/src/types/diagnostics.ts @@ -0,0 +1,62 @@ +export type DiagnosticsLevel = 'summary' | 'full'; + +export type SystemInfo = { + app_version: string; + architecture: string; + enabled_extensions: string[]; + model?: string | null; + os: string; + os_version: string; + provider?: string | null; +}; + +export type DiagnosticsConfig = { + configPath: string; + configYaml?: string | null; + truncated: boolean; +}; + +export type DiagnosticsError = { + message: string; + path?: string | null; +}; + +export type DiagnosticsExtensions = { + enabled: string[]; +}; + +export type DiagnosticsTextFile = { + content: string; + path: string; + truncated: boolean; +}; + +export type DiagnosticsLogs = { + llm: DiagnosticsTextFile[]; + server?: DiagnosticsTextFile | null; +}; + +export type DiagnosticsPrompt = { + content: string; + name: string; +}; + +export type DiagnosticsScheduledRecipe = { + content: string; + path: string; +}; + +export type DiagnosticsReport = { + config?: DiagnosticsConfig | null; + errors: DiagnosticsError[]; + extensions: DiagnosticsExtensions; + generatedAt: string; + level: DiagnosticsLevel; + logs: DiagnosticsLogs; + prompts: DiagnosticsPrompt[]; + schedule?: unknown; + scheduledRecipes: DiagnosticsScheduledRecipe[]; + schemaVersion: number; + session?: unknown; + system: SystemInfo; +}; diff --git a/ui/desktop/src/types/extensions.ts b/ui/desktop/src/types/extensions.ts new file mode 100644 index 000000000..293b59f72 --- /dev/null +++ b/ui/desktop/src/types/extensions.ts @@ -0,0 +1,58 @@ +import type { RecipeExtensionDto } from '@aaif/goose-sdk'; + +export type Envs = Record; + +type LegacySseExtensionConfig = { + description?: string | null; + name: string; + type: 'sse'; + uri?: string | null; +}; + +type FrontendTool = { + _meta?: Record; + annotations?: Record; + description?: string; + execution?: Record; + icons?: unknown[]; + inputSchema: Record; + name: string; + outputSchema?: Record; + title?: string; +}; + +type FrontendExtensionConfig = { + available_tools?: string[] | null; + bundled?: boolean | null; + description?: string | null; + instructions?: string | null; + name: string; + tools: FrontendTool[]; + type: 'frontend'; +}; + +type InlinePythonExtensionConfig = { + available_tools?: string[] | null; + code: string; + dependencies?: string[] | null; + description?: string | null; + name: string; + timeout?: number | null; + type: 'inline_python'; +}; + +export type ExtensionConfig = + | RecipeExtensionDto + | LegacySseExtensionConfig + | FrontendExtensionConfig + | InlinePythonExtensionConfig; + +export type ExtensionEntry = ExtensionConfig & { + enabled: boolean; +}; + +export type ExtensionLoadResult = { + error?: string | null; + name: string; + success: boolean; +}; diff --git a/ui/desktop/src/types/message.ts b/ui/desktop/src/types/message.ts index dc3ab844e..840f65895 100644 --- a/ui/desktop/src/types/message.ts +++ b/ui/desktop/src/types/message.ts @@ -1,11 +1,231 @@ -import { - Message, - MessageEvent, - ActionRequired, - ToolRequest, - ToolResponse, - ToolConfirmationRequest, -} from '../api'; +import type { TokenState } from './chat'; + +type JsonObject = Record; +export type Role = 'user' | 'assistant'; + +export type Annotations = { + audience?: Role[]; + lastModified?: string; + priority?: number; +}; + +type ContentAnnotations = + | { + audience?: Role[]; + lastModified?: string; + priority?: number; + _meta?: JsonObject; + } + | JsonObject; + +export type TextContent = { + _meta?: JsonObject; + annotations?: Annotations | JsonObject; + text: string; +}; + +export type ImageContent = { + _meta?: JsonObject; + annotations?: Annotations | JsonObject; + data: string; + mimeType: string; +}; + +export type ContentBlock = + | ({ type: 'text' } & RawTextContent) + | ({ type: 'image' } & RawImageContent) + | ({ type: 'resource' } & RawEmbeddedResource) + | ({ type: 'audio' } & RawAudioContent) + | ({ type: 'resource_link' } & RawResource); + +type RawTextContent = { + _meta?: JsonObject; + annotations?: ContentAnnotations; + text: string; +}; + +type RawImageContent = { + _meta?: JsonObject; + annotations?: ContentAnnotations; + data: string; + mimeType: string; +}; + +type RawAudioContent = { + data: string; + mimeType: string; +}; + +type RawEmbeddedResource = { + _meta?: JsonObject; + resource: ResourceContents; +}; + +type RawResource = { + _meta?: JsonObject; + description?: string; + icons?: ContentIcon[]; + mimeType?: string; + name: string; + size?: number; + title?: string; + uri: string; +}; + +type ResourceContents = + | { + _meta?: JsonObject; + mimeType?: string; + text: string; + uri: string; + } + | { + _meta?: JsonObject; + blob: string; + mimeType?: string; + uri: string; + }; + +type ContentIcon = { + mimeType?: string; + sizes?: string[]; + src: string; + theme?: 'light' | 'dark' | JsonObject; +}; + +export type SystemNotificationType = 'thinkingMessage' | 'inlineMessage' | 'creditsExhausted'; + +export type SystemNotificationContent = { + data?: unknown; + msg: string; + notificationType: SystemNotificationType; +}; + +export type ActionRequired = { + data: ActionRequiredData; +}; + +export type ActionRequiredData = + | { + actionType: 'toolConfirmation'; + arguments: JsonObject; + id: string; + prompt?: string | null; + toolName: string; + } + | { + actionType: 'elicitation'; + id: string; + message: string; + requested_schema: unknown; + } + | { + action?: string; + actionType: 'elicitationResponse'; + id: string; + user_data: unknown; + }; + +export type FrontendToolRequest = { + id: string; + toolCall: JsonObject; +}; + +export type ThinkingContent = { + signature: string; + thinking: string; +}; + +export type RedactedThinkingContent = { + data: string; +}; + +export type ToolConfirmationRequest = { + arguments: JsonObject; + id: string; + prompt?: string | null; + toolName: string; +}; + +export type ToolRequest = { + _meta?: JsonObject; + id: string; + metadata?: JsonObject; + toolCall: JsonObject; +}; + +export type ToolResponse = { + id: string; + metadata?: JsonObject; + toolResult: JsonObject; +}; + +export type InferenceMetadata = { + provider: string; + requestedModel: string; + resolvedModel?: string | null; +}; + +export type MessageMetadata = { + agentVisible: boolean; + inference?: InferenceMetadata | null; + steer?: boolean; + userVisible: boolean; +}; + +export type MessageContent = + | (TextContent & { type: 'text' }) + | (ImageContent & { type: 'image' }) + | (ToolRequest & { type: 'toolRequest' }) + | (ToolResponse & { type: 'toolResponse' }) + | (ToolConfirmationRequest & { type: 'toolConfirmationRequest' }) + | (ActionRequired & { type: 'actionRequired' }) + | (FrontendToolRequest & { type: 'frontendToolRequest' }) + | (ThinkingContent & { type: 'thinking' }) + | (RedactedThinkingContent & { type: 'redactedThinking' }) + | (SystemNotificationContent & { type: 'systemNotification' }); + +export type Message = { + content: MessageContent[]; + created: number; + id?: string | null; + metadata: MessageMetadata; + role: Role; +}; + +export type Conversation = Message[]; + +export type MessageEvent = + | { + message: Message; + token_state: TokenState; + type: 'Message'; + } + | { + error: string; + type: 'Error'; + } + | { + reason: string; + token_state: TokenState; + type: 'Finish'; + } + | { + message: JsonObject; + request_id: string; + type: 'Notification'; + } + | { + conversation: Conversation; + type: 'UpdateConversation'; + } + | { + request_ids: string[]; + type: 'ActiveRequests'; + } + | { + type: 'Ping'; + }; export type ToolRequestMessageContent = ToolRequest & { type: 'toolRequest' }; export type ToolResponseMessageContent = ToolResponse & { type: 'toolResponse' }; diff --git a/ui/desktop/src/types/permissions.ts b/ui/desktop/src/types/permissions.ts new file mode 100644 index 000000000..ff684f752 --- /dev/null +++ b/ui/desktop/src/types/permissions.ts @@ -0,0 +1 @@ +export type Permission = 'always_allow' | 'allow_once' | 'cancel' | 'deny_once' | 'always_deny'; diff --git a/ui/desktop/src/types/providers.ts b/ui/desktop/src/types/providers.ts new file mode 100644 index 000000000..904191e03 --- /dev/null +++ b/ui/desktop/src/types/providers.ts @@ -0,0 +1,13 @@ +export type UpdateCustomProviderRequest = { + api_key: string; + api_url: string; + base_path?: string | null; + catalog_provider_id?: string | null; + display_name: string; + engine: string; + headers?: Record | null; + models: string[]; + preserves_thinking?: boolean | null; + requires_auth?: boolean; + supports_streaming?: boolean | null; +}; diff --git a/ui/desktop/src/types/session.ts b/ui/desktop/src/types/session.ts new file mode 100644 index 000000000..df3ee4b50 --- /dev/null +++ b/ui/desktop/src/types/session.ts @@ -0,0 +1,60 @@ +import type { Recipe } from '../recipe'; +import type { Message } from './message'; + +export type ExtensionData = Record; + +export type GooseMode = 'auto' | 'approve' | 'smart_approve' | 'chat'; + +export type ModelConfig = { + context_limit?: number | null; + max_tokens?: number | null; + model_name: string; + reasoning?: boolean | null; + request_params?: Record | null; + temperature?: number | null; + toolshim: boolean; + toolshim_model?: string | null; +}; + +export type Usage = { + cache_read_input_tokens?: number | null; + cache_write_input_tokens?: number | null; + input_tokens?: number | null; + output_tokens?: number | null; + total_tokens?: number | null; +}; + +export type SessionType = + | 'user' + | 'scheduled' + | 'sub_agent' + | 'hidden' + | 'terminal' + | 'gateway' + | 'acp'; + +export type Session = { + accumulated_cost?: number | null; + accumulated_usage?: Usage; + archived_at?: string | null; + conversation?: Message[] | null; + created_at: string; + extension_data: ExtensionData; + goose_mode?: GooseMode; + id: string; + last_message_at?: string | null; + last_message_snippet?: string | null; + message_count: number; + model_config?: ModelConfig | null; + name: string; + project_id?: string | null; + provider_name?: string | null; + recipe?: Recipe | null; + schedule_id?: string | null; + session_type?: SessionType; + updated_at: string; + usage?: Usage; + user_recipe_values?: Record | null; + user_set_name?: boolean; + working_dir: string; +}; diff --git a/ui/desktop/src/utils/extensionErrorUtils.ts b/ui/desktop/src/utils/extensionErrorUtils.ts index 369a64c82..0b3a8536a 100644 --- a/ui/desktop/src/utils/extensionErrorUtils.ts +++ b/ui/desktop/src/utils/extensionErrorUtils.ts @@ -2,7 +2,7 @@ * Shared constants and utilities for extension error handling */ -import { ExtensionLoadResult } from '../api/types.gen'; +import type { ExtensionLoadResult } from '../types/extensions'; import { toastService, ExtensionLoadingStatus } from '../toasts'; export const MAX_ERROR_MESSAGE_LENGTH = 70; diff --git a/ui/desktop/src/utils/nextChatExtensions.ts b/ui/desktop/src/utils/nextChatExtensions.ts index e94257ec7..5571a862d 100644 --- a/ui/desktop/src/utils/nextChatExtensions.ts +++ b/ui/desktop/src/utils/nextChatExtensions.ts @@ -1,4 +1,4 @@ -import type { ExtensionConfig } from '../api'; +import type { ExtensionConfig } from '../types/extensions'; import type { FixedExtensionEntry } from '../components/ConfigContext'; export type NextChatExtensionDraft = { diff --git a/ui/desktop/src/utils/platform_events.ts b/ui/desktop/src/utils/platform_events.ts index 32e1da9e2..79e4bc4da 100644 --- a/ui/desktop/src/utils/platform_events.ts +++ b/ui/desktop/src/utils/platform_events.ts @@ -1,4 +1,4 @@ -import type { GooseApp } from '../api'; +import type { GooseApp } from '../types/apps'; import { listMcpApps } from '../acp/mcp-apps'; interface PlatformEventData { diff --git a/ui/desktop/src/utils/toolCallChaining.ts b/ui/desktop/src/utils/toolCallChaining.ts index 3b6a5a785..40e496170 100644 --- a/ui/desktop/src/utils/toolCallChaining.ts +++ b/ui/desktop/src/utils/toolCallChaining.ts @@ -1,5 +1,9 @@ -import { getToolRequests, getTextAndImageContent, getToolResponses } from '../types/message'; -import { Message } from '../api'; +import { + getToolRequests, + getTextAndImageContent, + getToolResponses, + type Message, +} from '../types/message'; export function identifyConsecutiveToolCalls(messages: Message[]): number[][] { const chains: number[][] = [];