Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qurator AI Assistant for summarizing file contents using Bedrock API #3989

Merged
merged 9 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 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 @@
{!!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 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 @@
<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