research-agent-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +177 -0
- package/dist/api/handlers/agents.d.ts +4 -0
- package/dist/api/handlers/article-followups.d.ts +2 -0
- package/dist/api/handlers/article-qa.d.ts +2 -0
- package/dist/api/handlers/autocomplete.d.ts +8 -0
- package/dist/api/handlers/chats.d.ts +23 -0
- package/dist/api/handlers/mcpservers.d.ts +24 -0
- package/dist/api/handlers/messages.d.ts +4 -0
- package/dist/api/handlers/providers.d.ts +29 -0
- package/dist/api/handlers/rewrite.d.ts +4 -0
- package/dist/api/handlers/search.d.ts +7 -0
- package/dist/api/handlers/suggestions.d.ts +3 -0
- package/dist/api/handlers/test-models.d.ts +3 -0
- package/dist/api/handlers/transcript.d.ts +4 -0
- package/dist/api/handlers/validate-openrouter.d.ts +5 -0
- package/dist/api/handlers/voice.d.ts +4 -0
- package/dist/api/index.d.ts +16 -0
- package/dist/api/types.d.ts +86 -0
- package/dist/api.cjs +22 -0
- package/dist/api.mjs +768 -0
- package/dist/components/ArticleReader/ArticleAIResponse.d.ts +11 -0
- package/dist/components/ArticleReader/ArticleActionButtons.d.ts +18 -0
- package/dist/components/ArticleReader/ArticleContent.d.ts +8 -0
- package/dist/components/ArticleReader/ArticleExtractPanel.d.ts +4 -0
- package/dist/components/ArticleReader/ArticleFollowupQuestions.d.ts +12 -0
- package/dist/components/ArticleReader/ArticlePanelHeader.d.ts +9 -0
- package/dist/components/ArticleReader/ArticlePromptInput.d.ts +11 -0
- package/dist/components/ArticleReader/ExtractPanelContext.d.ts +18 -0
- package/dist/components/ArticleReader/LexicalArticleViewer.d.ts +15 -0
- package/dist/components/ArticleReader/index.d.ts +12 -0
- package/dist/components/ArticleReader/unified-markdown.d.ts +19 -0
- package/dist/components/ChatConversation/ChatConversationThread.d.ts +10 -0
- package/dist/components/ChatConversation/ChatHeaderNavigationBar.d.ts +2 -0
- package/dist/components/ChatConversation/ChatHomepage.d.ts +6 -0
- package/dist/components/ChatConversation/ChatMessageBubble.d.ts +19 -0
- package/dist/components/ChatConversation/ChatMessageInputBar.d.ts +10 -0
- package/dist/components/ChatConversation/ChatWindow.d.ts +75 -0
- package/dist/components/ChatConversation/EmptyStateChatMessageInput.d.ts +9 -0
- package/dist/components/ChatConversation/MessageBubble/AssistantMessageActions.d.ts +15 -0
- package/dist/components/ChatConversation/MessageBubble/FollowUpSuggestions.d.ts +15 -0
- package/dist/components/ChatConversation/MessageBubble/ThinkTagProcessor.d.ts +13 -0
- package/dist/components/ChatConversation/MessageBubble/UserMessageHeader.d.ts +20 -0
- package/dist/components/ChatConversation/MessageReasoningPanel.d.ts +14 -0
- package/dist/components/ChatConversation/RecentHistoryChips.d.ts +1 -0
- package/dist/components/ChatConversation/SearchModeSpotlightPanel.d.ts +10 -0
- package/dist/components/ChatConversation/background-art.d.ts +11 -0
- package/dist/components/ChatHistoryDropdown/HistoryChatItem.d.ts +9 -0
- package/dist/components/ChatHistoryDropdown/HistoryDialogs.d.ts +14 -0
- package/dist/components/ChatHistoryDropdown/HistoryDropdown.d.ts +6 -0
- package/dist/components/ChatHistoryDropdown/HistoryHeader.d.ts +10 -0
- package/dist/components/ChatHistoryDropdown/index.d.ts +4 -0
- package/dist/components/ChatHistoryDropdown/useHistoryState.d.ts +27 -0
- package/dist/components/ConfigError.d.ts +1 -0
- package/dist/components/FileUpload/CompactFileAttachmentButton.d.ts +2 -0
- package/dist/components/FileUpload/FileAttachmentButton.d.ts +2 -0
- package/dist/components/FileUpload/FilePreviewCard.d.ts +13 -0
- package/dist/components/FileUpload/FileUploadDropdown.d.ts +7 -0
- package/dist/components/FileUpload/GoogleDrivePicker.d.ts +4 -0
- package/dist/components/FileUpload/useFileHandling.d.ts +26 -0
- package/dist/components/Footer.d.ts +19 -0
- package/dist/components/MessageActions/CopyMessageButton.d.ts +6 -0
- package/dist/components/MessageActions/DeleteChatSessionButton.d.ts +8 -0
- package/dist/components/MessageActions/RewriteMessageButton.d.ts +5 -0
- package/dist/components/MessageComposer/ActionBar.d.ts +17 -0
- package/dist/components/MessageComposer/ChatInputBox.d.ts +6 -0
- package/dist/components/MessageComposer/MessageInputIconSet.d.ts +24 -0
- package/dist/components/MessageComposer/PastedContentCard.d.ts +12 -0
- package/dist/components/SearchConfig/CategoriesMenu.d.ts +2 -0
- package/dist/components/SearchConfig/ChatModelSelector.d.ts +2 -0
- package/dist/components/SearchConfig/ModelSelector.d.ts +8 -0
- package/dist/components/SearchConfig/ModelSelectorSubmenu.d.ts +2 -0
- package/dist/components/SearchConfig/ResearchFocusToggleButton.d.ts +2 -0
- package/dist/components/SearchConfig/SearchOptimizationSelector.d.ts +2 -0
- package/dist/components/SearchConfig/categories.d.ts +10 -0
- package/dist/components/SearchResults/MessageSources.d.ts +11 -0
- package/dist/components/SearchResults/NewsArticleWidget.d.ts +2 -0
- package/dist/components/SearchResults/SearchProgressIndicator.d.ts +8 -0
- package/dist/components/SearchResults/WebCitationBadge.d.ts +7 -0
- package/dist/config.cjs +1 -0
- package/dist/config.d.ts +54 -0
- package/dist/config.mjs +16 -0
- package/dist/hooks/useChat/ChatContext.d.ts +147 -0
- package/dist/hooks/useChat/ChatProvider.d.ts +35 -0
- package/dist/hooks/useChat/buildSections.d.ts +39 -0
- package/dist/hooks/useChat/chatConfig.d.ts +31 -0
- package/dist/hooks/useChat/chatMessages.d.ts +48 -0
- package/dist/hooks/useChat/index.d.ts +58 -0
- package/dist/hooks/useChat/sendMessage.d.ts +91 -0
- package/dist/hooks/useChat/useChat.d.ts +3 -0
- package/dist/hooks/useChat/useChatState.d.ts +127 -0
- package/dist/hooks/useSession.d.ts +21 -0
- package/dist/hooks/voice/useInteruptionDetection.d.ts +16 -0
- package/dist/hooks/voice/useSpeechToTranscript.d.ts +5 -0
- package/dist/hooks/voice/useTextToVoice.d.ts +13 -0
- package/dist/icons/IconSearchAcademic.d.ts +1 -0
- package/dist/icons/IconSearchFiles.d.ts +1 -0
- package/dist/icons/IconSearchImages.d.ts +1 -0
- package/dist/icons/IconSearchNews.d.ts +1 -0
- package/dist/icons/IconSearchTech.d.ts +1 -0
- package/dist/icons/IconSearchVideos.d.ts +1 -0
- package/dist/icons/IconSearchWeb.d.ts +1 -0
- package/dist/index.cjs +52 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.mjs +5847 -0
- package/dist/lib/cdn-loader.d.ts +2 -0
- package/dist/lib/export.d.ts +17 -0
- package/dist/lib/guest.d.ts +19 -0
- package/dist/lib/suggestions.d.ts +2 -0
- package/dist/lib/url-autolink.d.ts +21 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/rolldown-runtime-CMqjfN_6.cjs +1 -0
- package/dist/types/chat.d.ts +132 -0
- package/dist/types/research.d.ts +81 -0
- package/dist/ui/Loader.d.ts +2 -0
- package/dist/ui/badge.d.ts +9 -0
- package/dist/ui/button.d.ts +11 -0
- package/dist/ui/dialog.d.ts +15 -0
- package/dist/ui/dropdown-menu.d.ts +25 -0
- package/dist/ui/glowing-effect.d.ts +14 -0
- package/dist/ui/gradient-blur.d.ts +9 -0
- package/dist/ui/live-waveform.d.ts +23 -0
- package/dist/ui/popover.d.ts +9 -0
- package/dist/ui/tooltip.d.ts +7 -0
- package/dist/ui/visually-hidden.d.ts +2 -0
- package/package.json +96 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central `Icons` export map of Lucide icons and custom SVGs (Thinking clock, SelectArrow)
|
|
3
|
+
* used across MessageComposer and related components.
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
export declare const Icons: {
|
|
7
|
+
Plus: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
8
|
+
Paperclip: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
9
|
+
Cloud: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
10
|
+
Upload: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
11
|
+
File: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
12
|
+
SquarePen: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
13
|
+
Thinking: (props: React.SVGProps<SVGSVGElement>) => React.JSX.Element;
|
|
14
|
+
SelectArrow: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
15
|
+
ArrowUp: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
16
|
+
X: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
17
|
+
FileText: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
18
|
+
Loader2: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
19
|
+
Check: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
20
|
+
Archive: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
21
|
+
Mic: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
22
|
+
Stop: React.ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
|
|
23
|
+
Clock: (props: React.SVGProps<SVGSVGElement>) => React.JSX.Element;
|
|
24
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small card shown in the attachment tray when a large block of text (>300 chars) is pasted into the input;
|
|
3
|
+
* displays a truncated preview with a "PASTED" label and a hover-revealed remove button.
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
import { PastedContent } from "../../types/research";
|
|
7
|
+
interface PastedContentCardProps {
|
|
8
|
+
content: PastedContent;
|
|
9
|
+
onRemove: (id: string) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare const PastedContentCard: React.FC<PastedContentCardProps>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ChatModelProvider } from "../../types/chat";
|
|
3
|
+
interface ModelSelectorProps {
|
|
4
|
+
chatModelProvider?: ChatModelProvider;
|
|
5
|
+
onSelect?: (provider: ChatModelProvider) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const ModelSelector: React.FC<ModelSelectorProps>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static array of search category metadata (code, SVG icon, display name) shared across CategoriesMenu,
|
|
3
|
+
* FileUploadDropdown, and SearchSpotlight components.
|
|
4
|
+
*/
|
|
5
|
+
import IconSearchWeb from '../../icons/IconSearchWeb';
|
|
6
|
+
export declare const categories: {
|
|
7
|
+
code: string;
|
|
8
|
+
icon: typeof IconSearchWeb;
|
|
9
|
+
name: string;
|
|
10
|
+
}[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source card grid with category tabs (Web/News/Videos/Images/Academic/Files) that renders search results as
|
|
3
|
+
* image tiles, video thumbnails, or web-result cards; supports infinite scroll pagination and opens URLs in
|
|
4
|
+
* the article extract panel. Auto-opens the first source on desktop.
|
|
5
|
+
*/
|
|
6
|
+
import type { Document } from 'extract-webpage/search';
|
|
7
|
+
declare const MessageSources: ({ sources: initialSources, query, }: {
|
|
8
|
+
sources: Document[];
|
|
9
|
+
query?: string;
|
|
10
|
+
}) => import("react").JSX.Element;
|
|
11
|
+
export default MessageSources;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SearchQuery } from '../ChatConversation/ChatWindow';
|
|
2
|
+
interface SearchProgressIndicatorProps {
|
|
3
|
+
queries: SearchQuery[];
|
|
4
|
+
/** True while the parent section is still streaming */
|
|
5
|
+
loading: boolean;
|
|
6
|
+
}
|
|
7
|
+
export default function SearchProgressIndicator({ queries, loading }: SearchProgressIndicatorProps): import("react").JSX.Element;
|
|
8
|
+
export {};
|
package/dist/config.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={appName:`QwkSearch`,defaultSummarizePrompt:`Summarize in bullet points and bold topics`,maxArticleLength:1500,downloadChromeUrl:`https://chromewebstore.google.com/detail/tab-manager-ai/manhemnhmipdhdpabojcplebckhckeko`,downloadWindowsStoreId:`9PCGF9GNK460`,footerLinks:[],googleApiKey:``,getAutoMediaSearch:()=>!0};function t(t){Object.assign(e,t)}exports.configureResearchAgentUI=t,exports.researchAgentUIConfig=e;
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export interface FooterLink {
|
|
2
|
+
url: string;
|
|
3
|
+
text: string;
|
|
4
|
+
icon?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Auth client shape expected by `SessionProvider`. Matches the subset of the
|
|
8
|
+
* better-auth React client actually used by this package, so the consuming
|
|
9
|
+
* app can pass its own configured instance without this package depending on
|
|
10
|
+
* `better-auth` directly.
|
|
11
|
+
*/
|
|
12
|
+
export interface ResearchAgentAuthClient {
|
|
13
|
+
getSession: (...args: any[]) => Promise<any>;
|
|
14
|
+
oneTap: (opts: {
|
|
15
|
+
fetchOptions: {
|
|
16
|
+
onSuccess: () => void;
|
|
17
|
+
};
|
|
18
|
+
}) => void;
|
|
19
|
+
signIn: {
|
|
20
|
+
social: (opts: {
|
|
21
|
+
provider: string;
|
|
22
|
+
callbackURL: string;
|
|
23
|
+
}) => void;
|
|
24
|
+
};
|
|
25
|
+
signOut: (opts: {
|
|
26
|
+
fetchOptions: {
|
|
27
|
+
onSuccess: () => void;
|
|
28
|
+
};
|
|
29
|
+
}) => Promise<any>;
|
|
30
|
+
}
|
|
31
|
+
export interface ResearchAgentUIConfig {
|
|
32
|
+
/** Product name shown in document titles, etc. */
|
|
33
|
+
appName: string;
|
|
34
|
+
/** Default prompt used to summarize an extracted article. */
|
|
35
|
+
defaultSummarizePrompt: string;
|
|
36
|
+
/** Max character length for article body sent to the LLM. */
|
|
37
|
+
maxArticleLength: number;
|
|
38
|
+
/** Chrome Web Store URL advertised on the homepage. */
|
|
39
|
+
downloadChromeUrl: string;
|
|
40
|
+
/** Microsoft Store product ID advertised on the homepage. */
|
|
41
|
+
downloadWindowsStoreId: string;
|
|
42
|
+
/** Links rendered in the homepage footer. */
|
|
43
|
+
footerLinks: FooterLink[];
|
|
44
|
+
/** Google API key used by the Google Drive file picker. */
|
|
45
|
+
googleApiKey: string;
|
|
46
|
+
/** Whether to auto-trigger image/video media search after a response completes. */
|
|
47
|
+
getAutoMediaSearch: () => boolean;
|
|
48
|
+
}
|
|
49
|
+
export declare const researchAgentUIConfig: ResearchAgentUIConfig;
|
|
50
|
+
/**
|
|
51
|
+
* Overrides default configuration. Call once, before rendering, from the
|
|
52
|
+
* consuming app (e.g. in the root layout) to wire up app-specific values.
|
|
53
|
+
*/
|
|
54
|
+
export declare function configureResearchAgentUI(overrides: Partial<ResearchAgentUIConfig>): void;
|
package/dist/config.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/config.ts
|
|
2
|
+
var e = {
|
|
3
|
+
appName: "QwkSearch",
|
|
4
|
+
defaultSummarizePrompt: "Summarize in bullet points and bold topics",
|
|
5
|
+
maxArticleLength: 1500,
|
|
6
|
+
downloadChromeUrl: "https://chromewebstore.google.com/detail/tab-manager-ai/manhemnhmipdhdpabojcplebckhckeko",
|
|
7
|
+
downloadWindowsStoreId: "9PCGF9GNK460",
|
|
8
|
+
footerLinks: [],
|
|
9
|
+
googleApiKey: "",
|
|
10
|
+
getAutoMediaSearch: () => !0
|
|
11
|
+
};
|
|
12
|
+
function t(t) {
|
|
13
|
+
Object.assign(e, t);
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { t as configureResearchAgentUI, e as researchAgentUIConfig };
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview React Context for the chat system.
|
|
3
|
+
* Provides the ChatContext and useChat hook for accessing chat state
|
|
4
|
+
* and actions throughout the application.
|
|
5
|
+
* @module components/ResearchAgent/state/chat/ChatContext
|
|
6
|
+
*/
|
|
7
|
+
import { ChatTurn, Message } from '../../components/ChatConversation/ChatWindow';
|
|
8
|
+
import { ChatFile, ChatModelProvider, Section } from '../../types/chat';
|
|
9
|
+
/**
|
|
10
|
+
* The value provided by the ChatContext.
|
|
11
|
+
* Contains all state and actions available to chat consumers.
|
|
12
|
+
*/
|
|
13
|
+
export interface ChatContextValue {
|
|
14
|
+
/** All messages in the current chat (user, assistant, source, suggestion) */
|
|
15
|
+
messages: Message[];
|
|
16
|
+
/** Filtered list of only user and assistant messages */
|
|
17
|
+
chatTurns: ChatTurn[];
|
|
18
|
+
/** Processed sections for UI rendering with citations and formatting */
|
|
19
|
+
sections: Section[];
|
|
20
|
+
/** Conversation history as [role, content] pairs for AI context */
|
|
21
|
+
chatHistory: [string, string][];
|
|
22
|
+
/** Files attached to the chat */
|
|
23
|
+
files: ChatFile[];
|
|
24
|
+
/** IDs of attached files for API requests */
|
|
25
|
+
fileIds: string[];
|
|
26
|
+
/** Current search/focus mode (e.g., 'webSearch', 'academic') */
|
|
27
|
+
focusMode: string;
|
|
28
|
+
/** Current category for filtering search results */
|
|
29
|
+
category: string;
|
|
30
|
+
/** Unique identifier for the current chat session */
|
|
31
|
+
chatId: string | undefined;
|
|
32
|
+
/** Response optimization mode (e.g., 'speed', 'quality') */
|
|
33
|
+
optimizationMode: string;
|
|
34
|
+
/** Whether messages have been loaded from storage/API */
|
|
35
|
+
isMessagesLoaded: boolean;
|
|
36
|
+
/** Whether a message is currently being sent/processed */
|
|
37
|
+
loading: boolean;
|
|
38
|
+
/** Whether the requested chat was not found */
|
|
39
|
+
notFound: boolean;
|
|
40
|
+
/** Whether the AI response has started appearing */
|
|
41
|
+
messageAppeared: boolean;
|
|
42
|
+
/** Whether the chat system is fully initialized and ready */
|
|
43
|
+
isReady: boolean;
|
|
44
|
+
/** Whether an error occurred during initialization */
|
|
45
|
+
hasError: boolean;
|
|
46
|
+
/** Current AI model provider configuration */
|
|
47
|
+
chatModelProvider: ChatModelProvider;
|
|
48
|
+
/**
|
|
49
|
+
* Sets the response optimization mode.
|
|
50
|
+
* @param mode - The optimization mode ('speed' or 'quality')
|
|
51
|
+
*/
|
|
52
|
+
setOptimizationMode: (mode: string) => void;
|
|
53
|
+
/**
|
|
54
|
+
* Sets the search/focus mode.
|
|
55
|
+
* @param mode - The focus mode (e.g., 'webSearch', 'academic')
|
|
56
|
+
*/
|
|
57
|
+
setFocusMode: (mode: string) => void;
|
|
58
|
+
/**
|
|
59
|
+
* Sets the search category.
|
|
60
|
+
* @param category - The category for filtering results
|
|
61
|
+
*/
|
|
62
|
+
setCategory: (category: string) => void;
|
|
63
|
+
/**
|
|
64
|
+
* Sets the files attached to the chat.
|
|
65
|
+
* @param files - Array of ChatFile objects
|
|
66
|
+
*/
|
|
67
|
+
setFiles: (files: ChatFile[]) => void;
|
|
68
|
+
/**
|
|
69
|
+
* Sets the file IDs for attached files.
|
|
70
|
+
* @param fileIds - Array of file ID strings
|
|
71
|
+
*/
|
|
72
|
+
setFileIds: (fileIds: string[]) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Sends a message to the chat.
|
|
75
|
+
* @param message - The message content to send
|
|
76
|
+
* @param messageId - Optional custom message ID
|
|
77
|
+
* @param rewrite - Whether this is a rewrite of a previous message
|
|
78
|
+
*/
|
|
79
|
+
sendMessage: (message: string, messageId?: string, rewrite?: boolean) => Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Rewrites a previous AI response.
|
|
82
|
+
* Removes messages after the specified one and regenerates the response.
|
|
83
|
+
* @param messageId - The ID of the assistant message to rewrite
|
|
84
|
+
*/
|
|
85
|
+
rewrite: (messageId: string) => void;
|
|
86
|
+
/**
|
|
87
|
+
* Updates the AI model provider configuration.
|
|
88
|
+
* @param provider - The new provider configuration
|
|
89
|
+
*/
|
|
90
|
+
setChatModelProvider: (provider: ChatModelProvider) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Stops the currently streaming response.
|
|
93
|
+
* Aborts the fetch request and finalizes with whatever content was received.
|
|
94
|
+
*/
|
|
95
|
+
stopStreaming: () => void;
|
|
96
|
+
/**
|
|
97
|
+
* Clears the current chat and starts a new session.
|
|
98
|
+
* Resets all messages, history, and generates a new chat ID.
|
|
99
|
+
*/
|
|
100
|
+
newChat: () => void;
|
|
101
|
+
/**
|
|
102
|
+
* Whether incognito mode is active.
|
|
103
|
+
* When true, messages are not saved to history or cloud.
|
|
104
|
+
*/
|
|
105
|
+
incognito: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Toggles incognito mode on or off.
|
|
108
|
+
*/
|
|
109
|
+
setIncognito: (value: boolean) => void;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* React Context for the chat system.
|
|
113
|
+
*
|
|
114
|
+
* Provides access to chat state and actions throughout the component tree.
|
|
115
|
+
* Should be used with the ChatProvider component at the app root.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```tsx
|
|
119
|
+
* // In a component
|
|
120
|
+
* const { messages, sendMessage, loading } = useChat();
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare const chatContext: import("react").Context<ChatContextValue>;
|
|
124
|
+
/**
|
|
125
|
+
* Hook for accessing the chat context.
|
|
126
|
+
*
|
|
127
|
+
* Provides access to all chat state and actions.
|
|
128
|
+
* Must be used within a ChatProvider component.
|
|
129
|
+
*
|
|
130
|
+
* @returns The current ChatContextValue
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```tsx
|
|
134
|
+
* function ChatInput() {
|
|
135
|
+
* const { sendMessage, loading } = useChat();
|
|
136
|
+
*
|
|
137
|
+
* const handleSubmit = (message: string) => {
|
|
138
|
+
* if (!loading) {
|
|
139
|
+
* sendMessage(message);
|
|
140
|
+
* }
|
|
141
|
+
* };
|
|
142
|
+
*
|
|
143
|
+
* return <input disabled={loading} onSubmit={handleSubmit} />;
|
|
144
|
+
* }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export declare function useChat(): ChatContextValue;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview React Provider component for the chat system.
|
|
3
|
+
* Orchestrates all chat functionality including state management,
|
|
4
|
+
* message loading, sending, and persistence.
|
|
5
|
+
* @module components/ResearchAgent/state/chat/ChatProvider
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Provider component that manages the chat system state and side effects.
|
|
9
|
+
*
|
|
10
|
+
* This component:
|
|
11
|
+
* - Initializes chat configuration (model provider selection)
|
|
12
|
+
* - Loads existing messages for a chat ID from URL params
|
|
13
|
+
* - Creates new chat sessions when needed
|
|
14
|
+
* - Persists guest chats to localStorage
|
|
15
|
+
* - Handles initial messages from URL query params
|
|
16
|
+
* - Provides the chat context to child components
|
|
17
|
+
*
|
|
18
|
+
* @param props - Component props
|
|
19
|
+
* @param props.children - Child components that will have access to chat context
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* // In app layout
|
|
24
|
+
* export default function RootLayout({ children }) {
|
|
25
|
+
* return (
|
|
26
|
+
* <ChatProvider>
|
|
27
|
+
* {children}
|
|
28
|
+
* </ChatProvider>
|
|
29
|
+
* );
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function ChatProvider({ children }: {
|
|
34
|
+
children: React.ReactNode;
|
|
35
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Message parsing and section building for the chat UI.
|
|
3
|
+
* Transforms raw message arrays into structured sections that group
|
|
4
|
+
* user messages with their corresponding AI responses, sources, and suggestions.
|
|
5
|
+
* @module components/ResearchAgent/state/chat/buildSections
|
|
6
|
+
*/
|
|
7
|
+
import { Message } from "../../components/ChatConversation/ChatWindow";
|
|
8
|
+
import { Section } from "../../types/chat";
|
|
9
|
+
/**
|
|
10
|
+
* Transforms a flat array of messages into structured UI sections.
|
|
11
|
+
*
|
|
12
|
+
* Each section groups together:
|
|
13
|
+
* - A user message
|
|
14
|
+
* - The corresponding AI assistant response
|
|
15
|
+
* - Source citations used for the response
|
|
16
|
+
* - Follow-up suggestions
|
|
17
|
+
*
|
|
18
|
+
* The function also performs message processing:
|
|
19
|
+
* - Converts citation markers `[1]`, `[2,3]` into clickable `<citation>` elements
|
|
20
|
+
* - Handles thinking/reasoning tags (`<think>...</think>`)
|
|
21
|
+
* - Creates a speech-friendly version with citations removed
|
|
22
|
+
*
|
|
23
|
+
* @param messages - Array of all chat messages (user, assistant, source, suggestion)
|
|
24
|
+
* @returns Array of Section objects for rendering in the UI
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const sections = buildSections(messages);
|
|
29
|
+
*
|
|
30
|
+
* // userMessage: { role: 'user', content: 'What is React?' },
|
|
31
|
+
* // assistantMessage: { role: 'assistant', content: 'React is...' },
|
|
32
|
+
* // parsedAssistantMessage: 'React is... <citation href="...">1</citation>',
|
|
33
|
+
* // speechMessage: 'React is...',
|
|
34
|
+
* // sourceMessage: { sources: [...] },
|
|
35
|
+
* // thinkingEnded: true,
|
|
36
|
+
* // suggestions: ['How does React compare to Vue?', ...]
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare const buildSections: (messages: Message[]) => Section[];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Chat configuration and model provider initialization.
|
|
3
|
+
* Handles loading and selecting the appropriate AI model provider and model
|
|
4
|
+
* based on user preferences stored in localStorage or system defaults.
|
|
5
|
+
* @module components/ResearchAgent/state/chat/chatConfig
|
|
6
|
+
*/
|
|
7
|
+
import { ChatModelProvider } from "../../types/chat";
|
|
8
|
+
/**
|
|
9
|
+
* Initializes and validates the chat model configuration.
|
|
10
|
+
*
|
|
11
|
+
* This function performs the following steps:
|
|
12
|
+
* 1. Fetches available providers from the API
|
|
13
|
+
* 2. Loads user preferences from localStorage (if any)
|
|
14
|
+
* 3. Selects an appropriate provider (preferring OpenRouter)
|
|
15
|
+
* 4. Selects an appropriate model (preferring Nemotron 3 Super 120B)
|
|
16
|
+
* 5. Saves the selection to localStorage for future sessions
|
|
17
|
+
*
|
|
18
|
+
* @param setChatModelProvider - Callback to set the selected provider configuration
|
|
19
|
+
* @param setIsConfigReady - Callback to signal configuration completion
|
|
20
|
+
* @param setHasError - Callback to signal configuration errors
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* useEffect(() => {
|
|
25
|
+
* checkConfig(setChatModelProvider, setIsConfigReady, setHasError);
|
|
26
|
+
* }, []);
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @throws Will call setHasError(true) if no providers or models are available
|
|
30
|
+
*/
|
|
31
|
+
export declare const checkConfig: (setChatModelProvider: (provider: ChatModelProvider) => void, setIsConfigReady: (ready: boolean) => void, setHasError: (hasError: boolean) => void) => Promise<void>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Chat message loading functionality.
|
|
3
|
+
* Handles loading chat messages from localStorage (for guest chats),
|
|
4
|
+
* the API (for authenticated users), or the API for public shared chats (for unauthenticated users).
|
|
5
|
+
* @module components/ResearchAgent/state/chat/chatMessages
|
|
6
|
+
*/
|
|
7
|
+
import { Message } from "../../components/ChatConversation/ChatWindow";
|
|
8
|
+
import { ChatFile } from "../../types/chat";
|
|
9
|
+
/**
|
|
10
|
+
* Loads chat messages and metadata for an existing chat session.
|
|
11
|
+
*
|
|
12
|
+
* This function handles three scenarios:
|
|
13
|
+
* - **Guest users**: Loads messages from localStorage via `getGuestChat()`, then tries API for public shared chats if not found
|
|
14
|
+
* - **Public shared chats**: Unauthenticated users can view public chats via the API without sign-in
|
|
15
|
+
* - **Authenticated users**: Fetches messages from the `/api/chats/:id` endpoint
|
|
16
|
+
*
|
|
17
|
+
* After loading, it:
|
|
18
|
+
* - Sets the document title to the first message
|
|
19
|
+
* - Builds the chat history for context
|
|
20
|
+
* - Loads attached files and their IDs
|
|
21
|
+
* - Sets the focus mode from the saved chat
|
|
22
|
+
*
|
|
23
|
+
* @param chatId - The unique identifier of the chat to load
|
|
24
|
+
* @param isAuthenticated - Whether the current user is authenticated
|
|
25
|
+
* @param setMessages - Callback to set the loaded messages
|
|
26
|
+
* @param setIsMessagesLoaded - Callback to signal loading completion
|
|
27
|
+
* @param setChatHistory - Callback to set the conversation history
|
|
28
|
+
* @param setFocusMode - Callback to set the chat's focus mode
|
|
29
|
+
* @param setNotFound - Callback to signal if the chat doesn't exist
|
|
30
|
+
* @param setFiles - Callback to set the attached files
|
|
31
|
+
* @param setFileIds - Callback to set the file IDs
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* await loadMessages(
|
|
36
|
+
* chatId,
|
|
37
|
+
* isAuthenticated,
|
|
38
|
+
* setMessages,
|
|
39
|
+
* setIsMessagesLoaded,
|
|
40
|
+
* setChatHistory,
|
|
41
|
+
* setFocusMode,
|
|
42
|
+
* setNotFound,
|
|
43
|
+
* setFiles,
|
|
44
|
+
* setFileIds,
|
|
45
|
+
* );
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare const loadMessages: (chatId: string, isAuthenticated: boolean, setMessages: (messages: Message[]) => void, setIsMessagesLoaded: (loaded: boolean) => void, setChatHistory: (history: [string, string][]) => void, setFocusMode: (mode: string) => void, setNotFound: (notFound: boolean) => void, setFiles: (files: ChatFile[]) => void, setFileIds: (fileIds: string[]) => void) => Promise<void>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Chat system module exports.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a complete chat system implementation with:
|
|
5
|
+
* - **State management**: Centralized state via `useChatState` hook
|
|
6
|
+
* - **Context provider**: `ChatProvider` for React context
|
|
7
|
+
* - **Message handling**: Send, receive, and stream chat messages
|
|
8
|
+
* - **Persistence**: Guest chat storage in localStorage
|
|
9
|
+
* - **Configuration**: AI model provider selection and setup
|
|
10
|
+
*
|
|
11
|
+
* ## Architecture
|
|
12
|
+
*
|
|
13
|
+
* ```
|
|
14
|
+
* ChatProvider (orchestration)
|
|
15
|
+
* └── useChatState (state management)
|
|
16
|
+
* ├── checkConfig (model configuration)
|
|
17
|
+
* ├── loadMessages (message loading)
|
|
18
|
+
* ├── sendMessage (message sending)
|
|
19
|
+
* └── buildSections (UI processing)
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* ## Quick Start
|
|
23
|
+
*
|
|
24
|
+
* ```tsx
|
|
25
|
+
* // 1. Wrap your app with ChatProvider
|
|
26
|
+
* import { ChatProvider } from 'research-agent-ui';
|
|
27
|
+
*
|
|
28
|
+
* function App({ children }) {
|
|
29
|
+
* return <ChatProvider>{children}</ChatProvider>;
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* // 2. Use the chat hook in components
|
|
33
|
+
* import { useChat } from 'research-agent-ui';
|
|
34
|
+
*
|
|
35
|
+
* function ChatComponent() {
|
|
36
|
+
* const { messages, sendMessage, loading } = useChat();
|
|
37
|
+
*
|
|
38
|
+
* return (
|
|
39
|
+
* <div>
|
|
40
|
+
* {messages.map(msg => <Message key={msg.messageId} {...msg} />)}
|
|
41
|
+
* <Input onSubmit={sendMessage} disabled={loading} />
|
|
42
|
+
* </div>
|
|
43
|
+
* );
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @module components/ResearchAgent/state/chat
|
|
48
|
+
*/
|
|
49
|
+
export * from "../../types/chat";
|
|
50
|
+
export { checkConfig } from "./chatConfig";
|
|
51
|
+
export { loadMessages } from "./chatMessages";
|
|
52
|
+
export { buildSections } from "./buildSections";
|
|
53
|
+
export { sendMessage } from "./sendMessage";
|
|
54
|
+
export { useChatState } from "./useChatState";
|
|
55
|
+
export type { ChatState, ChatStateSetters, UseChatStateReturn, } from "./useChatState";
|
|
56
|
+
export { chatContext, useChat } from "./ChatContext";
|
|
57
|
+
export type { ChatContextValue } from "./ChatContext";
|
|
58
|
+
export { ChatProvider } from "./ChatProvider";
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Message sending and streaming response handling.
|
|
3
|
+
* Handles the complete flow of sending a chat message, receiving streamed
|
|
4
|
+
* responses, and updating the UI state accordingly.
|
|
5
|
+
* @module components/ResearchAgent/state/chat/sendMessage
|
|
6
|
+
*/
|
|
7
|
+
import { Message } from "../../components/ChatConversation/ChatWindow";
|
|
8
|
+
import { ChatModelProvider } from "../../types/chat";
|
|
9
|
+
/**
|
|
10
|
+
* Parameters for sending a chat message.
|
|
11
|
+
*/
|
|
12
|
+
export interface SendMessageParams {
|
|
13
|
+
/** The message content to send */
|
|
14
|
+
message: string;
|
|
15
|
+
/** Optional custom message ID (used when rewriting) */
|
|
16
|
+
messageId?: string;
|
|
17
|
+
/** Whether this is a rewrite of a previous response */
|
|
18
|
+
rewrite?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Dependencies required by the sendMessage function.
|
|
22
|
+
* These are passed from the ChatProvider to allow the function
|
|
23
|
+
* to access and modify chat state.
|
|
24
|
+
*/
|
|
25
|
+
export interface SendMessageDeps {
|
|
26
|
+
/** Current chat session ID */
|
|
27
|
+
chatId: string;
|
|
28
|
+
/** Whether a message is currently being sent */
|
|
29
|
+
loading: boolean;
|
|
30
|
+
/** Current messages in the chat */
|
|
31
|
+
messages: Message[];
|
|
32
|
+
/** IDs of files attached to the chat */
|
|
33
|
+
fileIds: string[];
|
|
34
|
+
/** Current search/focus mode */
|
|
35
|
+
focusMode: string;
|
|
36
|
+
/** Current category for search filtering */
|
|
37
|
+
category: string;
|
|
38
|
+
/** Response optimization mode */
|
|
39
|
+
optimizationMode: string;
|
|
40
|
+
/** Conversation history for context */
|
|
41
|
+
chatHistory: [string, string][];
|
|
42
|
+
/** AI model provider configuration */
|
|
43
|
+
chatModelProvider: ChatModelProvider;
|
|
44
|
+
/** Whether the user is authenticated */
|
|
45
|
+
isAuthenticated: boolean;
|
|
46
|
+
/** Ref to current messages (avoids stale closures) */
|
|
47
|
+
messagesRef: React.MutableRefObject<Message[]>;
|
|
48
|
+
/** Ref to the AbortController for cancelling the stream */
|
|
49
|
+
abortControllerRef: React.MutableRefObject<AbortController | null>;
|
|
50
|
+
/** Setter for loading state */
|
|
51
|
+
setLoading: (loading: boolean) => void;
|
|
52
|
+
/** Setter for message appeared state */
|
|
53
|
+
setMessageAppeared: (appeared: boolean) => void;
|
|
54
|
+
/** Setter for messages array */
|
|
55
|
+
setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
|
|
56
|
+
/** Setter for chat history */
|
|
57
|
+
setChatHistory: React.Dispatch<React.SetStateAction<[string, string][]>>;
|
|
58
|
+
/** Setter for the selected chat model provider (optional — used to reset on model errors) */
|
|
59
|
+
setChatModelProvider?: (provider: ChatModelProvider) => void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Sends a message to the chat API and handles the streaming response.
|
|
63
|
+
*
|
|
64
|
+
* This function:
|
|
65
|
+
* 1. Adds the user message to the chat immediately
|
|
66
|
+
* 2. Sends the request to `/api/chat`
|
|
67
|
+
* 3. Processes the streaming response (sources, message chunks, completion)
|
|
68
|
+
* 4. Updates the URL to include the chat ID
|
|
69
|
+
* 5. Triggers auto media search if enabled
|
|
70
|
+
* 6. Fetches follow-up suggestions after the response completes
|
|
71
|
+
*
|
|
72
|
+
* The streaming response is expected in newline-delimited JSON format with
|
|
73
|
+
* message types: 'sources', 'message', 'messageEnd', 'error'.
|
|
74
|
+
*
|
|
75
|
+
* @param params - The message parameters
|
|
76
|
+
* @param deps - State and setter dependencies from ChatProvider
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* await sendMessage(
|
|
81
|
+
* { message: 'What is TypeScript?', rewrite: false },
|
|
82
|
+
* {
|
|
83
|
+
* chatId: 'abc123',
|
|
84
|
+
* loading: false,
|
|
85
|
+
* messages: [],
|
|
86
|
+
* // ... other dependencies
|
|
87
|
+
* }
|
|
88
|
+
* );
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare function sendMessage(params: SendMessageParams, deps: SendMessageDeps): Promise<void>;
|