Skip to content

Commit 6c50227

Browse files
nl0claude
andauthored
Qurator: adjust styling for tool messages (#4572)
Co-authored-by: Claude <[email protected]>
1 parent 6885b9e commit 6c50227

File tree

2 files changed

+88
-30
lines changed

2 files changed

+88
-30
lines changed

catalog/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ where verb is one of
1818

1919
## Changes
2020

21+
- [Changed] Qurator: make tool messages less prominent ([#4572](https://github.com/quiltdata/quilt/pull/4572))
2122
- [Fixed] Qurator: Limit total search results contents context to 100k characters to avoid context window overflow ([#4573](https://github.com/quiltdata/quilt/pull/4573))
2223
- [Fixed] Empty directory upload on Bucket tab ([#4552](https://github.com/quiltdata/quilt/pull/4552))
2324
- [Changed] Improve handling of no results on packages tab ([#4539](https://github.com/quiltdata/quilt/pull/4539))

catalog/app/components/Assistant/UI/Chat/Chat.tsx

Lines changed: 87 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import cx from 'classnames'
22
import * as Eff from 'effect'
33
import * as React from 'react'
44
import * as M from '@material-ui/core'
5+
import * as Icons from '@material-ui/icons'
56

67
import JsonDisplay from 'components/JsonDisplay'
78
import Markdown from 'components/Markdown'
@@ -14,15 +15,15 @@ import Input from './Input'
1415

1516
const BG = {
1617
intense: M.colors.indigo[900],
17-
bright: M.colors.indigo[500],
18-
faint: M.colors.common.white,
18+
normal: M.colors.common.white,
19+
faint: M.colors.grey[600],
1920
}
2021

2122
const useMessageContainerStyles = M.makeStyles((t) => ({
2223
align_left: {},
2324
align_right: {},
2425
color_intense: {},
25-
color_bright: {},
26+
color_normal: {},
2627
color_faint: {},
2728
messageContainer: {
2829
display: 'flex',
@@ -46,13 +47,17 @@ const useMessageContainerStyles = M.makeStyles((t) => ({
4647
background: BG.intense,
4748
color: M.fade(t.palette.common.white, 0.8),
4849
},
49-
'$color_bright &': {
50-
background: BG.bright,
51-
color: t.palette.common.white,
50+
'$color_normal &': {
51+
background: BG.normal,
52+
color: t.palette.text.primary,
5253
},
5354
'$color_faint &': {
5455
background: BG.faint,
55-
color: t.palette.text.primary,
56+
color: t.palette.getContrastText(BG.faint),
57+
opacity: 0.5,
58+
'&:hover': {
59+
opacity: 1,
60+
},
5661
},
5762
'$align_right &': {
5863
borderBottomRightRadius: 0,
@@ -83,15 +88,15 @@ const useMessageContainerStyles = M.makeStyles((t) => ({
8388
}))
8489

8590
interface MessageContainerProps {
86-
color?: 'intense' | 'bright' | 'faint'
91+
color?: 'intense' | 'normal' | 'faint'
8792
align?: 'left' | 'right'
8893
children: React.ReactNode
8994
actions?: React.ReactNode
9095
timestamp?: Date
9196
}
9297

9398
function MessageContainer({
94-
color = 'faint',
99+
color = 'normal',
95100
align = 'left',
96101
children,
97102
actions,
@@ -131,6 +136,32 @@ const useMessageActionStyles = M.makeStyles({
131136
},
132137
})
133138

139+
const useToolMessageStyles = M.makeStyles((t) => ({
140+
header: {
141+
display: 'flex',
142+
alignItems: 'center',
143+
cursor: 'pointer',
144+
userSelect: 'none',
145+
'&:hover': {
146+
opacity: 0.8,
147+
},
148+
},
149+
icon: {
150+
fontSize: '1rem',
151+
color: 'inherit',
152+
},
153+
toolName: {
154+
marginLeft: t.spacing(1),
155+
marginRight: t.spacing(1),
156+
},
157+
spinner: {
158+
color: 'inherit',
159+
},
160+
details: {
161+
marginTop: t.spacing(1),
162+
},
163+
}))
164+
134165
interface MessageActionProps {
135166
children: React.ReactNode
136167
className?: string
@@ -154,6 +185,42 @@ interface ConversationStateProps {
154185
state: Model.Conversation.State['_tag']
155186
}
156187

188+
interface ToolMessageProps {
189+
name: string
190+
status?: 'success' | 'error' | 'running'
191+
details: Record<string, any>
192+
timestamp: Date
193+
actions?: React.ReactNode
194+
}
195+
196+
function ToolMessage({ name, status, details, timestamp, actions }: ToolMessageProps) {
197+
const classes = useToolMessageStyles()
198+
const [expanded, setExpanded] = React.useState(false)
199+
200+
const toggleExpanded = React.useCallback(() => {
201+
setExpanded((prev) => !prev)
202+
}, [])
203+
204+
return (
205+
<MessageContainer color="faint" timestamp={timestamp} actions={actions}>
206+
<div className={classes.header} onClick={toggleExpanded}>
207+
<Icons.Build className={classes.icon} />
208+
<span className={classes.toolName}>{name}</span>
209+
{status === 'success' && <Icons.CheckCircleOutline className={classes.icon} />}
210+
{status === 'error' && <Icons.ErrorOutline className={classes.icon} />}
211+
{status === 'running' && (
212+
<M.CircularProgress size={14} thickness={4} className={classes.spinner} />
213+
)}
214+
</div>
215+
<M.Collapse in={expanded}>
216+
<div className={classes.details}>
217+
<JsonDisplay defaultExpanded={2} name="details" value={details} />
218+
</div>
219+
</M.Collapse>
220+
</MessageContainer>
221+
)
222+
}
223+
157224
type MessageEventProps = ConversationDispatchProps &
158225
ConversationStateProps &
159226
ReturnType<typeof Model.Conversation.Event.Message>
@@ -174,7 +241,7 @@ function MessageEvent({
174241

175242
return (
176243
<MessageContainer
177-
color={role === 'user' ? 'intense' : 'faint'}
244+
color={role === 'user' ? 'intense' : 'normal'}
178245
align={role === 'user' ? 'right' : 'left'}
179246
actions={discard && <MessageAction onClick={discard}>discard</MessageAction>}
180247
timestamp={timestamp}
@@ -212,18 +279,13 @@ function ToolUseEvent({
212279
[toolUseId, input, result],
213280
)
214281
return (
215-
<MessageContainer
216-
color="bright"
282+
<ToolMessage
283+
name={name}
284+
status={result.status}
285+
details={details}
217286
timestamp={timestamp}
218287
actions={discard && <MessageAction onClick={discard}>discard</MessageAction>}
219-
>
220-
<span>
221-
Tool Use: <b>{name}</b> ({result.status})
222-
</span>
223-
<M.Box py={0.5}>
224-
<JsonDisplay name="details" value={details} />
225-
</M.Box>
226-
</MessageContainer>
288+
/>
227289
)
228290
}
229291

@@ -246,18 +308,13 @@ function ToolUseState({ timestamp, dispatch, calls }: ToolUseStateProps) {
246308
const names = Eff.Record.collect(calls, (_k, v) => v.name)
247309

248310
return (
249-
<MessageContainer
250-
color="bright"
311+
<ToolMessage
312+
name={names.join(', ')}
313+
status="running"
314+
details={details}
251315
timestamp={timestamp}
252316
actions={<MessageAction onClick={abort}>abort</MessageAction>}
253-
>
254-
<span>
255-
Tool Use: <b>{names.join(', ')}</b>
256-
</span>
257-
<M.Box py={0.5}>
258-
<JsonDisplay name="details" value={details} />
259-
</M.Box>
260-
</MessageContainer>
317+
/>
261318
)
262319
}
263320

0 commit comments

Comments
 (0)