mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-03-10 18:22:40 +00:00
Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07f3b83f3d | ||
|
|
ad88d10388 | ||
|
|
b1499126a2 | ||
|
|
a1876fe653 | ||
|
|
0baa494ea4 | ||
|
|
4249b1383f | ||
|
|
cb05d5799a | ||
|
|
886d333cf2 | ||
|
|
6d5cee1589 | ||
|
|
f248b47719 | ||
|
|
964fb12d7d | ||
|
|
1b34649da8 | ||
|
|
7c83d15c8d | ||
|
|
75a388194a | ||
|
|
f4668e907d | ||
|
|
c9e423b58e | ||
|
|
0c8d0c39e6 | ||
|
|
ae8e981bdf | ||
|
|
f832e18376 | ||
|
|
e2572f2f5b | ||
|
|
4b142ae13c | ||
|
|
f434e50417 | ||
|
|
21481d5646 | ||
|
|
55953b7b4e | ||
|
|
9b54254411 | ||
|
|
8789ef02b9 | ||
|
|
42d4460f7b | ||
|
|
12d6370682 | ||
|
|
11dc1e4d45 | ||
|
|
96f1bdb0ed | ||
|
|
3c52435833 | ||
|
|
9e731ec41f | ||
|
|
d69e6123c7 | ||
|
|
31a6ec2a1e | ||
|
|
12c2c69a9f | ||
|
|
9e17618579 | ||
|
|
06d805e547 | ||
|
|
e1b172483a | ||
|
|
5cbf2de282 | ||
|
|
93ea53e3aa | ||
|
|
42941b62e8 | ||
|
|
d728d32165 | ||
|
|
d95c92bd8f | ||
|
|
620debc3ab | ||
|
|
07cef247c6 | ||
|
|
af9fd36fcf | ||
|
|
b796c91004 |
@@ -142,6 +142,7 @@ export { default as SvgStep3End } from "@opal/icons/step3-end";
|
||||
export { default as SvgStop } from "@opal/icons/stop";
|
||||
export { default as SvgStopCircle } from "@opal/icons/stop-circle";
|
||||
export { default as SvgSun } from "@opal/icons/sun";
|
||||
export { default as SvgTag } from "@opal/icons/tag";
|
||||
export { default as SvgTerminal } from "@opal/icons/terminal";
|
||||
export { default as SvgTerminalSmall } from "@opal/icons/terminal-small";
|
||||
export { default as SvgTextLinesSmall } from "@opal/icons/text-lines-small";
|
||||
|
||||
20
web/lib/opal/src/icons/tag.tsx
Normal file
20
web/lib/opal/src/icons/tag.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { IconProps } from "@opal/types";
|
||||
const SvgTag = ({ size, ...props }: IconProps) => (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
stroke="currentColor"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M4.66666 4.66668H4.67333M13.7267 8.94001L8.94666 13.72C8.82283 13.844 8.67578 13.9423 8.51392 14.0094C8.35205 14.0765 8.17855 14.1111 8.00333 14.1111C7.82811 14.1111 7.65461 14.0765 7.49274 14.0094C7.33088 13.9423 7.18383 13.844 7.05999 13.72L1.33333 8.00001V1.33334H7.99999L13.7267 7.06001C13.975 7.30983 14.1144 7.64776 14.1144 8.00001C14.1144 8.35226 13.975 8.69019 13.7267 8.94001Z"
|
||||
strokeWidth={1.5}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export default SvgTag;
|
||||
@@ -98,6 +98,20 @@ const nextConfig = {
|
||||
},
|
||||
];
|
||||
},
|
||||
async redirects() {
|
||||
return [
|
||||
{
|
||||
source: "/chat",
|
||||
destination: "/app",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/chat/:path*",
|
||||
destination: "/app/:path*",
|
||||
permanent: true,
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
// Sentry configuration for error monitoring:
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
togglePersonaVisibility,
|
||||
} from "./lib";
|
||||
import { FiEdit2 } from "react-icons/fi";
|
||||
import { useUser } from "@/components/user/UserProvider";
|
||||
import { useUser } from "@/providers/UserProvider";
|
||||
import IconButton from "@/refresh-components/buttons/IconButton";
|
||||
import ConfirmationModalLayout from "@/refresh-components/layouts/ConfirmationModalLayout";
|
||||
import Button from "@/refresh-components/buttons/Button";
|
||||
@@ -244,7 +244,7 @@ export function PersonasTable({
|
||||
className="mr-1 my-auto cursor-pointer"
|
||||
onClick={() =>
|
||||
router.push(
|
||||
`/chat/agents/edit/${
|
||||
`/app/agents/edit/${
|
||||
persona.id
|
||||
}?u=${Date.now()}&admin=true` as Route
|
||||
)
|
||||
|
||||
@@ -64,7 +64,7 @@ function MainContent({
|
||||
<Separator />
|
||||
|
||||
<Title>Create an Assistant</Title>
|
||||
<CreateButton href="/chat/agents/create?admin=true">
|
||||
<CreateButton href="/app/agents/create?admin=true">
|
||||
New Assistant
|
||||
</CreateButton>
|
||||
|
||||
@@ -109,7 +109,7 @@ function MainContent({
|
||||
<Text className="text-subtle text-sm mb-4">
|
||||
...and so much more!
|
||||
</Text>
|
||||
<CreateButton href="/chat/agents/create?admin=true">
|
||||
<CreateButton href="/app/agents/create?admin=true">
|
||||
Create Your First Assistant
|
||||
</CreateButton>
|
||||
<div className="mt-6 pt-6 border-t border-border">
|
||||
|
||||
@@ -102,7 +102,7 @@ export default function SlackChannelConfigsTable({
|
||||
) ? (
|
||||
<Link
|
||||
href={
|
||||
`/chat/agents/edit/${slackChannelConfig.persona.id}` as Route
|
||||
`/app/agents/edit/${slackChannelConfig.persona.id}` as Route
|
||||
}
|
||||
className="text-primary hover:underline"
|
||||
>
|
||||
|
||||
@@ -18,7 +18,7 @@ import CardSection from "@/components/admin/CardSection";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { MinimalPersonaSnapshot } from "@/app/admin/assistants/interfaces";
|
||||
import { StandardAnswerCategoryResponse } from "@/components/standardAnswers/getStandardAnswerCategoriesIfEE";
|
||||
import { SEARCH_TOOL_ID } from "@/app/chat/components/tools/constants";
|
||||
import { SEARCH_TOOL_ID } from "@/app/app/components/tools/constants";
|
||||
import { SlackChannelConfigFormFields } from "./SlackChannelConfigFormFields";
|
||||
|
||||
export const SlackChannelConfigCreationForm = ({
|
||||
|
||||
@@ -385,9 +385,7 @@ export function SlackChannelConfigFormFields({
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
router.push(
|
||||
`/chat/agents/edit/${persona.id}` as Route
|
||||
)
|
||||
router.push(`/app/agents/edit/${persona.id}` as Route)
|
||||
}
|
||||
key={persona.id}
|
||||
className="p-2 bg-background-100 cursor-pointer rounded-md flex items-center gap-2"
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
GoogleDriveCredentialJson,
|
||||
GoogleDriveServiceAccountCredentialJson,
|
||||
} from "@/lib/connectors/credentials";
|
||||
import { useUser } from "@/components/user/UserProvider";
|
||||
import { useUser } from "@/providers/UserProvider";
|
||||
import {
|
||||
useGoogleAppCredential,
|
||||
useGoogleServiceAccountKey,
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { GmailAuthSection, GmailJsonUploadSection } from "./Credential";
|
||||
import { usePublicCredentials, useBasicConnectorStatus } from "@/lib/hooks";
|
||||
import Title from "@/components/ui/title";
|
||||
import { useUser } from "@/components/user/UserProvider";
|
||||
import { useUser } from "@/providers/UserProvider";
|
||||
import {
|
||||
useGoogleAppCredential,
|
||||
useGoogleServiceAccountKey,
|
||||
|
||||
@@ -144,7 +144,6 @@ export function DiscordChannelsTable({
|
||||
)
|
||||
}
|
||||
disabled={disabled}
|
||||
className="w-[160px]"
|
||||
>
|
||||
<InputSelect.Trigger placeholder="-" />
|
||||
<InputSelect.Content>
|
||||
|
||||
@@ -364,7 +364,6 @@ export default function Page({ params }: Props) {
|
||||
)
|
||||
}
|
||||
disabled={isUpdating || !guild?.enabled || personasLoading}
|
||||
className="w-[200px]"
|
||||
>
|
||||
<InputSelect.Trigger placeholder="Select agent" />
|
||||
<InputSelect.Content>
|
||||
|
||||
@@ -20,7 +20,7 @@ import Button from "@/refresh-components/buttons/Button";
|
||||
import { usePaidEnterpriseFeaturesEnabled } from "@/components/settings/usePaidEnterpriseFeaturesEnabled";
|
||||
import { IsPublicGroupSelector } from "@/components/IsPublicGroupSelector";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useUser } from "@/components/user/UserProvider";
|
||||
import { useUser } from "@/providers/UserProvider";
|
||||
import { ConnectorMultiSelect } from "@/components/ConnectorMultiSelect";
|
||||
import { NonSelectableConnectors } from "@/components/NonSelectableConnectors";
|
||||
import { FederatedConnectorSelector } from "@/components/FederatedConnectorSelector";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useUser } from "@/components/user/UserProvider";
|
||||
import { useUser } from "@/providers/UserProvider";
|
||||
import { errorHandlingFetcher } from "@/lib/fetcher";
|
||||
import useSWR from "swr";
|
||||
import { KGConfig, KGConfigRaw } from "./interfaces";
|
||||
|
||||
@@ -27,7 +27,7 @@ export default function AnonymousPage({
|
||||
throw new Error("Failed to login as anonymous user");
|
||||
}
|
||||
// Redirect to the chat page and force a refresh
|
||||
window.location.href = "/chat";
|
||||
window.location.href = "/app";
|
||||
} catch (error) {
|
||||
console.error("Error logging in as anonymous user:", error);
|
||||
redirect("/auth/signup?error=Anonymous");
|
||||
|
||||
@@ -57,7 +57,7 @@ export async function GET(req: NextRequest) {
|
||||
redirectTo = `/admin/actions/edit-mcp?server_id=${serverId}`;
|
||||
} else {
|
||||
// For user flow, redirect to chat
|
||||
redirectTo = "/chat";
|
||||
redirectTo = "/app";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,14 +23,14 @@ export default function Page(props: PageProps) {
|
||||
// Handle invalid ID (NaN)
|
||||
useEffect(() => {
|
||||
if (isNaN(agentId)) {
|
||||
router.push("/chat");
|
||||
router.push("/app");
|
||||
}
|
||||
}, [agentId, router]);
|
||||
|
||||
// Redirect to home if agent not found after loading completes
|
||||
useEffect(() => {
|
||||
if (!isLoading && !agent) {
|
||||
router.push("/chat");
|
||||
router.push("/app");
|
||||
}
|
||||
}, [isLoading, agent, router]);
|
||||
|
||||
@@ -5,10 +5,10 @@ import { HealthCheckBanner } from "@/components/health/healthcheck";
|
||||
import {
|
||||
personaIncludesRetrieval,
|
||||
getAvailableContextTokens,
|
||||
} from "@/app/chat/services/lib";
|
||||
} from "@/app/app/services/lib";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { usePopup } from "@/components/admin/connectors/Popup";
|
||||
import { SEARCH_PARAM_NAMES } from "@/app/chat/services/searchParams";
|
||||
import { SEARCH_PARAM_NAMES } from "@/app/app/services/searchParams";
|
||||
import { useFederatedConnectors, useFilters, useLlmManager } from "@/lib/hooks";
|
||||
import { useForcedTools } from "@/lib/hooks/useForcedTools";
|
||||
import OnyxInitializingLoader from "@/components/OnyxInitializingLoader";
|
||||
@@ -17,15 +17,15 @@ import { useSettingsContext } from "@/components/settings/SettingsProvider";
|
||||
import Dropzone from "react-dropzone";
|
||||
import ChatInputBar, {
|
||||
ChatInputBarHandle,
|
||||
} from "@/app/chat/components/input/ChatInputBar";
|
||||
} from "@/app/app/components/input/ChatInputBar";
|
||||
import useChatSessions from "@/hooks/useChatSessions";
|
||||
import useCCPairs from "@/hooks/useCCPairs";
|
||||
import { useTags } from "@/lib/hooks/useTags";
|
||||
import { useDocumentSets } from "@/lib/hooks/useDocumentSets";
|
||||
import { useAgents } from "@/hooks/useAgents";
|
||||
import { ChatPopup } from "@/app/chat/components/ChatPopup";
|
||||
import { AppPopup } from "@/app/app/components/AppPopup";
|
||||
import ExceptionTraceModal from "@/components/modals/ExceptionTraceModal";
|
||||
import { useUser } from "@/components/user/UserProvider";
|
||||
import { useUser } from "@/providers/UserProvider";
|
||||
import NoAssistantModal from "@/components/modals/NoAssistantModal";
|
||||
import TextView from "@/components/chat/TextView";
|
||||
import Modal from "@/refresh-components/Modal";
|
||||
@@ -35,33 +35,38 @@ import { getSourceMetadata } from "@/lib/sources";
|
||||
import { SourceMetadata } from "@/lib/search/interfaces";
|
||||
import { FederatedConnectorDetail, UserRole, ValidSources } from "@/lib/types";
|
||||
import DocumentsSidebar from "@/sections/document-sidebar/DocumentsSidebar";
|
||||
import { useChatController } from "@/app/chat/hooks/useChatController";
|
||||
import { useAssistantController } from "@/app/chat/hooks/useAssistantController";
|
||||
import { useChatSessionController } from "@/app/chat/hooks/useChatSessionController";
|
||||
import { useDeepResearchToggle } from "@/app/chat/hooks/useDeepResearchToggle";
|
||||
import { useIsDefaultAgent } from "@/app/chat/hooks/useIsDefaultAgent";
|
||||
import { useChatController } from "@/hooks/useChatController";
|
||||
import { useAssistantController } from "@/app/app/hooks/useAssistantController";
|
||||
import { useChatSessionController } from "@/app/app/hooks/useChatSessionController";
|
||||
import { useDeepResearchToggle } from "@/app/app/hooks/useDeepResearchToggle";
|
||||
import { useIsDefaultAgent } from "@/app/app/hooks/useIsDefaultAgent";
|
||||
import useQueryController from "@/hooks/useQueryController";
|
||||
import useAppFocus from "@/hooks/useAppFocus";
|
||||
import { useAppBackground } from "@/providers/AppBackgroundProvider";
|
||||
import {
|
||||
useChatSessionStore,
|
||||
useCurrentMessageHistory,
|
||||
} from "@/app/chat/stores/useChatSessionStore";
|
||||
} from "@/app/app/stores/useChatSessionStore";
|
||||
import {
|
||||
useCurrentChatState,
|
||||
useIsReady,
|
||||
useDocumentSidebarVisible,
|
||||
} from "@/app/chat/stores/useChatSessionStore";
|
||||
} from "@/app/app/stores/useChatSessionStore";
|
||||
import FederatedOAuthModal from "@/components/chat/FederatedOAuthModal";
|
||||
import ChatScrollContainer, {
|
||||
ChatScrollContainerHandle,
|
||||
} from "@/components/chat/ChatScrollContainer";
|
||||
import MessageList from "@/components/chat/MessageList";
|
||||
import WelcomeMessage from "@/app/chat/components/WelcomeMessage";
|
||||
import ProjectContextPanel from "@/app/chat/components/projects/ProjectContextPanel";
|
||||
import { useProjectsContext } from "@/app/chat/projects/ProjectsContext";
|
||||
import ChatUI from "@/sections/ChatUI";
|
||||
import SearchResults from "@/sections/SearchUI";
|
||||
import SourceFilter from "@/sections/SourceFilter";
|
||||
import WelcomeMessage from "@/app/app/components/WelcomeMessage";
|
||||
import ProjectContextPanel from "@/app/app/components/projects/ProjectContextPanel";
|
||||
import { useProjectsContext } from "@/app/app/projects/ProjectsContext";
|
||||
import {
|
||||
getProjectTokenCount,
|
||||
getMaxSelectedDocumentTokens,
|
||||
} from "@/app/chat/projects/projectsService";
|
||||
import ProjectChatSessionList from "@/app/chat/components/projects/ProjectChatSessionList";
|
||||
} from "@/app/app/projects/projectsService";
|
||||
import ProjectChatSessionList from "@/app/app/components/projects/ProjectChatSessionList";
|
||||
import { cn } from "@/lib/utils";
|
||||
import Suggestions from "@/sections/Suggestions";
|
||||
import OnboardingFlow from "@/refresh-components/onboarding/OnboardingFlow";
|
||||
@@ -69,20 +74,15 @@ import { OnboardingStep } from "@/refresh-components/onboarding/types";
|
||||
import { useShowOnboarding } from "@/hooks/useShowOnboarding";
|
||||
import * as AppLayouts from "@/layouts/app-layouts";
|
||||
import { SvgChevronDown, SvgFileText } from "@opal/icons";
|
||||
import ChatHeader from "@/app/chat/components/ChatHeader";
|
||||
import IconButton from "@/refresh-components/buttons/IconButton";
|
||||
import Spacer from "@/refresh-components/Spacer";
|
||||
import { DEFAULT_CONTEXT_TOKENS } from "@/lib/constants";
|
||||
import {
|
||||
CHAT_BACKGROUND_NONE,
|
||||
getBackgroundById,
|
||||
} from "@/lib/constants/chatBackgrounds";
|
||||
import Spacer from "@/refresh-components/Spacer";
|
||||
|
||||
export interface ChatPageProps {
|
||||
firstMessage?: string;
|
||||
}
|
||||
|
||||
export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
export default function AppPage({ firstMessage }: ChatPageProps) {
|
||||
// Performance tracking
|
||||
// Keeping this here in case we need to track down slow renders in the future
|
||||
// const renderCount = useRef(0);
|
||||
@@ -190,6 +190,8 @@ export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
assistantId: selectedAssistant?.id,
|
||||
});
|
||||
|
||||
const { appBackgroundUrl, hasBackground } = useAppBackground();
|
||||
|
||||
const [presentingDocument, setPresentingDocument] =
|
||||
useState<MinimalOnyxDocument | null>(null);
|
||||
|
||||
@@ -263,9 +265,11 @@ export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
}
|
||||
}, [lastFailedFiles, setPopup, clearLastFailedFiles]);
|
||||
|
||||
const [projectPanelVisible, setProjectPanelVisible] = useState(true);
|
||||
const chatInputBarRef = useRef<ChatInputBarHandle>(null);
|
||||
|
||||
// Determine current app focus for conditional rendering
|
||||
const appFocus = useAppFocus();
|
||||
|
||||
const filterManager = useFilters();
|
||||
|
||||
const isDefaultAgent = useIsDefaultAgent({
|
||||
@@ -378,6 +382,36 @@ export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
});
|
||||
|
||||
useSendMessageToParent();
|
||||
const onChat = useCallback(
|
||||
(message: string) => {
|
||||
onSubmit({
|
||||
message,
|
||||
currentMessageFiles,
|
||||
deepResearch: deepResearchEnabled,
|
||||
});
|
||||
if (showOnboarding) {
|
||||
finishOnboarding();
|
||||
}
|
||||
},
|
||||
[
|
||||
onSubmit,
|
||||
currentMessageFiles,
|
||||
deepResearchEnabled,
|
||||
showOnboarding,
|
||||
finishOnboarding,
|
||||
]
|
||||
);
|
||||
|
||||
// Unified query controller - handles classification and search routing
|
||||
const queryController = useQueryController(onChat);
|
||||
|
||||
// Source filter state for search results
|
||||
const [selectedSources, setSelectedSources] = useState<string[]>([]);
|
||||
|
||||
// Reset source filter when search results change
|
||||
useEffect(() => {
|
||||
setSelectedSources([]);
|
||||
}, [queryController.searchResults]);
|
||||
|
||||
const retrievalEnabled = useMemo(() => {
|
||||
if (liveAssistant) {
|
||||
@@ -443,17 +477,28 @@ export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
}
|
||||
|
||||
const handleChatInputSubmit = useCallback(
|
||||
(message: string) => {
|
||||
onSubmit({
|
||||
message,
|
||||
currentMessageFiles: currentMessageFiles,
|
||||
deepResearch: deepResearchEnabled,
|
||||
});
|
||||
if (showOnboarding) {
|
||||
finishOnboarding();
|
||||
async (message: string) => {
|
||||
// If we're in an existing chat session, always use chat mode
|
||||
// (appMode only applies to new sessions)
|
||||
if (currentChatSessionId) {
|
||||
queryController.reset();
|
||||
onSubmit({
|
||||
message,
|
||||
currentMessageFiles,
|
||||
deepResearch: deepResearchEnabled,
|
||||
});
|
||||
if (showOnboarding) {
|
||||
finishOnboarding();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// For new sessions, let the query controller handle routing
|
||||
await queryController.submit(message);
|
||||
},
|
||||
[
|
||||
currentChatSessionId,
|
||||
queryController,
|
||||
onSubmit,
|
||||
currentMessageFiles,
|
||||
deepResearchEnabled,
|
||||
@@ -462,6 +507,14 @@ export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
]
|
||||
);
|
||||
|
||||
// Handle document click from search results
|
||||
const handleSearchDocumentClick = useCallback(
|
||||
(doc: MinimalOnyxDocument) => {
|
||||
setPresentingDocument(doc);
|
||||
},
|
||||
[setPresentingDocument]
|
||||
);
|
||||
|
||||
// Memoized callbacks for DocumentsSidebar
|
||||
const handleMobileDocumentSidebarClose = useCallback(() => {
|
||||
updateCurrentDocumentSidebarVisible(false);
|
||||
@@ -490,15 +543,6 @@ export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
useEffect(() => {
|
||||
if (!!currentProjectId && !currentChatSessionId) {
|
||||
setProjectPanelVisible(true);
|
||||
}
|
||||
if (!!currentChatSessionId) {
|
||||
setProjectPanelVisible(false);
|
||||
}
|
||||
}, [currentProjectId, currentChatSessionId]);
|
||||
|
||||
// When no chat session exists but a project is selected, fetch the
|
||||
// total tokens for the project's files so upload UX can compare
|
||||
// against available context similar to session-based flows.
|
||||
@@ -576,14 +620,52 @@ export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
);
|
||||
}
|
||||
|
||||
// Chat background logic
|
||||
const chatBackgroundId = user?.preferences?.chat_background;
|
||||
const chatBackground = getBackgroundById(chatBackgroundId ?? null);
|
||||
const hasBackground =
|
||||
chatBackground && chatBackground.url !== CHAT_BACKGROUND_NONE;
|
||||
|
||||
if (!isReady) return <OnyxInitializingLoader />;
|
||||
|
||||
const hasSuggestions = (liveAssistant?.starter_messages?.length ?? 0) > 0;
|
||||
const showWelcomeMessage = !queryController.classification;
|
||||
const showOnboardingUi =
|
||||
showOnboarding ||
|
||||
(user?.role !== UserRole.ADMIN && !user?.personalization?.name);
|
||||
|
||||
const chatInputBar = (
|
||||
<ChatInputBar
|
||||
ref={chatInputBarRef}
|
||||
deepResearchEnabled={deepResearchEnabled}
|
||||
toggleDeepResearch={toggleDeepResearch}
|
||||
toggleDocumentSidebar={toggleDocumentSidebar}
|
||||
filterManager={filterManager}
|
||||
llmManager={llmManager}
|
||||
removeDocs={() => setSelectedDocuments([])}
|
||||
retrievalEnabled={retrievalEnabled}
|
||||
selectedDocuments={selectedDocuments}
|
||||
initialMessage={
|
||||
queryController.query ||
|
||||
searchParams?.get(SEARCH_PARAM_NAMES.USER_PROMPT) ||
|
||||
""
|
||||
}
|
||||
stopGenerating={stopGenerating}
|
||||
onSubmit={handleChatInputSubmit}
|
||||
chatState={currentChatState}
|
||||
currentSessionFileTokenCount={
|
||||
currentChatSessionId
|
||||
? currentSessionFileTokenCount
|
||||
: projectContextTokenCount
|
||||
}
|
||||
availableContextTokens={availableContextTokens}
|
||||
selectedAssistant={selectedAssistant || liveAssistant}
|
||||
handleFileUpload={handleMessageSpecificFileUpload}
|
||||
setPresentingDocument={setPresentingDocument}
|
||||
disabled={
|
||||
(!llmManager.isLoadingProviders &&
|
||||
llmManager.hasAnyProvider === false) ||
|
||||
(!isLoadingOnboarding &&
|
||||
onboardingState.currentStep !== OnboardingStep.Complete)
|
||||
}
|
||||
isClassifying={queryController.isClassifying}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<HealthCheckBanner />
|
||||
@@ -592,7 +674,7 @@ export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
Only used in the EE version of the app. */}
|
||||
{popup}
|
||||
|
||||
<ChatPopup />
|
||||
<AppPopup />
|
||||
|
||||
{retrievalEnabled && documentSidebarVisible && settings.isMobile && (
|
||||
<div className="md:hidden">
|
||||
@@ -638,7 +720,7 @@ export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
|
||||
<FederatedOAuthModal />
|
||||
|
||||
<AppLayouts.Root disableFooter>
|
||||
<AppLayouts.Root>
|
||||
<Dropzone
|
||||
onDrop={(acceptedFiles) =>
|
||||
handleMessageSpecificFileUpload(acceptedFiles)
|
||||
@@ -648,163 +730,156 @@ export default function ChatPage({ firstMessage }: ChatPageProps) {
|
||||
{({ getRootProps }) => (
|
||||
<div
|
||||
className={cn(
|
||||
"h-full w-full flex flex-col items-center outline-none relative",
|
||||
hasBackground && "bg-cover bg-center bg-fixed"
|
||||
"flex flex-col h-full items-center outline-none relative",
|
||||
!!appBackgroundUrl && "bg-cover bg-center bg-fixed"
|
||||
)}
|
||||
style={
|
||||
hasBackground
|
||||
? { backgroundImage: `url(${chatBackground.url})` }
|
||||
!!appBackgroundUrl
|
||||
? { backgroundImage: `url(${appBackgroundUrl})` }
|
||||
: undefined
|
||||
}
|
||||
{...getRootProps({ tabIndex: -1 })}
|
||||
>
|
||||
{/* Semi-transparent overlay for readability when background is set */}
|
||||
{hasBackground && (
|
||||
{!!appBackgroundUrl && (
|
||||
<div className="absolute inset-0 bg-background/80 pointer-events-none" />
|
||||
)}
|
||||
|
||||
{/* ProjectUI */}
|
||||
{!!currentProjectId && projectPanelVisible && (
|
||||
<ProjectContextPanel
|
||||
projectTokenCount={projectContextTokenCount}
|
||||
availableContextTokens={availableContextTokens}
|
||||
setPresentingDocument={setPresentingDocument}
|
||||
/>
|
||||
)}
|
||||
{queryController.classification === "search" ? (
|
||||
// ========== SEARCH MODE: Grid Layout ==========
|
||||
<div className="grid grid-cols-[3fr_1fr] grid-rows-[auto_1fr] h-full w-full gap-x-8">
|
||||
{/* Row 1, Col 1: ChatInputBar */}
|
||||
<div className="flex flex-col w-full justify-center items-end py-1 pointer-events-auto">
|
||||
<div className="w-[var(--main-app-width)]">
|
||||
{chatInputBar}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ChatUI */}
|
||||
{!!currentChatSessionId && liveAssistant && (
|
||||
<ChatScrollContainer
|
||||
ref={scrollContainerRef}
|
||||
sessionId={currentChatSessionId}
|
||||
anchorSelector={anchorSelector}
|
||||
autoScroll={autoScrollEnabled}
|
||||
isStreaming={isStreaming}
|
||||
onScrollButtonVisibilityChange={setShowScrollButton}
|
||||
disableFadeOverlay={hasBackground}
|
||||
>
|
||||
<AppLayouts.StickyHeader>
|
||||
<ChatHeader />
|
||||
</AppLayouts.StickyHeader>
|
||||
<MessageList
|
||||
liveAssistant={liveAssistant}
|
||||
llmManager={llmManager}
|
||||
deepResearchEnabled={deepResearchEnabled}
|
||||
currentMessageFiles={currentMessageFiles}
|
||||
setPresentingDocument={setPresentingDocument}
|
||||
onSubmit={onSubmit}
|
||||
onMessageSelection={onMessageSelection}
|
||||
stopGenerating={stopGenerating}
|
||||
onResubmit={handleResubmitLastMessage}
|
||||
anchorNodeId={anchorNodeId}
|
||||
disableBlur={!hasBackground}
|
||||
/>
|
||||
</ChatScrollContainer>
|
||||
)}
|
||||
{/* Row 1, Col 2: Empty */}
|
||||
<div />
|
||||
|
||||
{!currentChatSessionId && !currentProjectId && (
|
||||
<div className="w-full flex-1 flex flex-col items-center justify-end">
|
||||
<WelcomeMessage
|
||||
agent={liveAssistant}
|
||||
isDefaultAgent={isDefaultAgent}
|
||||
/>
|
||||
<Spacer rem={1.5} />
|
||||
{/* Row 2, Col 1: Search Results */}
|
||||
<div className="min-h-0 overflow-hidden flex flex-col items-end">
|
||||
<SearchResults
|
||||
results={queryController.searchResults}
|
||||
llmSelectedDocIds={queryController.llmSelectedDocIds}
|
||||
onDocumentClick={handleSearchDocumentClick}
|
||||
selectedSources={selectedSources}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Row 2, Col 2: Source Filter */}
|
||||
<div className="min-h-0 overflow-hidden">
|
||||
<SourceFilter
|
||||
results={queryController.searchResults}
|
||||
selectedSources={selectedSources}
|
||||
onSourceChange={setSelectedSources}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* ChatInputBar container - absolutely positioned when in chat, centered when no session */}
|
||||
<div
|
||||
className={cn(
|
||||
"flex justify-center",
|
||||
currentChatSessionId
|
||||
? "absolute bottom-6 left-0 right-0 pointer-events-none"
|
||||
: "w-full"
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
"w-[min(50rem,100%)] z-sticky flex flex-col px-4",
|
||||
currentChatSessionId && "pointer-events-auto"
|
||||
)}
|
||||
>
|
||||
{/* Scroll to bottom button - positioned above ChatInputBar */}
|
||||
{showScrollButton && (
|
||||
<div className="mb-2 self-center">
|
||||
<IconButton
|
||||
icon={SvgChevronDown}
|
||||
onClick={handleScrollToBottom}
|
||||
aria-label="Scroll to bottom"
|
||||
) : (
|
||||
// ========== NORMAL MODE: Flex Layout ==========
|
||||
<>
|
||||
{/* Upper Block */}
|
||||
<div className="flex-1 min-h-0 w-full flex flex-col justify-end items-center overflow-y-auto overflow-x-hidden">
|
||||
{/* ProjectUI */}
|
||||
{appFocus.isProject() && (
|
||||
<ProjectContextPanel
|
||||
projectTokenCount={projectContextTokenCount}
|
||||
availableContextTokens={availableContextTokens}
|
||||
setPresentingDocument={setPresentingDocument}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* ChatUI */}
|
||||
{(appFocus.isChat() ||
|
||||
queryController.classification === "chat") && (
|
||||
<ChatScrollContainer
|
||||
ref={scrollContainerRef}
|
||||
sessionId={appFocus.getId()!}
|
||||
anchorSelector={anchorSelector}
|
||||
autoScroll={autoScrollEnabled}
|
||||
isStreaming={isStreaming}
|
||||
onScrollButtonVisibilityChange={setShowScrollButton}
|
||||
disableFadeOverlay={hasBackground}
|
||||
>
|
||||
{showScrollButton && (
|
||||
<div className="absolute bottom-4 z-sticky">
|
||||
<IconButton
|
||||
icon={SvgChevronDown}
|
||||
onClick={handleScrollToBottom}
|
||||
secondary
|
||||
aria-label="Scroll to bottom"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ChatUI
|
||||
liveAssistant={liveAssistant!}
|
||||
llmManager={llmManager}
|
||||
deepResearchEnabled={deepResearchEnabled}
|
||||
currentMessageFiles={currentMessageFiles}
|
||||
setPresentingDocument={setPresentingDocument}
|
||||
onSubmit={onSubmit}
|
||||
onMessageSelection={onMessageSelection}
|
||||
stopGenerating={stopGenerating}
|
||||
onResubmit={handleResubmitLastMessage}
|
||||
anchorNodeId={anchorNodeId}
|
||||
disableBlur={!hasBackground}
|
||||
/>
|
||||
</ChatScrollContainer>
|
||||
)}
|
||||
|
||||
{/* Onboarding */}
|
||||
{(appFocus.isNewSession() || appFocus.isAgent()) &&
|
||||
showOnboardingUi && (
|
||||
<>
|
||||
<OnboardingFlow
|
||||
handleHideOnboarding={hideOnboarding}
|
||||
handleFinishOnboarding={finishOnboarding}
|
||||
state={onboardingState}
|
||||
actions={onboardingActions}
|
||||
llmDescriptors={llmDescriptors}
|
||||
/>
|
||||
<Spacer rem={1} />
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Welcome Message */}
|
||||
{(appFocus.isNewSession() || appFocus.isAgent()) &&
|
||||
showWelcomeMessage && (
|
||||
<>
|
||||
<WelcomeMessage
|
||||
agent={liveAssistant}
|
||||
isDefaultAgent={isDefaultAgent}
|
||||
/>
|
||||
<Spacer rem={1} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* ChatInputBar - centrally laid out */}
|
||||
<div className="w-[var(--main-app-width)] pointer-events-auto py-1">
|
||||
{chatInputBar}
|
||||
</div>
|
||||
|
||||
{/* Lower Block */}
|
||||
{((appFocus.isNewSession() &&
|
||||
queryController.classification !== "chat") ||
|
||||
appFocus.isAgent() ||
|
||||
appFocus.isProject()) && (
|
||||
<div className="flex-1 min-h-0 w-full">
|
||||
{/* Agent-Suggestions */}
|
||||
{appFocus.isAgent() && hasSuggestions && (
|
||||
<Suggestions onSubmit={onSubmit} />
|
||||
)}
|
||||
|
||||
{/* Project Sessions */}
|
||||
{appFocus.isProject() && <ProjectChatSessionList />}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(showOnboarding ||
|
||||
(user?.role !== UserRole.ADMIN &&
|
||||
!user?.personalization?.name)) &&
|
||||
currentProjectId === null && (
|
||||
<OnboardingFlow
|
||||
handleHideOnboarding={hideOnboarding}
|
||||
handleFinishOnboarding={finishOnboarding}
|
||||
state={onboardingState}
|
||||
actions={onboardingActions}
|
||||
llmDescriptors={llmDescriptors}
|
||||
/>
|
||||
)}
|
||||
|
||||
<ChatInputBar
|
||||
ref={chatInputBarRef}
|
||||
deepResearchEnabled={deepResearchEnabled}
|
||||
toggleDeepResearch={toggleDeepResearch}
|
||||
toggleDocumentSidebar={toggleDocumentSidebar}
|
||||
filterManager={filterManager}
|
||||
llmManager={llmManager}
|
||||
removeDocs={() => setSelectedDocuments([])}
|
||||
retrievalEnabled={retrievalEnabled}
|
||||
selectedDocuments={selectedDocuments}
|
||||
initialMessage={
|
||||
searchParams?.get(SEARCH_PARAM_NAMES.USER_PROMPT) || ""
|
||||
}
|
||||
stopGenerating={stopGenerating}
|
||||
onSubmit={handleChatInputSubmit}
|
||||
chatState={currentChatState}
|
||||
currentSessionFileTokenCount={
|
||||
currentChatSessionId
|
||||
? currentSessionFileTokenCount
|
||||
: projectContextTokenCount
|
||||
}
|
||||
availableContextTokens={availableContextTokens}
|
||||
selectedAssistant={selectedAssistant || liveAssistant}
|
||||
handleFileUpload={handleMessageSpecificFileUpload}
|
||||
setPresentingDocument={setPresentingDocument}
|
||||
disabled={
|
||||
(!llmManager.isLoadingProviders &&
|
||||
llmManager.hasAnyProvider === false) ||
|
||||
(!isLoadingOnboarding &&
|
||||
onboardingState.currentStep !== OnboardingStep.Complete)
|
||||
}
|
||||
/>
|
||||
|
||||
<Spacer rem={0.5} />
|
||||
|
||||
{!!currentProjectId && <ProjectChatSessionList />}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* SearchUI */}
|
||||
{!currentChatSessionId && !currentProjectId && (
|
||||
<div className="flex flex-1 flex-col items-center w-full">
|
||||
{liveAssistant?.starter_messages &&
|
||||
liveAssistant.starter_messages.length > 0 &&
|
||||
messageHistory.length === 0 &&
|
||||
!currentProjectId &&
|
||||
!currentChatSessionId && (
|
||||
<div className="max-w-[50rem] w-full">
|
||||
<Suggestions onSubmit={onSubmit} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<AppLayouts.Footer />
|
||||
</div>
|
||||
)}
|
||||
</Dropzone>
|
||||
@@ -25,7 +25,7 @@ const CustomLogoHeaderIcon = ({ className, size = 24 }: IconProps) => (
|
||||
/>
|
||||
);
|
||||
|
||||
export function ChatPopup() {
|
||||
export function AppPopup() {
|
||||
const [completedFlow, setCompletedFlow] = useState(true);
|
||||
const [showConsentError, setShowConsentError] = useState(false);
|
||||
const [consentChecked, setConsentChecked] = useState(false);
|
||||
@@ -10,6 +10,7 @@ import Text from "@/refresh-components/texts/Text";
|
||||
import { MinimalPersonaSnapshot } from "@/app/admin/assistants/interfaces";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useSettingsContext } from "@/components/settings/SettingsProvider";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
|
||||
export interface WelcomeMessageProps {
|
||||
agent?: MinimalPersonaSnapshot;
|
||||
@@ -38,31 +39,32 @@ export default function WelcomeMessage({
|
||||
|
||||
if (isDefaultAgent) {
|
||||
content = (
|
||||
<div data-testid="onyx-logo" className="flex flex-row items-center gap-4">
|
||||
<Logo folded size={32} />
|
||||
<Text as="p" headingH2>
|
||||
{greeting}
|
||||
</Text>
|
||||
<div data-testid="onyx-logo">
|
||||
<Section flexDirection="row" gap={1}>
|
||||
<Logo folded size={32} />
|
||||
<Text as="p" headingH2>
|
||||
{greeting}
|
||||
</Text>
|
||||
</Section>
|
||||
</div>
|
||||
);
|
||||
} else if (agent) {
|
||||
content = (
|
||||
<>
|
||||
<div
|
||||
data-testid="assistant-name-display"
|
||||
className="flex flex-row items-center gap-3"
|
||||
>
|
||||
<AgentAvatar agent={agent} size={36} />
|
||||
<Text as="p" headingH2>
|
||||
{agent.name}
|
||||
</Text>
|
||||
<Section gap={0.25}>
|
||||
<div data-testid="assistant-name-display">
|
||||
<Section flexDirection="row" gap={1}>
|
||||
<AgentAvatar agent={agent} size={36} />
|
||||
<Text as="p" headingH2>
|
||||
{agent.name}
|
||||
</Text>
|
||||
</Section>
|
||||
</div>
|
||||
{agent.description && (
|
||||
<Text as="p" secondaryBody text03>
|
||||
<Text secondaryBody text03>
|
||||
{agent.description}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -71,10 +73,7 @@ export default function WelcomeMessage({
|
||||
if (!content) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
data-testid="chat-intro"
|
||||
className="flex flex-col items-center justify-center gap-3 max-w-[50rem]"
|
||||
>
|
||||
<div data-testid="chat-intro" className="w-[min(50rem,100%)]">
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { buildImgUrl } from "@/app/chat/components/files/images/utils";
|
||||
import { buildImgUrl } from "@/app/app/components/files/images/utils";
|
||||
import { cn } from "@/lib/utils";
|
||||
import * as Dialog from "@radix-ui/react-dialog";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useState } from "react";
|
||||
import { FiDownload } from "react-icons/fi";
|
||||
import { ImageShape } from "@/app/chat/services/streamingModels";
|
||||
import { FullImageModal } from "@/app/chat/components/files/images/FullImageModal";
|
||||
import { buildImgUrl } from "@/app/chat/components/files/images/utils";
|
||||
import { ImageShape } from "@/app/app/services/streamingModels";
|
||||
import { FullImageModal } from "@/app/app/components/files/images/FullImageModal";
|
||||
import { buildImgUrl } from "@/app/app/components/files/images/utils";
|
||||
import IconButton from "@/refresh-components/buttons/IconButton";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -11,24 +11,24 @@ import React, {
|
||||
import LineItem from "@/refresh-components/buttons/LineItem";
|
||||
import { MinimalPersonaSnapshot } from "@/app/admin/assistants/interfaces";
|
||||
import LLMPopover from "@/refresh-components/popovers/LLMPopover";
|
||||
import { InputPrompt } from "@/app/chat/interfaces";
|
||||
import { InputPrompt } from "@/app/app/interfaces";
|
||||
import { FilterManager, LlmManager, useFederatedConnectors } from "@/lib/hooks";
|
||||
import usePromptShortcuts from "@/hooks/usePromptShortcuts";
|
||||
import useFilter from "@/hooks/useFilter";
|
||||
import useCCPairs from "@/hooks/useCCPairs";
|
||||
import { OnyxDocument, MinimalOnyxDocument } from "@/lib/search/interfaces";
|
||||
import { ChatState } from "@/app/chat/interfaces";
|
||||
import { ChatState } from "@/app/app/interfaces";
|
||||
import { useForcedTools } from "@/lib/hooks/useForcedTools";
|
||||
import { getFormattedDateRangeString } from "@/lib/dateUtils";
|
||||
import { truncateString, cn } from "@/lib/utils";
|
||||
import { useUser } from "@/components/user/UserProvider";
|
||||
import { useUser } from "@/providers/UserProvider";
|
||||
import { SettingsContext } from "@/components/settings/SettingsProvider";
|
||||
import { useProjectsContext } from "@/app/chat/projects/ProjectsContext";
|
||||
import { FileCard } from "@/app/chat/components/input/FileCard";
|
||||
import { useProjectsContext } from "@/app/app/projects/ProjectsContext";
|
||||
import { FileCard } from "@/app/app/components/input/FileCard";
|
||||
import {
|
||||
ProjectFile,
|
||||
UserFileStatus,
|
||||
} from "@/app/chat/projects/projectsService";
|
||||
} from "@/app/app/projects/projectsService";
|
||||
import IconButton from "@/refresh-components/buttons/IconButton";
|
||||
import FilePickerPopover from "@/refresh-components/popovers/FilePickerPopover";
|
||||
import ActionsPopover from "@/refresh-components/popovers/ActionsPopover";
|
||||
@@ -36,7 +36,7 @@ import SelectButton from "@/refresh-components/buttons/SelectButton";
|
||||
import {
|
||||
getIconForAction,
|
||||
hasSearchToolsAvailable,
|
||||
} from "@/app/chat/services/actionUtils";
|
||||
} from "@/app/app/services/actionUtils";
|
||||
import {
|
||||
SvgArrowUp,
|
||||
SvgCalendar,
|
||||
@@ -49,6 +49,7 @@ import {
|
||||
SvgX,
|
||||
} from "@opal/icons";
|
||||
import Popover from "@/refresh-components/Popover";
|
||||
import SimpleLoader from "@/refresh-components/loaders/SimpleLoader";
|
||||
|
||||
const LINE_HEIGHT = 24;
|
||||
const MIN_INPUT_HEIGHT = 44;
|
||||
@@ -120,6 +121,8 @@ export interface ChatInputBarProps {
|
||||
setPresentingDocument?: (document: MinimalOnyxDocument) => void;
|
||||
toggleDeepResearch: () => void;
|
||||
disabled: boolean;
|
||||
/** Whether query classification is in progress */
|
||||
isClassifying?: boolean;
|
||||
ref?: React.Ref<ChatInputBarHandle>;
|
||||
}
|
||||
|
||||
@@ -145,6 +148,7 @@ const ChatInputBar = React.memo(
|
||||
toggleDeepResearch,
|
||||
setPresentingDocument,
|
||||
disabled,
|
||||
isClassifying = false,
|
||||
ref,
|
||||
}: ChatInputBarProps) => {
|
||||
// Internal message state - kept local to avoid parent re-renders on every keystroke
|
||||
@@ -389,7 +393,7 @@ const ChatInputBar = React.memo(
|
||||
e.preventDefault();
|
||||
if (tabbingIconIndex === sortedFilteredPrompts.length) {
|
||||
// "Create a new prompt" is selected
|
||||
window.open("/chat/settings/chat-preferences", "_self");
|
||||
window.open("/app/settings/chat-preferences", "_self");
|
||||
} else {
|
||||
const selectedPrompt = sortedFilteredPrompts[tabbingIconIndex];
|
||||
if (selectedPrompt) {
|
||||
@@ -516,7 +520,7 @@ const ChatInputBar = React.memo(
|
||||
sortedFilteredPrompts.length > 0 ? null : undefined,
|
||||
<LineItem
|
||||
key="create-new"
|
||||
href="/chat/settings/chat-preferences"
|
||||
href="/app/settings/chat-preferences"
|
||||
icon={SvgPlus}
|
||||
selected={tabbingIconIndex === sortedFilteredPrompts.length}
|
||||
emphasized={tabbingIconIndex === sortedFilteredPrompts.length}
|
||||
@@ -690,9 +694,17 @@ const ChatInputBar = React.memo(
|
||||
{/* Submit button - always visible */}
|
||||
<IconButton
|
||||
id="onyx-chat-input-send-button"
|
||||
icon={chatState === "input" ? SvgArrowUp : SvgStop}
|
||||
icon={
|
||||
isClassifying
|
||||
? SimpleLoader
|
||||
: chatState === "input"
|
||||
? SvgArrowUp
|
||||
: SvgStop
|
||||
}
|
||||
disabled={
|
||||
(chatState === "input" && !message) || hasUploadingFiles
|
||||
isClassifying ||
|
||||
(chatState === "input" && !message) ||
|
||||
hasUploadingFiles
|
||||
}
|
||||
onClick={() => {
|
||||
if (chatState == "streaming") {
|
||||
@@ -1,13 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import React, { useMemo } from "react";
|
||||
import type { ProjectFile } from "@/app/chat/projects/projectsService";
|
||||
import { UserFileStatus } from "@/app/chat/projects/projectsService";
|
||||
import type { ProjectFile } from "@/app/app/projects/projectsService";
|
||||
import { UserFileStatus } from "@/app/app/projects/projectsService";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import Truncated from "@/refresh-components/texts/Truncated";
|
||||
import { cn, isImageFile } from "@/lib/utils";
|
||||
import SimpleLoader from "@/refresh-components/loaders/SimpleLoader";
|
||||
import { SvgFileText, SvgX } from "@opal/icons";
|
||||
|
||||
function ImageFileCard({
|
||||
file,
|
||||
imageUrl,
|
||||
@@ -4,8 +4,8 @@ import { useState } from "react";
|
||||
import Button from "@/refresh-components/buttons/Button";
|
||||
import { Callout } from "@/components/ui/callout";
|
||||
import Text from "@/components/ui/text";
|
||||
import { ChatSession, ChatSessionSharedStatus } from "@/app/chat/interfaces";
|
||||
import { SEARCH_PARAM_NAMES } from "@/app/chat/services/searchParams";
|
||||
import { ChatSession, ChatSessionSharedStatus } from "@/app/app/interfaces";
|
||||
import { SEARCH_PARAM_NAMES } from "@/app/app/services/searchParams";
|
||||
import { usePopup } from "@/components/admin/connectors/Popup";
|
||||
import { structureValue } from "@/lib/llm/utils";
|
||||
import { LlmDescriptor, useLlmManager } from "@/lib/hooks";
|
||||
@@ -14,15 +14,15 @@ import { AdvancedOptionsToggle } from "@/components/AdvancedOptionsToggle";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useCurrentAgent } from "@/hooks/useAgents";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useChatSessionStore } from "@/app/chat/stores/useChatSessionStore";
|
||||
import { useChatSessionStore } from "@/app/app/stores/useChatSessionStore";
|
||||
import ConfirmationModalLayout from "@/refresh-components/layouts/ConfirmationModalLayout";
|
||||
import CopyIconButton from "@/refresh-components/buttons/CopyIconButton";
|
||||
import { copyAll } from "@/app/chat/message/copyingUtils";
|
||||
import { copyAll } from "@/app/app/message/copyingUtils";
|
||||
import { SvgCopy, SvgShare } from "@opal/icons";
|
||||
|
||||
function buildShareLink(chatSessionId: string) {
|
||||
const baseUrl = `${window.location.protocol}//${window.location.host}`;
|
||||
return `${baseUrl}/chat/shared/${chatSessionId}`;
|
||||
return `${baseUrl}/app/shared/${chatSessionId}`;
|
||||
}
|
||||
|
||||
async function generateShareLink(chatSessionId: string) {
|
||||
@@ -53,7 +53,7 @@ async function generateSeedLink(
|
||||
modelOverride.modelName
|
||||
)
|
||||
: null;
|
||||
return `${baseUrl}/chat${
|
||||
return `${baseUrl}/app${
|
||||
message
|
||||
? `?${SEARCH_PARAM_NAMES.USER_PROMPT}=${encodeURIComponent(message)}`
|
||||
: ""
|
||||
@@ -4,12 +4,11 @@ import React, { useMemo } from "react";
|
||||
import Link from "next/link";
|
||||
import { ChatSessionMorePopup } from "@/components/sidebar/ChatSessionMorePopup";
|
||||
import { useProjectsContext } from "../../projects/ProjectsContext";
|
||||
import { ChatSession } from "@/app/chat/interfaces";
|
||||
import { ChatSession } from "@/app/app/interfaces";
|
||||
import AgentAvatar from "@/refresh-components/avatars/AgentAvatar";
|
||||
import { useAgents } from "@/hooks/useAgents";
|
||||
import { formatRelativeTime } from "./project_utils";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn, formatRelativeTime } from "@/lib/utils";
|
||||
import { UNNAMED_CHAT } from "@/lib/constants";
|
||||
import ChatSessionSkeleton from "@/refresh-components/skeletons/ChatSessionSkeleton";
|
||||
import { SvgBubbleText } from "@opal/icons";
|
||||
@@ -60,7 +59,7 @@ export default function ProjectChatSessionList() {
|
||||
{projectChats.map((chat) => (
|
||||
<Link
|
||||
key={chat.id}
|
||||
href={{ pathname: "/chat", query: { chatId: chat.id } }}
|
||||
href={{ pathname: "/app", query: { chatId: chat.id } }}
|
||||
className="relative flex w-full"
|
||||
onMouseEnter={() => setHoveredChatId(chat.id)}
|
||||
onMouseLeave={() => setHoveredChatId(null)}
|
||||
@@ -18,7 +18,7 @@ import CreateButton from "@/refresh-components/buttons/CreateButton";
|
||||
import { FileCard } from "../input/FileCard";
|
||||
import { hasNonImageFiles } from "@/lib/utils";
|
||||
import IconButton from "@/refresh-components/buttons/IconButton";
|
||||
import { FileCardSkeleton } from "@/app/chat/components/input/FileCard";
|
||||
import { FileCardSkeleton } from "@/app/app/components/input/FileCard";
|
||||
import ButtonRenaming from "@/refresh-components/buttons/ButtonRenaming";
|
||||
import { UserFileStatus } from "../../projects/projectsService";
|
||||
import { SvgAddLines, SvgEdit, SvgFiles, SvgFolderOpen } from "@opal/icons";
|
||||
@@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { ChatFileType, FileDescriptor } from "@/app/chat/interfaces";
|
||||
import { ChatFileType, FileDescriptor } from "@/app/app/interfaces";
|
||||
import Attachment from "@/refresh-components/Attachment";
|
||||
import { InMessageImage } from "@/app/chat/components/files/images/InMessageImage";
|
||||
import { InMessageImage } from "@/app/app/components/files/images/InMessageImage";
|
||||
import CsvContent from "@/components/tools/CSVContent";
|
||||
import TextView from "@/components/chat/TextView";
|
||||
import { MinimalOnyxDocument } from "@/lib/search/interfaces";
|
||||
@@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { FileDescriptor } from "@/app/chat/interfaces";
|
||||
import { FileDescriptor } from "@/app/app/interfaces";
|
||||
import "katex/dist/katex.min.css";
|
||||
import MessageSwitcher from "@/app/chat/message/MessageSwitcher";
|
||||
import MessageSwitcher from "@/app/app/message/MessageSwitcher";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import { cn } from "@/lib/utils";
|
||||
import IconButton from "@/refresh-components/buttons/IconButton";
|
||||
@@ -17,25 +17,25 @@ import {
|
||||
TopLevelBranching,
|
||||
StopReason,
|
||||
Stop,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
import { CitationMap } from "@/app/chat/interfaces";
|
||||
import { FullChatState } from "@/app/chat/message/messageComponents/interfaces";
|
||||
import { FeedbackType } from "@/app/chat/interfaces";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import { CitationMap } from "@/app/app/interfaces";
|
||||
import { FullChatState } from "@/app/app/message/messageComponents/interfaces";
|
||||
import { FeedbackType } from "@/app/app/interfaces";
|
||||
import { OnyxDocument } from "@/lib/search/interfaces";
|
||||
import CitedSourcesToggle from "@/app/chat/message/messageComponents/CitedSourcesToggle";
|
||||
import CitedSourcesToggle from "@/app/app/message/messageComponents/CitedSourcesToggle";
|
||||
import { TooltipGroup } from "@/components/tooltip/CustomTooltip";
|
||||
import {
|
||||
useChatSessionStore,
|
||||
useDocumentSidebarVisible,
|
||||
useSelectedNodeForDocDisplay,
|
||||
useCurrentChatState,
|
||||
} from "@/app/chat/stores/useChatSessionStore";
|
||||
} from "@/app/app/stores/useChatSessionStore";
|
||||
import {
|
||||
handleCopy,
|
||||
convertMarkdownTablesToTsv,
|
||||
} from "@/app/chat/message/copyingUtils";
|
||||
import MessageSwitcher from "@/app/chat/message/MessageSwitcher";
|
||||
import { BlinkingDot } from "@/app/chat/message/BlinkingDot";
|
||||
} from "@/app/app/message/copyingUtils";
|
||||
import MessageSwitcher from "@/app/app/message/MessageSwitcher";
|
||||
import { BlinkingDot } from "@/app/app/message/BlinkingDot";
|
||||
import {
|
||||
getTextContent,
|
||||
isActualToolCallPacket,
|
||||
@@ -43,19 +43,19 @@ import {
|
||||
isFinalAnswerComing,
|
||||
isStreamingComplete,
|
||||
isToolPacket,
|
||||
} from "@/app/chat/services/packetUtils";
|
||||
import { removeThinkingTokens } from "@/app/chat/services/thinkingTokens";
|
||||
import { useMessageSwitching } from "@/app/chat/message/messageComponents/hooks/useMessageSwitching";
|
||||
import MultiToolRenderer from "@/app/chat/message/messageComponents/MultiToolRenderer";
|
||||
import { RendererComponent } from "@/app/chat/message/messageComponents/renderMessageComponent";
|
||||
import { parseToolKey } from "@/app/chat/message/messageComponents/toolDisplayHelpers";
|
||||
} from "@/app/app/services/packetUtils";
|
||||
import { removeThinkingTokens } from "@/app/app/services/thinkingTokens";
|
||||
import { useMessageSwitching } from "@/app/app/message/messageComponents/hooks/useMessageSwitching";
|
||||
import MultiToolRenderer from "@/app/app/message/messageComponents/MultiToolRenderer";
|
||||
import { RendererComponent } from "@/app/app/message/messageComponents/renderMessageComponent";
|
||||
import { parseToolKey } from "@/app/app/message/messageComponents/toolDisplayHelpers";
|
||||
import AgentAvatar from "@/refresh-components/avatars/AgentAvatar";
|
||||
import IconButton from "@/refresh-components/buttons/IconButton";
|
||||
import CopyIconButton from "@/refresh-components/buttons/CopyIconButton";
|
||||
import LLMPopover from "@/refresh-components/popovers/LLMPopover";
|
||||
import { parseLlmDescriptor } from "@/lib/llm/utils";
|
||||
import { LlmDescriptor, LlmManager } from "@/lib/hooks";
|
||||
import { Message } from "@/app/chat/interfaces";
|
||||
import { Message } from "@/app/app/interfaces";
|
||||
import { useCreateModal } from "@/refresh-components/contexts/ModalContext";
|
||||
import FeedbackModal, {
|
||||
FeedbackModalProps,
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useMemo, useEffect, JSX } from "react";
|
||||
import {
|
||||
FiCheckCircle,
|
||||
@@ -12,7 +14,7 @@ import {
|
||||
PacketType,
|
||||
SearchToolPacket,
|
||||
StopReason,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import { FullChatState, RendererResult } from "./interfaces";
|
||||
import { RendererComponent } from "./renderMessageComponent";
|
||||
import { isToolPacket } from "../../services/packetUtils";
|
||||
@@ -32,8 +34,8 @@ import {
|
||||
constructCurrentSearchState,
|
||||
} from "./renderers/SearchToolRenderer";
|
||||
import { SvgChevronDown, SvgChevronDownSmall, SvgXCircle } from "@opal/icons";
|
||||
import { LoadingSpinner } from "../../chat_search/LoadingSpinner";
|
||||
import SimpleTooltip from "@/refresh-components/SimpleTooltip";
|
||||
import SimpleLoader from "@/refresh-components/loaders/SimpleLoader";
|
||||
|
||||
enum DisplayType {
|
||||
REGULAR = "regular",
|
||||
@@ -269,7 +271,7 @@ function ParallelToolTabs({
|
||||
>
|
||||
{tab.name}
|
||||
</span>
|
||||
{isLoading && <LoadingSpinner size="small" />}
|
||||
{isLoading && <SimpleLoader />}
|
||||
{tab.isComplete && !isLoading && tab.hasError && (
|
||||
<FiXCircle
|
||||
className={cn(
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Packet } from "@/app/chat/services/streamingModels";
|
||||
import { Packet } from "@/app/app/services/streamingModels";
|
||||
|
||||
// Control the rate of packet streaming (packets per second)
|
||||
const PACKET_DELAY_MS = 10;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Packet } from "@/app/chat/services/streamingModels";
|
||||
import { Packet } from "@/app/app/services/streamingModels";
|
||||
import { useMemo, useState, useCallback, useEffect } from "react";
|
||||
import { useRef } from "react";
|
||||
import { getToolKey, parseToolKey } from "../toolDisplayHelpers";
|
||||
@@ -5,14 +5,14 @@ import remarkMath from "remark-math";
|
||||
import rehypeHighlight from "rehype-highlight";
|
||||
import rehypeKatex from "rehype-katex";
|
||||
import "katex/dist/katex.min.css";
|
||||
import "@/app/chat/message/custom-code-styles.css";
|
||||
import { FullChatState } from "@/app/chat/message/messageComponents/interfaces";
|
||||
import "@/app/app/message/custom-code-styles.css";
|
||||
import { FullChatState } from "@/app/app/message/messageComponents/interfaces";
|
||||
import {
|
||||
MemoizedAnchor,
|
||||
MemoizedParagraph,
|
||||
} from "@/app/chat/message/MemoizedTextComponents";
|
||||
import { extractCodeText, preprocessLaTeX } from "@/app/chat/message/codeUtils";
|
||||
import { CodeBlock } from "@/app/chat/message/CodeBlock";
|
||||
} from "@/app/app/message/MemoizedTextComponents";
|
||||
import { extractCodeText, preprocessLaTeX } from "@/app/app/message/codeUtils";
|
||||
import { CodeBlock } from "@/app/app/message/CodeBlock";
|
||||
import { transformLinkUri, cn } from "@/lib/utils";
|
||||
|
||||
/**
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
import { MessageRenderer } from "../interfaces";
|
||||
import { truncateString } from "@/lib/utils";
|
||||
import { OnyxDocument } from "@/lib/search/interfaces";
|
||||
import { SourceChip2 } from "@/app/chat/components/SourceChip2";
|
||||
import { SourceChip2 } from "@/app/app/components/SourceChip2";
|
||||
import { BlinkingDot } from "../../BlinkingDot";
|
||||
import { clearTimeoutRefs } from "../timing";
|
||||
|
||||
@@ -5,12 +5,12 @@ import {
|
||||
PythonToolStart,
|
||||
PythonToolDelta,
|
||||
SectionEnd,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import {
|
||||
MessageRenderer,
|
||||
RenderType,
|
||||
} from "@/app/chat/message/messageComponents/interfaces";
|
||||
import { CodeBlock } from "@/app/chat/message/CodeBlock";
|
||||
} from "@/app/app/message/messageComponents/interfaces";
|
||||
import { CodeBlock } from "@/app/app/message/CodeBlock";
|
||||
import hljs from "highlight.js/lib/core";
|
||||
import python from "highlight.js/lib/languages/python";
|
||||
import { SvgCode } from "@opal/icons";
|
||||
@@ -10,12 +10,13 @@ import {
|
||||
} from "../../../services/streamingModels";
|
||||
import { MessageRenderer, RendererResult } from "../interfaces";
|
||||
import { truncateString } from "@/lib/utils";
|
||||
import { SourceChip2 } from "@/app/chat/components/SourceChip2";
|
||||
import { SourceChip2 } from "@/app/app/components/SourceChip2";
|
||||
import { BlinkingDot } from "../../BlinkingDot";
|
||||
import { OnyxDocument } from "@/lib/search/interfaces";
|
||||
import { ResultIcon } from "@/components/chat/sources/SourceCard";
|
||||
import { IconType } from "react-icons";
|
||||
import { OnyxIconType } from "@/components/icons/icons";
|
||||
import { WebResultIcon } from "@/components/WebResultIcon";
|
||||
import { SourceIcon } from "@/components/SourceIcon";
|
||||
|
||||
const MAX_TITLE_LENGTH = 25;
|
||||
|
||||
@@ -37,6 +38,19 @@ export interface SearchState {
|
||||
isInternetSearch: boolean;
|
||||
}
|
||||
|
||||
const ResultIcon = ({ doc, size }: { doc: OnyxDocument; size: number }) => {
|
||||
return (
|
||||
<div className="flex-none">
|
||||
{" "}
|
||||
{doc.is_internet || doc.source_type === "web" ? (
|
||||
<WebResultIcon size={size} url={doc.link} />
|
||||
) : (
|
||||
<SourceIcon iconSize={size} sourceType={doc.source_type} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const constructCurrentSearchState = (
|
||||
packets: SearchToolPacket[]
|
||||
): SearchState => {
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React, { FunctionComponent, useMemo, useCallback } from "react";
|
||||
import { StopReason } from "@/app/chat/services/streamingModels";
|
||||
import { StopReason } from "@/app/app/services/streamingModels";
|
||||
import { FullChatState } from "../interfaces";
|
||||
import { TurnGroup, TransformedStep } from "./transformers";
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -19,18 +19,18 @@ import {
|
||||
useTimelineExpansion,
|
||||
useTimelineMetrics,
|
||||
useTimelineHeader,
|
||||
} from "@/app/chat/message/messageComponents/timeline/hooks";
|
||||
} from "@/app/app/message/messageComponents/timeline/hooks";
|
||||
import {
|
||||
isResearchAgentPackets,
|
||||
stepSupportsCompact,
|
||||
} from "@/app/chat/message/messageComponents/timeline/packetHelpers";
|
||||
} from "@/app/app/message/messageComponents/timeline/packetHelpers";
|
||||
import {
|
||||
StreamingHeader,
|
||||
CollapsedHeader,
|
||||
ExpandedHeader,
|
||||
StoppedHeader,
|
||||
ParallelStreamingHeader,
|
||||
} from "@/app/chat/message/messageComponents/timeline/headers";
|
||||
} from "@/app/app/message/messageComponents/timeline/headers";
|
||||
|
||||
// =============================================================================
|
||||
// TimelineStep Component - Memoized to prevent re-renders
|
||||
@@ -6,7 +6,7 @@ import React, {
|
||||
useCallback,
|
||||
FunctionComponent,
|
||||
} from "react";
|
||||
import { StopReason } from "@/app/chat/services/streamingModels";
|
||||
import { StopReason } from "@/app/app/services/streamingModels";
|
||||
import { FullChatState } from "../interfaces";
|
||||
import { TurnGroup } from "./transformers";
|
||||
import { getToolName, getToolIcon } from "../toolDisplayHelpers";
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
import Tabs from "@/refresh-components/Tabs";
|
||||
import { SvgBranch } from "@opal/icons";
|
||||
import { StepContainer } from "./StepContainer";
|
||||
import { isResearchAgentPackets } from "@/app/chat/message/messageComponents/timeline/packetHelpers";
|
||||
import { isResearchAgentPackets } from "@/app/app/message/messageComponents/timeline/packetHelpers";
|
||||
import { IconProps } from "@/components/icons/icons";
|
||||
|
||||
export interface ParallelTimelineTabsProps {
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, JSX } from "react";
|
||||
import { Packet, StopReason } from "@/app/chat/services/streamingModels";
|
||||
import { Packet, StopReason } from "@/app/app/services/streamingModels";
|
||||
import { FullChatState, RenderType, RendererResult } from "../interfaces";
|
||||
import { findRenderer } from "../renderMessageComponent";
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from "react";
|
||||
import { SvgExpand } from "@opal/icons";
|
||||
import Button from "@/refresh-components/buttons/Button";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import type { UniqueTool } from "@/app/chat/message/messageComponents/timeline/hooks";
|
||||
import type { UniqueTool } from "@/app/app/message/messageComponents/timeline/hooks";
|
||||
|
||||
export interface CollapsedHeaderProps {
|
||||
uniqueTools: UniqueTool[];
|
||||
@@ -10,15 +10,15 @@ import {
|
||||
Stop,
|
||||
SearchToolStart,
|
||||
CustomToolStart,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
import { CitationMap } from "@/app/chat/interfaces";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import { CitationMap } from "@/app/app/interfaces";
|
||||
import { OnyxDocument } from "@/lib/search/interfaces";
|
||||
import {
|
||||
isActualToolCallPacket,
|
||||
isToolPacket,
|
||||
isDisplayPacket,
|
||||
} from "@/app/chat/services/packetUtils";
|
||||
import { parseToolKey } from "@/app/chat/message/messageComponents/toolDisplayHelpers";
|
||||
} from "@/app/app/services/packetUtils";
|
||||
import { parseToolKey } from "@/app/app/message/messageComponents/toolDisplayHelpers";
|
||||
|
||||
// Re-export parseToolKey for consumers that import from this module
|
||||
export { parseToolKey };
|
||||
@@ -3,20 +3,20 @@ import {
|
||||
Packet,
|
||||
StreamingCitation,
|
||||
StopReason,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
import { CitationMap } from "@/app/chat/interfaces";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import { CitationMap } from "@/app/app/interfaces";
|
||||
import { OnyxDocument } from "@/lib/search/interfaces";
|
||||
import {
|
||||
ProcessorState,
|
||||
GroupedPacket,
|
||||
createInitialState,
|
||||
processPackets,
|
||||
} from "@/app/chat/message/messageComponents/timeline/hooks/packetProcessor";
|
||||
} from "@/app/app/message/messageComponents/timeline/hooks/packetProcessor";
|
||||
import {
|
||||
transformPacketGroups,
|
||||
groupStepsByTurn,
|
||||
TurnGroup,
|
||||
} from "@/app/chat/message/messageComponents/timeline/transformers";
|
||||
} from "@/app/app/message/messageComponents/timeline/transformers";
|
||||
|
||||
export interface UsePacketProcessorResult {
|
||||
// Data
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
SearchToolPacket,
|
||||
StopReason,
|
||||
CustomToolStart,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
import { constructCurrentSearchState } from "@/app/chat/message/messageComponents/timeline/renderers/search/searchStateUtils";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import { constructCurrentSearchState } from "@/app/app/message/messageComponents/timeline/renderers/search/searchStateUtils";
|
||||
|
||||
export interface TimelineHeaderResult {
|
||||
headerText: string;
|
||||
@@ -2,12 +2,12 @@ import { useMemo } from "react";
|
||||
import {
|
||||
TurnGroup,
|
||||
TransformedStep,
|
||||
} from "@/app/chat/message/messageComponents/timeline/transformers";
|
||||
import { getToolIconByName } from "@/app/chat/message/messageComponents/toolDisplayHelpers";
|
||||
} from "@/app/app/message/messageComponents/timeline/transformers";
|
||||
import { getToolIconByName } from "@/app/app/message/messageComponents/toolDisplayHelpers";
|
||||
import {
|
||||
isResearchAgentPackets,
|
||||
stepSupportsCompact,
|
||||
} from "@/app/chat/message/messageComponents/timeline/packetHelpers";
|
||||
} from "@/app/app/message/messageComponents/timeline/packetHelpers";
|
||||
|
||||
export interface UniqueTool {
|
||||
key: string;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Packet, PacketType } from "@/app/chat/services/streamingModels";
|
||||
import { Packet, PacketType } from "@/app/app/services/streamingModels";
|
||||
|
||||
// Packet types with renderers supporting compact mode
|
||||
export const COMPACT_SUPPORTED_PACKET_TYPES = new Set<PacketType>([
|
||||
@@ -5,12 +5,12 @@ import {
|
||||
PythonToolStart,
|
||||
PythonToolDelta,
|
||||
SectionEnd,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import {
|
||||
MessageRenderer,
|
||||
RenderType,
|
||||
} from "@/app/chat/message/messageComponents/interfaces";
|
||||
import { CodeBlock } from "@/app/chat/message/CodeBlock";
|
||||
} from "@/app/app/message/messageComponents/interfaces";
|
||||
import { CodeBlock } from "@/app/app/message/CodeBlock";
|
||||
import hljs from "highlight.js/lib/core";
|
||||
import python from "highlight.js/lib/languages/python";
|
||||
import { SvgTerminal } from "@opal/icons";
|
||||
@@ -4,15 +4,15 @@ import { FiList } from "react-icons/fi";
|
||||
import {
|
||||
DeepResearchPlanPacket,
|
||||
PacketType,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import {
|
||||
MessageRenderer,
|
||||
FullChatState,
|
||||
} from "@/app/chat/message/messageComponents/interfaces";
|
||||
import { usePacketAnimationAndCollapse } from "@/app/chat/message/messageComponents/hooks/usePacketAnimationAndCollapse";
|
||||
} from "@/app/app/message/messageComponents/interfaces";
|
||||
import { usePacketAnimationAndCollapse } from "@/app/app/message/messageComponents/hooks/usePacketAnimationAndCollapse";
|
||||
import MinimalMarkdown from "@/components/chat/MinimalMarkdown";
|
||||
import ExpandableTextDisplay from "@/refresh-components/texts/ExpandableTextDisplay";
|
||||
import { mutedTextMarkdownComponents } from "@/app/chat/message/messageComponents/timeline/renderers/sharedMarkdownComponents";
|
||||
import { mutedTextMarkdownComponents } from "@/app/app/message/messageComponents/timeline/renderers/sharedMarkdownComponents";
|
||||
|
||||
/**
|
||||
* Renderer for deep research plan packets.
|
||||
@@ -15,19 +15,19 @@ import {
|
||||
ResearchAgentPacket,
|
||||
ResearchAgentStart,
|
||||
IntermediateReportDelta,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import {
|
||||
MessageRenderer,
|
||||
FullChatState,
|
||||
} from "@/app/chat/message/messageComponents/interfaces";
|
||||
import { getToolName } from "@/app/chat/message/messageComponents/toolDisplayHelpers";
|
||||
import { StepContainer } from "@/app/chat/message/messageComponents/timeline/StepContainer";
|
||||
} from "@/app/app/message/messageComponents/interfaces";
|
||||
import { getToolName } from "@/app/app/message/messageComponents/toolDisplayHelpers";
|
||||
import { StepContainer } from "@/app/app/message/messageComponents/timeline/StepContainer";
|
||||
import {
|
||||
TimelineRendererComponent,
|
||||
TimelineRendererResult,
|
||||
} from "@/app/chat/message/messageComponents/timeline/TimelineRendererComponent";
|
||||
} from "@/app/app/message/messageComponents/timeline/TimelineRendererComponent";
|
||||
import ExpandableTextDisplay from "@/refresh-components/texts/ExpandableTextDisplay";
|
||||
import { useMarkdownRenderer } from "@/app/chat/message/messageComponents/markdownUtils";
|
||||
import { useMarkdownRenderer } from "@/app/app/message/messageComponents/markdownUtils";
|
||||
|
||||
interface NestedToolGroup {
|
||||
sub_turn_index: number;
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from "react";
|
||||
import { FiLink } from "react-icons/fi";
|
||||
import { FetchToolPacket } from "@/app/chat/services/streamingModels";
|
||||
import { FetchToolPacket } from "@/app/app/services/streamingModels";
|
||||
import {
|
||||
MessageRenderer,
|
||||
RenderType,
|
||||
} from "@/app/chat/message/messageComponents/interfaces";
|
||||
import { BlinkingDot } from "@/app/chat/message/BlinkingDot";
|
||||
} from "@/app/app/message/messageComponents/interfaces";
|
||||
import { BlinkingDot } from "@/app/app/message/BlinkingDot";
|
||||
import { OnyxDocument } from "@/lib/search/interfaces";
|
||||
import { ValidSources } from "@/lib/types";
|
||||
import { SearchChipList, SourceInfo } from "../search/SearchChipList";
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
FetchToolPacket,
|
||||
FetchToolUrls,
|
||||
FetchToolDocuments,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import { OnyxDocument } from "@/lib/search/interfaces";
|
||||
|
||||
export const INITIAL_URLS_TO_SHOW = 3;
|
||||
@@ -10,14 +10,14 @@ import {
|
||||
PacketType,
|
||||
ReasoningDelta,
|
||||
ReasoningPacket,
|
||||
} from "@/app/chat/services/streamingModels";
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import {
|
||||
MessageRenderer,
|
||||
FullChatState,
|
||||
} from "@/app/chat/message/messageComponents/interfaces";
|
||||
} from "@/app/app/message/messageComponents/interfaces";
|
||||
import MinimalMarkdown from "@/components/chat/MinimalMarkdown";
|
||||
import ExpandableTextDisplay from "@/refresh-components/texts/ExpandableTextDisplay";
|
||||
import { mutedTextMarkdownComponents } from "@/app/chat/message/messageComponents/timeline/renderers/sharedMarkdownComponents";
|
||||
import { mutedTextMarkdownComponents } from "@/app/app/message/messageComponents/timeline/renderers/sharedMarkdownComponents";
|
||||
import { SvgCircle } from "@opal/icons";
|
||||
|
||||
const THINKING_MIN_DURATION_MS = 500; // 0.5 second minimum for "Thinking" state
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from "react";
|
||||
import { SvgSearch, SvgGlobe, SvgSearchMenu } from "@opal/icons";
|
||||
import { SearchToolPacket } from "@/app/chat/services/streamingModels";
|
||||
import { SearchToolPacket } from "@/app/app/services/streamingModels";
|
||||
import {
|
||||
MessageRenderer,
|
||||
RenderType,
|
||||
} from "@/app/chat/message/messageComponents/interfaces";
|
||||
import { BlinkingDot } from "@/app/chat/message/BlinkingDot";
|
||||
} from "@/app/app/message/messageComponents/interfaces";
|
||||
import { BlinkingDot } from "@/app/app/message/BlinkingDot";
|
||||
import { OnyxDocument } from "@/lib/search/interfaces";
|
||||
import { ValidSources } from "@/lib/types";
|
||||
import { SearchChipList, SourceInfo } from "./SearchChipList";
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user