Skip to content

Commit

Permalink
Qurator: use Bedrock for summarizing file content
Browse files Browse the repository at this point in the history
  • Loading branch information
fiskus committed Jun 12, 2024
1 parent b58a355 commit 51c769c
Show file tree
Hide file tree
Showing 25 changed files with 942 additions and 25 deletions.
91 changes: 91 additions & 0 deletions catalog/app/components/Chat/Chat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import * as React from 'react'
import * as M from '@material-ui/core'
import * as Lab from '@material-ui/lab'

Check warning on line 3 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L1-L3

Added lines #L1 - L3 were not covered by tests

import Skeleton from 'components/Skeleton'

Check warning on line 5 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L5

Added line #L5 was not covered by tests
import type * as AWS from 'utils/AWS'

import History from './History'
import Input from './Input'

Check warning on line 9 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L8-L9

Added lines #L8 - L9 were not covered by tests

const useStyles = M.makeStyles((t) => ({

Check warning on line 11 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L11

Added line #L11 was not covered by tests
root: {
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
overflow: 'hidden',
},
error: {
marginTop: t.spacing(2),
},
history: {
...t.typography.body1,
maxHeight: t.spacing(70),
overflowY: 'auto',
},
input: {
marginTop: t.spacing(2),
},
}))

const noMessages: AWS.Bedrock.Message[] = []

Check warning on line 31 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L31

Added line #L31 was not covered by tests

export function ChatSkeleton() {
const classes = useStyles()
return (

Check warning on line 35 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L33-L35

Added lines #L33 - L35 were not covered by tests
<div className={classes.root}>
<History loading messages={noMessages} />
<Skeleton className={classes.input} height="32px" />
</div>
)
}

const Submitting = Symbol('Submitting')

Check warning on line 43 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L43

Added line #L43 was not covered by tests

interface ChatProps {
initializing: boolean
history: AWS.Bedrock.History
onSubmit: (value: string) => Promise<void>
}

export default function Chat({ history, onSubmit, initializing }: ChatProps) {
const classes = useStyles()

Check warning on line 52 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L51-L52

Added lines #L51 - L52 were not covered by tests

const [value, setValue] = React.useState('')
const [state, setState] = React.useState<Error | typeof Submitting | null>(null)

Check warning on line 55 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L54-L55

Added lines #L54 - L55 were not covered by tests

const handleSubmit = React.useCallback(async () => {

Check warning on line 57 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L57

Added line #L57 was not covered by tests
if (state) return

setState(Submitting)

Check warning on line 60 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L60

Added line #L60 was not covered by tests
try {
await onSubmit(value)
setValue('')

Check warning on line 63 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L62-L63

Added lines #L62 - L63 were not covered by tests
} catch (e) {
setState(e instanceof Error ? e : new Error('Failed to submit message'))
}
setState(null)

Check warning on line 67 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L67

Added line #L67 was not covered by tests
}, [state, onSubmit, value])

return (

Check warning on line 70 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L70

Added line #L70 was not covered by tests
<div className={classes.root}>
<History
className={classes.history}
loading={state === Submitting || initializing}
messages={history.messages}
/>
{state instanceof Error && (
<Lab.Alert className={classes.error} severity="error">

Check warning on line 78 in catalog/app/components/Chat/Chat.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Chat.tsx#L78

Added line #L78 was not covered by tests
{state.message}
</Lab.Alert>
)}
<Input
className={classes.input}
disabled={state === Submitting}
onChange={setValue}
onSubmit={handleSubmit}
value={value}
/>
</div>
)
}
101 changes: 101 additions & 0 deletions catalog/app/components/Chat/History.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import cx from 'classnames'
import * as React from 'react'
import * as M from '@material-ui/core'

Check warning on line 3 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L1-L3

Added lines #L1 - L3 were not covered by tests

import usePrevious from 'utils/usePrevious'

Check warning on line 5 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L5

Added line #L5 was not covered by tests
import * as AWS from 'utils/AWS'

import * as Messages from './Message'

Check warning on line 8 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L8

Added line #L8 was not covered by tests

const useStyles = M.makeStyles((t) => ({

Check warning on line 10 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L10

Added line #L10 was not covered by tests
assistant: {
animation: `$show 300ms ease-out`,
},
message: {
'& + &': {
marginTop: t.spacing(2),
},
},
user: {
animation: `$slide 150ms ease-out`,
marginLeft: 'auto',
width: '60%',
},
'@keyframes slide': {
'0%': {
transform: `translateX($${t.spacing(8)}px)`,
},
'100%': {
transform: `translateX(0)`,
},
},
'@keyframes show': {
'0%': {
opacity: 0.7,
},
'100%': {
opacity: '1',
},
},
}))

interface HistoryProps {
className?: string
loading: boolean
messages: AWS.Bedrock.Message[]
}

export default function History({ className, loading, messages }: HistoryProps) {
const classes = useStyles()

Check warning on line 49 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L48-L49

Added lines #L48 - L49 were not covered by tests

const list = React.useMemo(
() => messages.filter((message) => message.role !== 'system'),

Check warning on line 52 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L51-L52

Added lines #L51 - L52 were not covered by tests
[messages],
)

const ref = React.useRef<HTMLDivElement | null>(null)
usePrevious(messages, (prev) => {

Check warning on line 57 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L56-L57

Added lines #L56 - L57 were not covered by tests
if (prev && messages.length > prev.length) {
ref.current?.scroll({
top: ref.current?.firstElementChild?.clientHeight,
behavior: 'smooth',
})
}
})

return (

Check warning on line 66 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L66

Added line #L66 was not covered by tests
<div className={className} ref={ref}>
<div /* full height scroll area */>
{list.map((message, index) => {

Check warning on line 69 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L69

Added line #L69 was not covered by tests
switch (message.role) {
case 'user':
return (

Check warning on line 72 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L71-L72

Added lines #L71 - L72 were not covered by tests
<Messages.User
key={`message_${index}`}
className={cx(classes.message, classes.user)}
content={message.content}
/>
)
case 'summarize':
return (

Check warning on line 80 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L79-L80

Added lines #L79 - L80 were not covered by tests
<Messages.User
key={`message_${index}`}
className={cx(classes.message, classes.user)}
content="Summarize this document"
/>
)
case 'assistant':
return (

Check warning on line 88 in catalog/app/components/Chat/History.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/History.tsx#L87-L88

Added lines #L87 - L88 were not covered by tests
<Messages.Assistant
key={`message_${index}`}
className={cx(classes.message, classes.assistant)}
content={message.content}
/>
)
}
})}
{loading && <Messages.Skeleton className={classes.message} />}
</div>
</div>
)
}
51 changes: 51 additions & 0 deletions catalog/app/components/Chat/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as React from 'react'
import * as M from '@material-ui/core'

Check warning on line 2 in catalog/app/components/Chat/Input.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Input.tsx#L1-L2

Added lines #L1 - L2 were not covered by tests

interface ChatInputProps {
className?: string
disabled?: boolean
onChange: (value: string) => void
onSubmit: () => void
value: string
}

export default function ChatInput({
className,
disabled,
onChange,
onSubmit,
value,
}: ChatInputProps) {
const handleSubmit = React.useCallback(
(event) => {
event.preventDefault()

Check warning on line 21 in catalog/app/components/Chat/Input.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Input.tsx#L12-L21

Added lines #L12 - L21 were not covered by tests
if (!value || disabled) return
onSubmit()

Check warning on line 23 in catalog/app/components/Chat/Input.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Input.tsx#L23

Added line #L23 was not covered by tests
},
[disabled, onSubmit, value],
)
return (

Check warning on line 27 in catalog/app/components/Chat/Input.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Input.tsx#L27

Added line #L27 was not covered by tests
<form onSubmit={handleSubmit}>
<M.TextField
autoFocus
className={className}
disabled={disabled}
fullWidth
label="Chat"
onChange={(e) => onChange(e.target.value)}

Check warning on line 35 in catalog/app/components/Chat/Input.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Input.tsx#L35

Added line #L35 was not covered by tests
size="small"
value={value}
variant="outlined"
InputProps={{
endAdornment: (
<M.InputAdornment position="end">
<M.IconButton disabled={!value} onClick={onSubmit} type="submit">
<M.Icon>send</M.Icon>
</M.IconButton>
</M.InputAdornment>
),
}}
/>
</form>
)
}
73 changes: 73 additions & 0 deletions catalog/app/components/Chat/Message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import cx from 'classnames'
import * as React from 'react'
import * as M from '@material-ui/core'
import { fade } from '@material-ui/core/styles'

Check warning on line 4 in catalog/app/components/Chat/Message.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Message.tsx#L1-L4

Added lines #L1 - L4 were not covered by tests

import Markdown from 'components/Markdown'
import Skel from 'components/Skeleton'

Check warning on line 7 in catalog/app/components/Chat/Message.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Message.tsx#L6-L7

Added lines #L6 - L7 were not covered by tests

const useSkeletonStyles = M.makeStyles((t) => ({

Check warning on line 9 in catalog/app/components/Chat/Message.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Message.tsx#L9

Added line #L9 was not covered by tests
text: {
height: t.spacing(2),
'& + &': {
marginTop: t.spacing(1),
},
},
}))

interface SkeletonProps {
className?: string
}

export function Skeleton({ className }: SkeletonProps) {
const classes = useSkeletonStyles()
return (

Check warning on line 24 in catalog/app/components/Chat/Message.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Message.tsx#L22-L24

Added lines #L22 - L24 were not covered by tests
<div className={className}>
<Skel className={classes.text} width="30%" />
<Skel className={classes.text} width="90%" />
<Skel className={classes.text} width="70%" />
<Skel className={classes.text} width="50%" />
</div>
)
}

interface AssistantProps {
className?: string
content: string
}

export function Assistant({ className, content }: AssistantProps) {
return (

Check warning on line 40 in catalog/app/components/Chat/Message.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Message.tsx#L39-L40

Added lines #L39 - L40 were not covered by tests
<div className={className}>
<Markdown data={content} />
</div>
)
}

const useUserStyles = M.makeStyles((t) => ({

Check warning on line 47 in catalog/app/components/Chat/Message.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Message.tsx#L47

Added line #L47 was not covered by tests
root: {
borderRadius: t.shape.borderRadius,
background: t.palette.primary.main,
},
inner: {
padding: t.spacing(2),
background: fade(t.palette.background.paper, 0.9),
},
}))

interface UserProps {
className?: string
content: string
}

export function User({ className, content }: UserProps) {
const classes = useUserStyles()

Check warning on line 64 in catalog/app/components/Chat/Message.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Message.tsx#L63-L64

Added lines #L63 - L64 were not covered by tests

return (

Check warning on line 66 in catalog/app/components/Chat/Message.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/Message.tsx#L66

Added line #L66 was not covered by tests
<div className={cx(classes.root, className)}>
<div className={classes.inner}>
<Markdown data={content} />
</div>
</div>
)
}
3 changes: 3 additions & 0 deletions catalog/app/components/Chat/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as Input } from './Input'
export { default as History } from './History'
export { default, ChatSkeleton } from './Chat'

Check warning on line 3 in catalog/app/components/Chat/index.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Chat/index.ts#L1-L3

Added lines #L1 - L3 were not covered by tests
12 changes: 12 additions & 0 deletions catalog/app/components/Markdown/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,18 @@ const useContainerStyles = M.makeStyles({
maxWidth: '100%',
},

'& * + h1, & * + h2, & * + h3, & * + h4, & * + h5, & * + h6': {
marginTop: '8px',
},

'& * + p': {
marginTop: '8px',
},

'& li + li': {
marginTop: '4px',
},

'& table': {
maxWidth: '100%',
width: '100%',
Expand Down
4 changes: 4 additions & 0 deletions catalog/app/containers/Bucket/File.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { readableBytes, readableQuantity } from 'utils/string'
import FileCodeSamples from './CodeSamples/File'
import FileProperties from './FileProperties'
import * as FileView from './FileView'
import QuratorSection from './Qurator/Section'

Check warning on line 35 in catalog/app/containers/Bucket/File.js

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/containers/Bucket/File.js#L35

Added line #L35 was not covered by tests
import Section from './Section'
import renderPreview from './renderPreview'
import * as requests from './requests'
Expand Down Expand Up @@ -496,6 +497,9 @@ export default function File() {
{!!cfg.analyticsBucket && !!blocks.analytics && (
<Analytics {...{ bucket, path }} />
)}
{cfg.qurator && blocks.qurator && (
<QuratorSection handle={handle} />

Check warning on line 501 in catalog/app/containers/Bucket/File.js

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/containers/Bucket/File.js#L500-L501

Added lines #L500 - L501 were not covered by tests
)}
{blocks.meta && (
<>
<FileView.ObjectMeta handle={handle} />
Expand Down
4 changes: 4 additions & 0 deletions catalog/app/containers/Bucket/PackageTree/PackageTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import * as FileView from '../FileView'
import * as Listing from '../Listing'
import PackageCopyDialog from '../PackageCopyDialog'
import * as PD from '../PackageDialog'
import QuratorSection from '../Qurator/Section'

Check warning on line 40 in catalog/app/containers/Bucket/PackageTree/PackageTree.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/containers/Bucket/PackageTree/PackageTree.tsx#L40

Added line #L40 was not covered by tests
import Section from '../Section'
import * as Successors from '../Successors'
import Summary from '../Summary'
Expand Down Expand Up @@ -677,6 +678,9 @@ function FileDisplay({
<FileView.ObjectTags handle={handle} />
</>
)}
{cfg.qurator && blocks.qurator && (
<QuratorSection handle={handle} />

Check warning on line 682 in catalog/app/containers/Bucket/PackageTree/PackageTree.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/containers/Bucket/PackageTree/PackageTree.tsx#L682

Added line #L682 was not covered by tests
)}
</>
),
_: () => null,
Expand Down
Loading

0 comments on commit 51c769c

Please sign in to comment.