diff --git a/src/common/beam/BeamView.tsx b/src/common/beam/BeamView.tsx index cc026f9c0..99dac24e9 100644 --- a/src/common/beam/BeamView.tsx +++ b/src/common/beam/BeamView.tsx @@ -29,7 +29,7 @@ export function BeamView(props: { const { /* root */ editInputHistoryMessage, /* scatter */ setRayCount, startScatteringAll, stopScatteringAll, - /* gather */ setFusionIndex, setFusionLlmId, startFusion, stopFusion, + /* gather */ setFusionIndex, setFusionLlmId, fusionCustomize, fusionStart, fusionStop, } = props.beamStore.getState(); const { /* root */ inputHistory, inputIssues, inputReady, @@ -140,8 +140,9 @@ export function BeamView(props: { isMobile={props.isMobile} fusionIndex={fusionIndex} setFusionIndex={setFusionIndex} - onStartFusion={startFusion} - onStopFusion={stopFusion} + onFusionCustomize={fusionCustomize} + onFusionStart={fusionStart} + onFusionStop={fusionStop} /> {/* Fusion Output */} diff --git a/src/common/beam/gather/BeamGatherConfig.tsx b/src/common/beam/gather/BeamGatherConfig.tsx index 25595fb2d..e67dc88ca 100644 --- a/src/common/beam/gather/BeamGatherConfig.tsx +++ b/src/common/beam/gather/BeamGatherConfig.tsx @@ -6,8 +6,10 @@ import { Box, Typography } from '@mui/joy'; import { ChatMessageMemo } from '../../../apps/chat/components/message/ChatMessage'; import { createDMessage } from '~/common/state/store-chats'; -import { BeamStoreApi, useBeamStore } from '~/common/beam/store-beam.hooks'; -import { GATHER_DEBUG_NONCUSTOM } from '~/common/beam/beam.config'; + +import type { TInstruction } from './beam.gather'; +import { BeamStoreApi, useBeamStore } from '../store-beam.hooks'; +import { GATHER_DEBUG_NONCUSTOM } from '../beam.config'; const gatherConfigWrapperSx: SxProps = { @@ -34,6 +36,79 @@ const configChatInstructionSx: SxProps = { flex: 1, }; +function InstructionWrapper(props: { children: React.ReactNode }) { + return ( + + {props.children} + + ); +} + + +function ReadOnlyInstruction(props: { instruction: TInstruction, isMobile: boolean }) { + const { instruction } = props; + + // render 'chat-generate' + if (instruction.type === 'chat-generate') { + return ( + + + + System Prompt: + + + + + + User Prompt: + + + + + ); + } + + // render 'user-input-checklist' + if (instruction.type === 'user-input-checklist') { + return ( + + + + Checklist: + + + + + ); + } + + return ( + + + Unknown Instruction + + + ); +} + export function BeamGatherConfig(props: { beamStore: BeamStoreApi @@ -41,7 +116,7 @@ export function BeamGatherConfig(props: { }) { // state - const [viewInstructionIndex, setViewInstructionIndex] = React.useState(0); + // const [viewInstructionIndex, setViewInstructionIndex] = React.useState(0); // external state const fusion = useBeamStore(props.beamStore, store => { @@ -49,64 +124,23 @@ export function BeamGatherConfig(props: { return (fusion?.isEditable || GATHER_DEBUG_NONCUSTOM) ? fusion : null; }); - - // [effect] sync the fusion program index to the viewInstructionIndex - React.useEffect(() => { - fusion && setViewInstructionIndex(fusion.currentInstructionIndex); - }, [fusion]); - + // // [effect] sync the fusion program index to the viewInstructionIndex + // React.useEffect(() => { + // fusion && setViewInstructionIndex(fusion.currentInstructionIndex); + // }, [fusion]); // derived state - const instruction = React.useMemo(() => { - return fusion?.instructions[viewInstructionIndex] ?? null; - }, [fusion, viewInstructionIndex]); + // const instructions = React.useMemo(() => { + // return fusion?.instructions ?? null; + // }, [fusion]); + const instructions = fusion?.instructions ?? null; - // render instruction - const instructionComponent = React.useMemo(() => { - if (instruction && instruction.type === 'chat-generate') { - return <> - {instruction.systemPrompt && ( - - - System Prompt: - - - - )} - {instruction.userPrompt && ( - - - User Prompt: - - - - - )} - ; - } - return null; - }, [instruction, props.isMobile]); - - - if (!instructionComponent) - return null; - - return ( + return !!instructions?.length ? ( - {instructionComponent} + {instructions.map((instruction, stepIndex) => + , + )} - ); + ) : null; } \ No newline at end of file diff --git a/src/common/beam/gather/BeamGatherPane.tsx b/src/common/beam/gather/BeamGatherPane.tsx index 4f2e0056f..ac220e608 100644 --- a/src/common/beam/gather/BeamGatherPane.tsx +++ b/src/common/beam/gather/BeamGatherPane.tsx @@ -1,9 +1,10 @@ import * as React from 'react'; import type { SxProps } from '@mui/joy/styles/types'; -import { Box, Button, ButtonGroup, FormControl, SvgIconProps, Typography } from '@mui/joy'; +import { Box, Button, ButtonGroup, FormControl, IconButton, SvgIconProps, Tooltip, Typography } from '@mui/joy'; import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome'; import AutoAwesomeOutlinedIcon from '@mui/icons-material/AutoAwesomeOutlined'; +import EditRoundedIcon from '@mui/icons-material/EditRounded'; import MergeRoundedIcon from '@mui/icons-material/MergeRounded'; import StopRoundedIcon from '@mui/icons-material/StopRounded'; @@ -15,7 +16,7 @@ import { useScrollToBottom } from '~/common/scroll-to-bottom/useScrollToBottom'; import { GATHER_COLOR } from '../beam.config'; import { beamPaneSx } from '../BeamCard'; -import { FUSION_PROGRAMS } from './beam.gather'; +import { FUSION_FACTORIES } from './beam.gather'; const mobileBeamGatherPane: SxProps = { @@ -47,21 +48,25 @@ export function BeamGatherPane(props: { gatherLlmIcon?: React.FunctionComponent, fusionIndex: number | null, setFusionIndex: (index: number | null) => void - onStartFusion: () => void, - onStopFusion: () => void, + onFusionCustomize: (index: number) => void, + onFusionStart: () => void, + onFusionStop: () => void, }) { // external state const { setStickToBottom } = useScrollToBottom(); // derived state - const { gatherCount, gatherEnabled, gatherBusy, setFusionIndex } = props; + const { gatherCount, gatherEnabled, gatherBusy, setFusionIndex, onFusionCustomize } = props; const handleFusionActivate = React.useCallback((idx: number, shiftPressed: boolean) => { setStickToBottom(true); setFusionIndex((idx !== props.fusionIndex || !shiftPressed) ? idx : null); }, [props.fusionIndex, setFusionIndex, setStickToBottom]); + const handleFusionCustomize = React.useCallback(() => { + props.fusionIndex !== null && onFusionCustomize(props.fusionIndex); + }, [onFusionCustomize, props.fusionIndex]); const Icon = props.gatherLlmIcon || (gatherBusy ? AutoAwesomeIcon : AutoAwesomeOutlinedIcon); @@ -85,10 +90,13 @@ export function BeamGatherPane(props: { {/* Method */} - Method} sx={{ mb: '0.25rem' /* orig: 6px */ }} /> - + Method} + sx={{ mb: '0.25rem' /* orig: 6px */ }} + /> + - {FUSION_PROGRAMS.map((fusion, idx) => { + {FUSION_FACTORIES.map((fusion, idx) => { const isActive = idx === props.fusionIndex; return (