UI acp migratoin: Decouple desktop UI types from generated OpenAPI types (#10109)
This commit is contained in:
@@ -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';
|
||||
|
||||
@@ -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> = {}): Session {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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' },
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Message } from '../../api';
|
||||
import type { Message } from '../../types/message';
|
||||
import type { AcpElicitationRequest } from '../elicitationRequests';
|
||||
import {
|
||||
type AcpChatStateChange,
|
||||
|
||||
@@ -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<ContentBlock, { type: 'text' | 'image' }>;
|
||||
|
||||
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<MessageContent, { type: 'image' }>) {
|
||||
function hasImageContent(
|
||||
message: Message,
|
||||
image: Extract<StreamedContentBlock, { type: 'image' }>
|
||||
) {
|
||||
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') {
|
||||
|
||||
@@ -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[] }
|
||||
|
||||
@@ -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<AcpContentBlock, { type: 'resource' }>['resource']
|
||||
): Extract<ApiContentBlock, { type: 'resource' }>['resource'] {
|
||||
): Extract<GooseContentBlock, { type: 'resource' }>['resource'] {
|
||||
if ('text' in resource) {
|
||||
return {
|
||||
uri: resource.uri,
|
||||
@@ -303,7 +306,7 @@ interface DesktopMcpAppMeta extends Record<string, unknown> {
|
||||
}
|
||||
|
||||
type ToolResultValue = {
|
||||
content: ApiContentBlock[];
|
||||
content: GooseContentBlock[];
|
||||
structuredContent?: unknown;
|
||||
isError: boolean;
|
||||
_meta?: DesktopMcpAppMeta;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<string, unknown>;
|
||||
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<void> {
|
||||
export async function listMcpAppTools(
|
||||
sessionId: string,
|
||||
extensionName?: string
|
||||
): Promise<ToolInfo[] | null> {
|
||||
): Promise<McpAppTool[]> {
|
||||
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}__`;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ExtensionConfig } from '../api';
|
||||
import type { ExtensionConfig } from '../types/extensions';
|
||||
import { getAcpClient } from './acpConnection';
|
||||
import { extensionConfigToGooseExtension, gooseExtensionToExtensionConfig } from './extensions';
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 & {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<ToolInfo>;
|
||||
type ToolsList = Array<McpAppTool>;
|
||||
|
||||
const cache = new Map<string, Promise<ToolsList | null>>();
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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<typeof getSessionExtensions>[0]['signal'];
|
||||
type GetSessionExtensionsSignal = { aborted: boolean };
|
||||
|
||||
const EXTENSION_SORT_DELAY_MS = 800;
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Message, SystemNotificationContent } from '../../api';
|
||||
import type { Message, SystemNotificationContent } from '../../types/message';
|
||||
|
||||
interface SystemNotificationInlineProps {
|
||||
notification: SystemNotificationContent;
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ExtensionConfig } from '../../../api/types.gen';
|
||||
import type { ExtensionConfig } from '../../../types/extensions';
|
||||
import { toastService } from '../../../toasts';
|
||||
import {
|
||||
trackExtensionAdded,
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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
|
||||
<DropdownMenuItem
|
||||
key={option.value}
|
||||
onSelect={() =>
|
||||
handleSettingChange(tool.name, option.value as PermissionLevel)
|
||||
handleSettingChange(tool.name, option.value)
|
||||
}
|
||||
>
|
||||
{option.label}
|
||||
|
||||
@@ -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,
|
||||
|
||||
+1
-1
@@ -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';
|
||||
|
||||
@@ -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> = {}): Session {
|
||||
return {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
import type { RecipeExtensionDto } from '@aaif/goose-sdk';
|
||||
|
||||
export type Envs = Record<string, string>;
|
||||
|
||||
type LegacySseExtensionConfig = {
|
||||
description?: string | null;
|
||||
name: string;
|
||||
type: 'sse';
|
||||
uri?: string | null;
|
||||
};
|
||||
|
||||
type FrontendTool = {
|
||||
_meta?: Record<string, unknown>;
|
||||
annotations?: Record<string, unknown>;
|
||||
description?: string;
|
||||
execution?: Record<string, unknown>;
|
||||
icons?: unknown[];
|
||||
inputSchema: Record<string, unknown>;
|
||||
name: string;
|
||||
outputSchema?: Record<string, unknown>;
|
||||
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;
|
||||
};
|
||||
@@ -1,11 +1,231 @@
|
||||
import {
|
||||
Message,
|
||||
MessageEvent,
|
||||
ActionRequired,
|
||||
ToolRequest,
|
||||
ToolResponse,
|
||||
ToolConfirmationRequest,
|
||||
} from '../api';
|
||||
import type { TokenState } from './chat';
|
||||
|
||||
type JsonObject = Record<string, unknown>;
|
||||
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' };
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export type Permission = 'always_allow' | 'allow_once' | 'cancel' | 'deny_once' | 'always_deny';
|
||||
@@ -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<string, string> | null;
|
||||
models: string[];
|
||||
preserves_thinking?: boolean | null;
|
||||
requires_auth?: boolean;
|
||||
supports_streaming?: boolean | null;
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
import type { Recipe } from '../recipe';
|
||||
import type { Message } from './message';
|
||||
|
||||
export type ExtensionData = Record<string, unknown>;
|
||||
|
||||
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<string, unknown> | 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<string, string> | null;
|
||||
user_set_name?: boolean;
|
||||
working_dir: string;
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ExtensionConfig } from '../api';
|
||||
import type { ExtensionConfig } from '../types/extensions';
|
||||
import type { FixedExtensionEntry } from '../components/ConfigContext';
|
||||
|
||||
export type NextChatExtensionDraft = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { GooseApp } from '../api';
|
||||
import type { GooseApp } from '../types/apps';
|
||||
import { listMcpApps } from '../acp/mcp-apps';
|
||||
|
||||
interface PlatformEventData {
|
||||
|
||||
@@ -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[][] = [];
|
||||
|
||||
Reference in New Issue
Block a user