Skip to content

Commit

Permalink
Inline Thinking Fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
enricoros committed Jan 23, 2025
1 parent ae8602a commit e6dd1f0
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/apps/chat/components/message/ChatMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ export function ChatMessage(props: {

onFragmentBlank={handleFragmentNew}
onFragmentDelete={handleFragmentDelete}
onFragmentReplace={handleFragmentReplace}
onFragmentReplace={!props.onMessageFragmentReplace ? undefined : handleFragmentReplace}
onMessageDelete={props.onMessageDelete ? handleOpsDelete : undefined}

onContextMenu={(props.onMessageFragmentReplace && ENABLE_CONTEXT_MENU) ? handleBlocksContextMenu : undefined}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import * as React from 'react';

import { Box, Chip, Typography } from '@mui/joy';
import AllInclusiveIcon from '@mui/icons-material/AllInclusive';
import TextFieldsIcon from '@mui/icons-material/TextFields';

import { useScaledTypographySx } from '~/modules/blocks/blocks.styles';

import { ConfirmationModal } from '~/common/components/modals/ConfirmationModal';
import { ExpanderControlledBox } from '~/common/components/ExpanderControlledBox';
import { adjustContentScaling, ContentScaling } from '~/common/app.theme';
import { useUIComplexityIsMinimal } from '~/common/state/store-ui';
import { createTextContentFragment, DMessageContentFragment, DMessageFragmentId } from '~/common/stores/chat/chat.fragments';
import { useOverlayComponents } from '~/common/layout/overlays/useOverlayComponents';


const _styles = {
Expand All @@ -15,8 +20,14 @@ const _styles = {
} as const,

chip: {
px: 1,
py: 0.25,
px: 1.5,
py: 0.375,
boxShadow: '0px 2px 4px -2px rgba(0, 0, 0, 0.25)',
} as const,

chipExpanded: {
px: 1.5,
py: 0.375,
} as const,

text: {
Expand All @@ -29,44 +40,94 @@ const _styles = {
// plain text style
overflowWrap: 'anywhere',
whiteSpace: 'break-spaces',

// layout
display: 'flex',
flexDirection: 'column',
} as const,

buttonInline: {
outline: 'none',
// borderRadius: 'sm',
// fontSize: 'xs',
} as const,

} as const;

export function BlockPartModelAux(props: {
fragmentId: DMessageFragmentId,
auxType: 'reasoning' | string,
auxText: string,
zenMode: boolean,
contentScaling: ContentScaling,
onFragmentReplace?: (fragmentId: DMessageFragmentId, newFragment: DMessageContentFragment) => void,
}) {

// state
const [expanded, setExpanded] = React.useState(false);

// external state
const zenMode = useUIComplexityIsMinimal();
const { showPromisedOverlay } = useOverlayComponents();

// memo
const scaledTypographySx = useScaledTypographySx(adjustContentScaling(props.contentScaling, -1), false, false);
const textSx = React.useMemo(() => ({ ..._styles.text, ...scaledTypographySx }), [scaledTypographySx]);

let typeText = props.auxType === 'reasoning' ? 'Show Reasoning' : 'Show Auxiliary';
if (!zenMode && props.auxType === 'reasoning')
typeText = '🧠 ' + typeText;
let typeText = props.auxType === 'reasoning' ? 'Thought Process' : 'Auxiliary';


// handlers

const { onFragmentReplace } = props;
const showInline = !!onFragmentReplace;

const handleInline = React.useCallback(() => {
if (!onFragmentReplace) return;
showPromisedOverlay('chat-message-inline-aux', {}, ({ onResolve, onUserReject }) =>
<ConfirmationModal
open onClose={onUserReject} onPositive={() => onResolve(true)}
confirmationText={<>
Convert this {typeText.toLowerCase()} into regular message text?
<br />
It will become part of the message and can&apos;t be collapsed again.
</>}
positiveActionText='Convert'
/>,
).then(() => {
onFragmentReplace(props.fragmentId, createTextContentFragment(props.auxText));
}).catch(() => null /* ignore closure */);
}, [onFragmentReplace, props.auxText, props.fragmentId, showPromisedOverlay, typeText]);


// create up to 3 dots '.' based on the length of the auxText (1 dot per 100 characters)
// const dots = '.'.repeat(Math.floor(props.auxText.length / 100) % 5);

return <Box sx={_styles.block}>

{/* Chip to expand/collapse */}
<Chip
variant={expanded ? 'solid' : 'soft'}
size="sm"
onClick={() => setExpanded(on => !on)}
sx={_styles.chip}
>
{typeText}
</Chip>
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, alignItems: 'center', justifyContent: 'space-between' }}>
<Chip
variant={expanded ? 'solid' : 'outlined'}
size='sm'
onClick={() => setExpanded(on => !on)}
sx={expanded ? _styles.chipExpanded : _styles.chip}
startDecorator={<AllInclusiveIcon />}
>
{expanded ? '' : <>&nbsp;Show </>}{typeText}
</Chip>

{expanded && showInline && (
<Chip
variant='outlined'
size='sm'
onClick={!onFragmentReplace ? undefined : handleInline}
endDecorator={<TextFieldsIcon />}
sx={_styles.chipExpanded}
>
Make Regular Text
</Chip>
)}
</Box>

{/* Controlled Box */}
<ExpanderControlledBox expanded={expanded}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function ContentFragments(props: {

onFragmentBlank: () => void
onFragmentDelete: (fragmentId: DMessageFragmentId) => void,
onFragmentReplace: (fragmentId: DMessageFragmentId, newFragment: DMessageContentFragment) => void,
onFragmentReplace?: (fragmentId: DMessageFragmentId, newFragment: DMessageContentFragment) => void,
onMessageDelete?: () => void,

onContextMenu?: (event: React.MouseEvent) => void;
Expand Down Expand Up @@ -116,9 +116,12 @@ export function ContentFragments(props: {
return (
<BlockPartModelAux
key={fId}
fragmentId={fId}
auxType={part.aType}
auxText={part.aText}
zenMode={props.uiComplexityMode === 'minimal'}
contentScaling={props.contentScaling}
onFragmentReplace={props.onFragmentReplace}
/>
);
}
Expand Down
1 change: 1 addition & 0 deletions src/common/layout/overlays/store-layout-overlays.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type GlobalOverlayId = // string - disabled so we keep an orderliness
| 'chat-delete-confirmation'
| 'chat-reset-confirmation'
| 'chat-message-delete-confirmation'
| 'chat-message-inline-aux'
| 'livefile-overwrite'
| 'shortcuts-confirm-close'
| 'blocks-off-enhance-code'
Expand Down

0 comments on commit e6dd1f0

Please sign in to comment.