From b9ba0ad7c9bf970f13a29431610c3cf186192c80 Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Tue, 16 Jul 2024 17:52:51 -0700 Subject: [PATCH] DEV MODE. Visible/usable only on localhost:3xxx --- .../layout-menu/ChatPageMenuItems.tsx | 42 +++++++++++++++++-- src/apps/settings-modal/UxLabsSettings.tsx | 10 +++++ src/common/state/store-ux-labs.ts | 23 +++++++++- src/common/util/pwaUtils.ts | 1 + src/modules/aix/client/aix.client.ts | 7 +++- 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/apps/chat/components/layout-menu/ChatPageMenuItems.tsx b/src/apps/chat/components/layout-menu/ChatPageMenuItems.tsx index d3508e377..997809ef3 100644 --- a/src/apps/chat/components/layout-menu/ChatPageMenuItems.tsx +++ b/src/apps/chat/components/layout-menu/ChatPageMenuItems.tsx @@ -1,11 +1,12 @@ import * as React from 'react'; -import { Box, IconButton, ListDivider, ListItemDecorator, MenuItem, Switch, Tooltip } from '@mui/joy'; +import { Box, IconButton, ListDivider, ListItemDecorator, MenuItem, Switch, Tooltip, Typography } from '@mui/joy'; import AddIcon from '@mui/icons-material/Add'; import CheckBoxOutlineBlankOutlinedIcon from '@mui/icons-material/CheckBoxOutlineBlankOutlined'; import CheckBoxOutlinedIcon from '@mui/icons-material/CheckBoxOutlined'; import ClearIcon from '@mui/icons-material/Clear'; import CompressIcon from '@mui/icons-material/Compress'; +import EngineeringIcon from '@mui/icons-material/Engineering'; import ForkRightIcon from '@mui/icons-material/ForkRight'; import HorizontalSplitIcon from '@mui/icons-material/HorizontalSplit'; import HorizontalSplitOutlinedIcon from '@mui/icons-material/HorizontalSplitOutlined'; @@ -14,7 +15,10 @@ import VerticalSplitIcon from '@mui/icons-material/VerticalSplit'; import VerticalSplitOutlinedIcon from '@mui/icons-material/VerticalSplitOutlined'; import type { DConversationId } from '~/common/stores/chat/chat.conversation'; +import { GoodModal } from '~/common/components/GoodModal'; import { KeyStroke } from '~/common/components/KeyStroke'; +import { devMode_AixLastDispatchRequestBody } from '~/modules/aix/client/aix.client'; // [DEV MODE] +import { useLabsDevMode } from '~/common/state/store-ux-labs'; import { useOptimaDrawers } from '~/common/layout/optima/useOptimaDrawers'; import { useChatShowSystemMessages } from '../../store-app-chat'; @@ -38,6 +42,7 @@ export function ChatPageMenuItems(props: { const { closePageMenu } = useOptimaDrawers(); const { canAddPane, isMultiPane, duplicateFocusedPane, removeOtherPanes } = usePaneDuplicateOrClose(); const [showSystemMessages, setShowSystemMessages] = useChatShowSystemMessages(); + const labsDevMode = useLabsDevMode(); const handleIncreaseMultiPane = React.useCallback((event?: React.MouseEvent) => { @@ -87,16 +92,35 @@ export function ChatPageMenuItems(props: { const handleToggleSystemMessages = () => setShowSystemMessages(!showSystemMessages); + // [DEV MODE] + + const [devModeDialog, setDevModeDialog] = React.useState(null); + + const handleAixShowLastRequest = React.useCallback(() => { + setDevModeDialog(( + setDevModeDialog(null)} + title='Aix: Last Dispach Request Body' + sx={{ width: '80vw', height: '80vh' }} + > + + {devMode_AixLastDispatchRequestBody || 'Contents will be shown after the next request.'} + + + )); + }, []); + + return <> - {/* System Message(s) */} System messages - {/* Un /Split */} + {/* Pane management: Un/Split */} {props.isMobile ? (isMultiPane ? : ) @@ -137,6 +161,15 @@ export function ChatPageMenuItems(props: { Compress ... + {labsDevMode && } + + {labsDevMode && ( + + + AIX: Show Last Request... + + )} + @@ -147,5 +180,8 @@ export function ChatPageMenuItems(props: { + {/* [DEV MODE] Show any dialog, if present */} + {devModeDialog} + ; } \ No newline at end of file diff --git a/src/apps/settings-modal/UxLabsSettings.tsx b/src/apps/settings-modal/UxLabsSettings.tsx index 99522cdc7..7336d722b 100644 --- a/src/apps/settings-modal/UxLabsSettings.tsx +++ b/src/apps/settings-modal/UxLabsSettings.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import { FormControl, Typography } from '@mui/joy'; import AddAPhotoIcon from '@mui/icons-material/AddAPhoto'; +import EngineeringIcon from '@mui/icons-material/Engineering'; import LocalAtmOutlinedIcon from '@mui/icons-material/LocalAtmOutlined'; import ScreenshotMonitorIcon from '@mui/icons-material/ScreenshotMonitor'; import SpeedIcon from '@mui/icons-material/Speed'; @@ -10,6 +11,7 @@ import TitleIcon from '@mui/icons-material/Title'; import { FormLabelStart } from '~/common/components/forms/FormLabelStart'; import { FormSwitchControl } from '~/common/components/forms/FormSwitchControl'; import { Link } from '~/common/components/Link'; +import { isDevModeLocalhost } from '~/common/util/pwaUtils'; import { useIsMobile } from '~/common/components/useMatchMedia'; import { useUXLabsStore } from '~/common/state/store-ux-labs'; @@ -28,6 +30,7 @@ export function UxLabsSettings() { labsChatBarAlt, setLabsChatBarAlt, labsHighPerformance, setLabsHighPerformance, labsShowCost, setLabsShowCost, + labsDevMode, setLabsDevMode, } = useUXLabsStore(); return <> @@ -59,6 +62,13 @@ export function UxLabsSettings() { checked={labsShowCost} onChange={setLabsShowCost} /> + {isDevModeLocalhost && ( + [DEV Mode]} description={labsDevMode ? 'Enabled' : 'Disabled'} + checked={labsDevMode} onChange={setLabsDevMode} + /> + )} + {/* Other Graduated (removed or backlog): - Draw App diff --git a/src/common/state/store-ux-labs.ts b/src/common/state/store-ux-labs.ts index 49cc6e473..4ab3bc021 100644 --- a/src/common/state/store-ux-labs.ts +++ b/src/common/state/store-ux-labs.ts @@ -1,6 +1,8 @@ import { create } from 'zustand'; import { persist } from 'zustand/middleware'; +import { isDevModeLocalhost } from '~/common/util/pwaUtils'; + // UX Labs Experiments @@ -24,6 +26,11 @@ interface UXLabsStore { labsShowCost: boolean; setLabsShowCost: (labsShowCost: boolean) => void; + // [DEV MODE] only shown on localhost + + labsDevMode: boolean; + setLabsDevMode: (labsDevMode: boolean) => void; + } export const useUXLabsStore = create()( @@ -45,6 +52,11 @@ export const useUXLabsStore = create()( labsShowCost: true, // release 1.16.0 with this enabled by default setLabsShowCost: (labsShowCost: boolean) => set({ labsShowCost }), + // [DEV MODE] - maybe move them from here + + labsDevMode: false, + setLabsDevMode: (labsDevMode: boolean) => set({ labsDevMode }), + }), { name: 'app-ux-labs', @@ -58,10 +70,19 @@ export const useUXLabsStore = create()( return { ...state, labsAttachScreenCapture: true }; return state; }, + }, ), ); export function getUXLabsHighPerformance() { return useUXLabsStore.getState().labsHighPerformance; -} \ No newline at end of file +} + +export function useLabsDevMode() { + return useUXLabsStore((state) => state.labsDevMode) && isDevModeLocalhost; +} + +export function getLabsDevMode() { + return useUXLabsStore.getState().labsDevMode && isDevModeLocalhost; +} diff --git a/src/common/util/pwaUtils.ts b/src/common/util/pwaUtils.ts index 9e6465e5d..7298d9339 100644 --- a/src/common/util/pwaUtils.ts +++ b/src/common/util/pwaUtils.ts @@ -2,6 +2,7 @@ import { Brand } from '../app.config'; // assume these won't change during the application lifetime export const isBrowser = typeof window !== 'undefined'; +export const isDevModeLocalhost = clientHostName().includes('localhost:300'); // this sort of detection is brittle, but we use it for very optional features const safeUA = isBrowser ? window.navigator?.userAgent || '' : ''; diff --git a/src/modules/aix/client/aix.client.ts b/src/modules/aix/client/aix.client.ts index a82cbe40c..bef85b8fe 100644 --- a/src/modules/aix/client/aix.client.ts +++ b/src/modules/aix/client/aix.client.ts @@ -3,6 +3,7 @@ import type { DLLMId } from '~/modules/llms/store-llms'; import { findVendorForLlmOrThrow } from '~/modules/llms/vendors/vendors.registry'; import { apiStream } from '~/common/util/trpc.client'; +import { getLabsDevMode } from '~/common/state/store-ux-labs'; // NOTE: pay particular attention to the "import type", as this is importing from the server-side Zod definitions import type { AixAPI_Access, AixAPI_ContextChatStream, AixAPI_Model, AixAPIChatGenerate_Request } from '~/modules/aix/server/aix.wiretypes'; @@ -68,6 +69,9 @@ function _aixModelFromLLMOptions(llmOptions: Record, debugLlmId: st } +export let devMode_AixLastDispatchRequestBody: string | null = null; + + /** * Client side chat generation, with streaming. This decodes the (text) streaming response from * our server streaming endpoint (plain text, not EventSource), and signals updates via a callback. @@ -89,7 +93,7 @@ async function _aixChatGenerateContent( ): Promise { const operation = await apiStream.aix.chatGenerateContent.mutate( - { access: aixAccess, model: aixModel, chatGenerate: aixChatGenerate, context: aixContext, streaming: true, _debugRequestBody: false }, + { access: aixAccess, model: aixModel, chatGenerate: aixChatGenerate, context: aixContext, streaming: true, _debugRequestBody: getLabsDevMode() }, { signal: abortSignal }, ); @@ -111,6 +115,7 @@ async function _aixChatGenerateContent( onUpdate({ textSoFar: incrementalText, typing: true }, false); } else if ('_debugClientPrint' in update) { console.log('_debugClientPrint:', update._debugClientPrint); + devMode_AixLastDispatchRequestBody = update._debugClientPrint; } else console.log('update:', update); }