@@ -2,7 +2,7 @@
|
||||
|
||||
import type { Client, Options as Options2, TDataShape } from './client';
|
||||
import { client } from './client.gen';
|
||||
import type { AddExtensionData, AddExtensionErrors, AddExtensionResponses, BackupConfigData, BackupConfigErrors, BackupConfigResponses, ConfirmPermissionData, ConfirmPermissionErrors, ConfirmPermissionResponses, CreateCustomProviderData, CreateCustomProviderErrors, CreateCustomProviderResponses, CreateRecipeData, CreateRecipeErrors, CreateRecipeResponses, CreateScheduleData, CreateScheduleErrors, CreateScheduleResponses, DecodeRecipeData, DecodeRecipeErrors, DecodeRecipeResponses, DeleteRecipeData, DeleteRecipeErrors, DeleteRecipeResponses, DeleteScheduleData, DeleteScheduleErrors, DeleteScheduleResponses, DeleteSessionData, DeleteSessionErrors, DeleteSessionResponses, EncodeRecipeData, EncodeRecipeErrors, EncodeRecipeResponses, ExportSessionData, ExportSessionErrors, ExportSessionResponses, GetCustomProviderData, GetCustomProviderErrors, GetCustomProviderResponses, GetExtensionsData, GetExtensionsErrors, GetExtensionsResponses, GetProviderModelsData, GetProviderModelsErrors, GetProviderModelsResponses, GetSessionData, GetSessionErrors, GetSessionInsightsData, GetSessionInsightsErrors, GetSessionInsightsResponses, GetSessionResponses, GetToolsData, GetToolsErrors, GetToolsResponses, ImportSessionData, ImportSessionErrors, ImportSessionResponses, InitConfigData, InitConfigErrors, InitConfigResponses, InspectRunningJobData, InspectRunningJobErrors, InspectRunningJobResponses, KillRunningJobData, KillRunningJobResponses, ListRecipesData, ListRecipesErrors, ListRecipesResponses, ListSchedulesData, ListSchedulesErrors, ListSchedulesResponses, ListSessionsData, ListSessionsErrors, ListSessionsResponses, ManageContextData, ManageContextErrors, ManageContextResponses, ParseRecipeData, ParseRecipeErrors, ParseRecipeResponses, PauseScheduleData, PauseScheduleErrors, PauseScheduleResponses, ProvidersData, ProvidersResponses, ReadAllConfigData, ReadAllConfigResponses, ReadConfigData, ReadConfigErrors, ReadConfigResponses, RecoverConfigData, RecoverConfigErrors, RecoverConfigResponses, RemoveConfigData, RemoveConfigErrors, RemoveConfigResponses, RemoveCustomProviderData, RemoveCustomProviderErrors, RemoveCustomProviderResponses, RemoveExtensionData, RemoveExtensionErrors, RemoveExtensionResponses, ReplyData, ReplyErrors, ReplyResponses, ResumeAgentData, ResumeAgentErrors, ResumeAgentResponses, RunNowHandlerData, RunNowHandlerErrors, RunNowHandlerResponses, SaveRecipeData, SaveRecipeErrors, SaveRecipeResponses, ScanRecipeData, ScanRecipeResponses, SessionsHandlerData, SessionsHandlerErrors, SessionsHandlerResponses, StartAgentData, StartAgentErrors, StartAgentResponses, StartOpenrouterSetupData, StartOpenrouterSetupResponses, StartTetrateSetupData, StartTetrateSetupResponses, StatusData, StatusResponses, UnpauseScheduleData, UnpauseScheduleErrors, UnpauseScheduleResponses, UpdateAgentProviderData, UpdateAgentProviderErrors, UpdateAgentProviderResponses, UpdateCustomProviderData, UpdateCustomProviderErrors, UpdateCustomProviderResponses, UpdateFromSessionData, UpdateFromSessionErrors, UpdateFromSessionResponses, UpdateRouterToolSelectorData, UpdateRouterToolSelectorErrors, UpdateRouterToolSelectorResponses, UpdateScheduleData, UpdateScheduleErrors, UpdateScheduleResponses, UpdateSessionDescriptionData, UpdateSessionDescriptionErrors, UpdateSessionDescriptionResponses, UpdateSessionUserRecipeValuesData, UpdateSessionUserRecipeValuesErrors, UpdateSessionUserRecipeValuesResponses, UpsertConfigData, UpsertConfigErrors, UpsertConfigResponses, UpsertPermissionsData, UpsertPermissionsErrors, UpsertPermissionsResponses, ValidateConfigData, ValidateConfigErrors, ValidateConfigResponses } from './types.gen';
|
||||
import type { AddExtensionData, AddExtensionErrors, AddExtensionResponses, BackupConfigData, BackupConfigErrors, BackupConfigResponses, ConfirmPermissionData, ConfirmPermissionErrors, ConfirmPermissionResponses, CreateCustomProviderData, CreateCustomProviderErrors, CreateCustomProviderResponses, CreateRecipeData, CreateRecipeErrors, CreateRecipeResponses, CreateScheduleData, CreateScheduleErrors, CreateScheduleResponses, DecodeRecipeData, DecodeRecipeErrors, DecodeRecipeResponses, DeleteRecipeData, DeleteRecipeErrors, DeleteRecipeResponses, DeleteScheduleData, DeleteScheduleErrors, DeleteScheduleResponses, DeleteSessionData, DeleteSessionErrors, DeleteSessionResponses, DiagnosticsData, DiagnosticsErrors, DiagnosticsResponses, EncodeRecipeData, EncodeRecipeErrors, EncodeRecipeResponses, ExportSessionData, ExportSessionErrors, ExportSessionResponses, GetCustomProviderData, GetCustomProviderErrors, GetCustomProviderResponses, GetExtensionsData, GetExtensionsErrors, GetExtensionsResponses, GetProviderModelsData, GetProviderModelsErrors, GetProviderModelsResponses, GetSessionData, GetSessionErrors, GetSessionInsightsData, GetSessionInsightsErrors, GetSessionInsightsResponses, GetSessionResponses, GetToolsData, GetToolsErrors, GetToolsResponses, ImportSessionData, ImportSessionErrors, ImportSessionResponses, InitConfigData, InitConfigErrors, InitConfigResponses, InspectRunningJobData, InspectRunningJobErrors, InspectRunningJobResponses, KillRunningJobData, KillRunningJobResponses, ListRecipesData, ListRecipesErrors, ListRecipesResponses, ListSchedulesData, ListSchedulesErrors, ListSchedulesResponses, ListSessionsData, ListSessionsErrors, ListSessionsResponses, ManageContextData, ManageContextErrors, ManageContextResponses, ParseRecipeData, ParseRecipeErrors, ParseRecipeResponses, PauseScheduleData, PauseScheduleErrors, PauseScheduleResponses, ProvidersData, ProvidersResponses, ReadAllConfigData, ReadAllConfigResponses, ReadConfigData, ReadConfigErrors, ReadConfigResponses, RecoverConfigData, RecoverConfigErrors, RecoverConfigResponses, RemoveConfigData, RemoveConfigErrors, RemoveConfigResponses, RemoveCustomProviderData, RemoveCustomProviderErrors, RemoveCustomProviderResponses, RemoveExtensionData, RemoveExtensionErrors, RemoveExtensionResponses, ReplyData, ReplyErrors, ReplyResponses, ResumeAgentData, ResumeAgentErrors, ResumeAgentResponses, RunNowHandlerData, RunNowHandlerErrors, RunNowHandlerResponses, SaveRecipeData, SaveRecipeErrors, SaveRecipeResponses, ScanRecipeData, ScanRecipeResponses, SessionsHandlerData, SessionsHandlerErrors, SessionsHandlerResponses, StartAgentData, StartAgentErrors, StartAgentResponses, StartOpenrouterSetupData, StartOpenrouterSetupResponses, StartTetrateSetupData, StartTetrateSetupResponses, StatusData, StatusResponses, UnpauseScheduleData, UnpauseScheduleErrors, UnpauseScheduleResponses, UpdateAgentProviderData, UpdateAgentProviderErrors, UpdateAgentProviderResponses, UpdateCustomProviderData, UpdateCustomProviderErrors, UpdateCustomProviderResponses, UpdateFromSessionData, UpdateFromSessionErrors, UpdateFromSessionResponses, UpdateRouterToolSelectorData, UpdateRouterToolSelectorErrors, UpdateRouterToolSelectorResponses, UpdateScheduleData, UpdateScheduleErrors, UpdateScheduleResponses, UpdateSessionDescriptionData, UpdateSessionDescriptionErrors, UpdateSessionDescriptionResponses, UpdateSessionUserRecipeValuesData, UpdateSessionUserRecipeValuesErrors, UpdateSessionUserRecipeValuesResponses, UpsertConfigData, UpsertConfigErrors, UpsertConfigResponses, UpsertPermissionsData, UpsertPermissionsErrors, UpsertPermissionsResponses, ValidateConfigData, ValidateConfigErrors, ValidateConfigResponses } from './types.gen';
|
||||
|
||||
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = Options2<TData, ThrowOnError> & {
|
||||
/**
|
||||
@@ -256,6 +256,13 @@ export const manageContext = <ThrowOnError extends boolean = false>(options: Opt
|
||||
});
|
||||
};
|
||||
|
||||
export const diagnostics = <ThrowOnError extends boolean = false>(options: Options<DiagnosticsData, ThrowOnError>) => {
|
||||
return (options.client ?? client).get<DiagnosticsResponses, DiagnosticsErrors, ThrowOnError>({
|
||||
url: '/diagnostics/{session_id}',
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
export const startOpenrouterSetup = <ThrowOnError extends boolean = false>(options?: Options<StartOpenrouterSetupData, ThrowOnError>) => {
|
||||
return (options?.client ?? client).post<StartOpenrouterSetupResponses, unknown, ThrowOnError>({
|
||||
url: '/handle_openrouter',
|
||||
|
||||
@@ -1594,6 +1594,31 @@ export type ManageContextResponses = {
|
||||
|
||||
export type ManageContextResponse = ManageContextResponses[keyof ManageContextResponses];
|
||||
|
||||
export type DiagnosticsData = {
|
||||
body?: never;
|
||||
path: {
|
||||
session_id: string;
|
||||
};
|
||||
query?: never;
|
||||
url: '/diagnostics/{session_id}';
|
||||
};
|
||||
|
||||
export type DiagnosticsErrors = {
|
||||
/**
|
||||
* Failed to generate diagnostics
|
||||
*/
|
||||
500: unknown;
|
||||
};
|
||||
|
||||
export type DiagnosticsResponses = {
|
||||
/**
|
||||
* Diagnostics zip file
|
||||
*/
|
||||
200: Blob | File;
|
||||
};
|
||||
|
||||
export type DiagnosticsResponse = DiagnosticsResponses[keyof DiagnosticsResponses];
|
||||
|
||||
export type StartOpenrouterSetupData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useRef, useState, useEffect, useMemo, useCallback } from 'react';
|
||||
import { FolderKey, ScrollText } from 'lucide-react';
|
||||
import { Bug, FolderKey, ScrollText } from 'lucide-react';
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from './ui/Tooltip';
|
||||
import { Button } from './ui/button';
|
||||
import type { View } from '../utils/navigationUtils';
|
||||
@@ -8,7 +8,6 @@ import { Attach, Send, Close, Microphone } from './icons';
|
||||
import { ChatState } from '../types/chatState';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { LocalMessageStorage } from '../utils/localMessageStorage';
|
||||
import { Message } from '../api';
|
||||
import { DirSwitcher } from './bottom_menu/DirSwitcher';
|
||||
import ModelsBottomBar from './settings/models/bottom_bar/ModelsBottomBar';
|
||||
import { BottomMenuModeSelection } from './bottom_menu/BottomMenuModeSelection';
|
||||
@@ -28,6 +27,8 @@ import { DroppedFile, useFileDrop } from '../hooks/useFileDrop';
|
||||
import { Recipe } from '../recipe';
|
||||
import MessageQueue from './MessageQueue';
|
||||
import { detectInterruption } from '../utils/interruptionDetector';
|
||||
import { DiagnosticsModal } from './ui/DownloadDiagnostics';
|
||||
import { Message } from '../api';
|
||||
|
||||
interface QueuedMessage {
|
||||
id: string;
|
||||
@@ -149,6 +150,8 @@ export default function ChatInput({
|
||||
const agentIsReady = chatContext === null || chatContext.agentWaitingMessage === null;
|
||||
const draftLoadedRef = useRef(false);
|
||||
|
||||
const [diagnosticsOpen, setDiagnosticsOpen] = useState(false);
|
||||
|
||||
// Debug logging for draft context
|
||||
useEffect(() => {
|
||||
// Debug logging removed - draft functionality is working correctly
|
||||
@@ -1548,7 +1551,6 @@ export default function ChatInput({
|
||||
<DirSwitcher className="mr-0" />
|
||||
<div className="w-px h-4 bg-border-default mx-2" />
|
||||
|
||||
{/* Attach button */}
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
@@ -1563,6 +1565,7 @@ export default function ChatInput({
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Attach file or directory</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<div className="w-px h-4 bg-border-default mx-2" />
|
||||
|
||||
{/* Model selector, mode selector, alerts, summarize button */}
|
||||
@@ -1610,8 +1613,32 @@ export default function ChatInput({
|
||||
<TooltipContent>Configure goosehints</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
{sessionId && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => setDiagnosticsOpen(true)}
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="flex items-center justify-center text-text-default/70 hover:text-text-default text-xs cursor-pointer transition-colors"
|
||||
>
|
||||
<Bug className="w-4 h-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Generate diagnostics bundle</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{sessionId && diagnosticsOpen && (
|
||||
<DiagnosticsModal
|
||||
isOpen={diagnosticsOpen}
|
||||
onClose={() => setDiagnosticsOpen(false)}
|
||||
sessionId={sessionId}
|
||||
/>
|
||||
)}
|
||||
|
||||
<MentionPopover
|
||||
ref={mentionPopoverRef}
|
||||
isOpen={mentionPopover.isOpen}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
import React, { useState } from 'react';
|
||||
import { AlertTriangle } from 'lucide-react';
|
||||
import { Button } from './button';
|
||||
import { toastError } from '../../toasts';
|
||||
import { diagnostics } from '../../api';
|
||||
|
||||
interface DiagnosticsModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
sessionId: string;
|
||||
}
|
||||
|
||||
export const DiagnosticsModal: React.FC<DiagnosticsModalProps> = ({
|
||||
isOpen,
|
||||
onClose,
|
||||
sessionId,
|
||||
}) => {
|
||||
const [isDownloading, setIsDownloading] = useState(false);
|
||||
|
||||
const handleDownload = async () => {
|
||||
setIsDownloading(true);
|
||||
|
||||
try {
|
||||
const response = await diagnostics({
|
||||
path: { session_id: sessionId },
|
||||
throwOnError: true,
|
||||
});
|
||||
|
||||
const blob = new Blob([response.data], { type: 'application/zip' });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `diagnostics_${sessionId}.zip`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
|
||||
onClose();
|
||||
} catch {
|
||||
toastError({
|
||||
title: 'Diagnostics Error',
|
||||
msg: 'Failed to download diagnostics',
|
||||
});
|
||||
} finally {
|
||||
setIsDownloading(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||||
<div className="bg-background-default border border-borderStandard rounded-lg p-6 max-w-md mx-4">
|
||||
<div className="flex items-start gap-3 mb-4">
|
||||
<AlertTriangle className="text-orange-500 flex-shrink-0 mt-1" size={20} />
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-textStandard mb-2">Download Diagnostics</h3>
|
||||
<p className="text-sm text-textSubtle mb-3">
|
||||
Hit the download button to get a zip file containing all the important information to
|
||||
diagnose a problem in goose. You can share this file with the team or if you are a
|
||||
developer look at it yourself.
|
||||
</p>
|
||||
<ul className="text-sm text-textSubtle list-disc list-inside space-y-1 mb-3">
|
||||
<li>Basic system info</li>
|
||||
<li>Your current session messages</li>
|
||||
<li>Recent log files</li>
|
||||
<li>Configuration settings</li>
|
||||
</ul>
|
||||
<p className="text-sm text-textSubtle">
|
||||
<strong>Warning:</strong> If your session contains sensitive information, do not share
|
||||
this file publicly.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2 justify-end">
|
||||
<Button onClick={onClose} variant="outline" size="sm" disabled={isDownloading}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleDownload}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
disabled={isDownloading}
|
||||
className="bg-slate-600 text-white hover:bg-slate-700"
|
||||
>
|
||||
{isDownloading ? 'Downloading...' : 'Download'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user