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 Omni: initial public release #4032

Merged
merged 121 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from 116 commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
595fbc9
scaffold
nl0 Jun 21, 2024
a1ab626
bump aws-sdk
nl0 Jun 23, 2024
02e0321
expose bedrock client
nl0 Jun 23, 2024
39b3179
chat with tool calling
nl0 Jun 23, 2024
599ab66
rename to Assistant
nl0 Jun 23, 2024
c5dcdf3
injectable context
nl0 Jun 23, 2024
bceb7df
assistant context for file page
nl0 Jun 24, 2024
a338236
chat -> button to trigger summarize prompt
nl0 Jun 24, 2024
8b1125c
add effect and @effect/schema
nl0 Jun 24, 2024
1a05a4d
refactor context management
nl0 Jun 24, 2024
f6dc833
stable context
nl0 Jun 24, 2024
6626385
render assistant ui above layout
nl0 Jun 24, 2024
0d03f72
multi-round tool use
nl0 Jun 24, 2024
2da0ad8
makeTool helper
nl0 Jun 24, 2024
5aa0a54
startSearch tool
nl0 Jun 24, 2024
21524ef
assistant: iterate
nl0 Jun 24, 2024
08e2f11
instrument search page
nl0 Jun 24, 2024
5ca7147
deploy catalog
nl0 Jun 24, 2024
c959d43
add @types/uuid
nl0 Jun 24, 2024
11c52e3
work on prompting
nl0 Jun 25, 2024
e2e4054
search: expose updateUrlState
nl0 Jun 26, 2024
8c5c004
adjust tools
nl0 Jun 26, 2024
994acbc
tsconfig: enable `downlevelIterators`
nl0 Jul 3, 2024
4103a4d
utils/useConstant: TS
nl0 Jul 3, 2024
05dcd49
lightweight Actor-like abstraction
nl0 Jul 3, 2024
a72c251
Actor: further work
nl0 Jul 3, 2024
79a7ccc
assistant model draft
nl0 Jul 5, 2024
58ce3bc
assistant ui scaffolding
nl0 Jul 5, 2024
47f3b26
use new assistant model and ui
nl0 Jul 5, 2024
e6712dd
some basic ui styling
nl0 Jul 8, 2024
6da6414
tool for getting search results
nl0 Jul 8, 2024
314af98
image and document preview tool
nl0 Jul 10, 2024
70ae971
update effect packages
nl0 Jul 11, 2024
72547d2
effect runtime w/ custom logger
nl0 Jul 11, 2024
d9eb7f4
use custom runtime
nl0 Jul 11, 2024
3a93ebf
use claude 3.5
nl0 Jul 12, 2024
b56e4f9
add stately inspector as a dev dependency
nl0 Jul 15, 2024
2cfe5d4
logging utils for effect
nl0 Jul 16, 2024
7e0749a
utils/Effect: remove logging logic
nl0 Jul 16, 2024
a6ddfca
further work, refactoring, instrumentation
nl0 Jul 16, 2024
b0b4af1
refactor a little
nl0 Jul 16, 2024
4cffe8b
preview tool: scoped logging
nl0 Jul 17, 2024
d7c0d0c
fix context / tools updates
nl0 Jul 18, 2024
19bb829
allow tool schemas with differing I and A types
nl0 Jul 18, 2024
13c937f
expose more comprehensive set of search params to the assistant
nl0 Jul 18, 2024
d4dc1ee
bump @types/react-router
nl0 Jul 19, 2024
aefad0e
refactor routes for more precision and less boilerplate
nl0 Jul 19, 2024
39c450e
add @effect/platform and upgrade other effect packages
nl0 Jul 24, 2024
3f10a3d
navigation tool wip
nl0 Jul 24, 2024
3d85f74
split navigation into reusable parts and instantiation
nl0 Jul 24, 2024
5f8c4fb
comprehensive search url schema
nl0 Jul 31, 2024
faef06d
move stuff around
nl0 Jul 31, 2024
8476e6f
expose route/location info to the assistant
nl0 Jul 31, 2024
495eb10
move stuff around
nl0 Aug 2, 2024
e7dfdb8
reimplement search context
nl0 Aug 2, 2024
ea31868
context: add markers
nl0 Aug 2, 2024
f7f7b78
add searchResultsReady marker
nl0 Aug 2, 2024
e6ea3a2
wait for markers
nl0 Aug 2, 2024
e7e2b96
move stuff around
nl0 Aug 3, 2024
5e12608
move more stuff around
nl0 Aug 3, 2024
a47d946
expose current time
nl0 Aug 3, 2024
713197d
use XML module more
nl0 Aug 3, 2024
99df3e0
mv buckets context to global
nl0 Aug 3, 2024
0c54a2d
graphql codegen config: exclude unnecessary files
nl0 Aug 5, 2024
2374019
fix user meta filters encoding
nl0 Aug 5, 2024
dd708b1
export routes, use XML
nl0 Aug 5, 2024
89b8d62
route en/decoding test
nl0 Aug 5, 2024
5555219
include extents for user meta facets into base search query
nl0 Aug 5, 2024
103c27f
iterate on ui
nl0 Aug 5, 2024
105cdca
discard messages
nl0 Aug 6, 2024
fa73d75
discard tool use; more timestamps
nl0 Aug 6, 2024
324d0f3
JsonDisplay: TSify, fix an issue on expansion (supposedly)
nl0 Aug 7, 2024
3fdec3c
remove obsolete comments
nl0 Aug 7, 2024
e614e7c
JsonDisplay: allow omitting name
nl0 Aug 9, 2024
a1e805b
rm obsolete @ts-expect-error
nl0 Aug 9, 2024
aa83eb2
abort calls; refactor
nl0 Aug 9, 2024
8ecac84
scroll to new messages
nl0 Aug 9, 2024
1209b8d
distinct tool use styles
nl0 Aug 9, 2024
6c1bbbe
utils/Navigation: exact & strict, fromPathParams
nl0 Aug 14, 2024
acf1da4
preview: treat ipynb as text; dedupe object names
nl0 Aug 14, 2024
5885d1b
instrument s3 object route; cleanup
nl0 Aug 14, 2024
0290883
switch back to calude 3 to support documents
nl0 Aug 14, 2024
63f8910
add path-to-regexp package
nl0 Aug 16, 2024
22d1b9f
utils/XML: export types
nl0 Aug 16, 2024
cc584f5
utils/Navigation: use path-to-regexp directly do work around encoding…
nl0 Aug 16, 2024
aef5ba1
more reliable marker handling
nl0 Aug 16, 2024
cb21ebc
FileAssistantContext: tsx -> ts
nl0 Aug 16, 2024
d5e84a0
instrument directory route
nl0 Aug 16, 2024
82ad7eb
feat: update Bedrock model to Claude 3.5 Sonnet
nl0 Oct 3, 2024
2ae30f5
update effect
nl0 Oct 4, 2024
00e91e5
update snapshots
nl0 Oct 4, 2024
783e689
feat: add indexedContent field to SearchHitObject type
nl0 Oct 4, 2024
672da1c
feat: truncate indexed content in search results
nl0 Oct 4, 2024
9b7d5b4
update effect
nl0 Oct 7, 2024
0ce8eec
style: capitalize titles and improve descriptions in search filters
nl0 Oct 7, 2024
4f64926
Merge branch 'master' into qurator-omni
nl0 Oct 7, 2024
e1dacb8
update snapshot
nl0 Oct 7, 2024
4b13363
style: remove background pattern from Assistant UI sidebar
nl0 Oct 8, 2024
13d37fd
rm bg
nl0 Oct 8, 2024
bb4449c
refactor: remove icons from message blocks
nl0 Oct 8, 2024
3d0e438
feat: add faint background to assistant messages
nl0 Oct 8, 2024
c251a5c
feat: update chat UI colors and styling
nl0 Oct 8, 2024
e7f884d
refactor: update MessageContainer to use color and align props
nl0 Oct 8, 2024
8837bc2
refactor: improve CSS specificity and simplify component props
nl0 Oct 8, 2024
ad5fa7b
refactor: move timestamps and actions outside message boxes
nl0 Oct 8, 2024
6bf0cef
style: align footer with colored content boxes in chat UI
nl0 Oct 8, 2024
7aa0264
style: adjust message container padding and action opacity
nl0 Oct 8, 2024
b09a6bd
style: adjust opacity for secondary text elements in JsonDisplay
nl0 Oct 8, 2024
d6ad3aa
style: redesign chat UI and input component
nl0 Oct 8, 2024
e2ba58e
style: update chat UI colors and input styling
nl0 Oct 8, 2024
1ba8262
style: adjust chat UI layout and colors
nl0 Oct 9, 2024
4b0e4aa
Merge branch 'master' into qurator-omni
nl0 Oct 10, 2024
61f5cd1
feat: add conditional rendering for Assistant features
nl0 Oct 10, 2024
856764c
docs: Update Qurator AI Assistant description to use Amazon Bedrock
nl0 Oct 10, 2024
98f3ebf
refactor: remove console.log statements from Context component
nl0 Oct 10, 2024
cd52f78
feat: add AI summarization button for package files
nl0 Oct 10, 2024
14f1a02
refactor: Remove commented out Qurator section in FileDisplay
nl0 Oct 10, 2024
07b7f6a
Merge branch 'master' into qurator-omni
nl0 Oct 10, 2024
e13ec46
changelog
nl0 Oct 10, 2024
89daea6
revert deployment changes
nl0 Oct 10, 2024
1e90cfa
Merge branch 'master' into qurator-omni
nl0 Oct 10, 2024
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
7 changes: 4 additions & 3 deletions .github/workflows/deploy-catalog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ name: Deploy catalog to ECR
on:
push:
branches:
- master
# - master
- qurator-omni
paths:
- '.github/workflows/deploy-catalog.yaml'
- 'catalog/**'
Expand Down Expand Up @@ -64,5 +65,5 @@ jobs:
-t $ECR_REGISTRY_MP/$ECR_REPOSITORY_MP:$IMAGE_TAG \
.
docker push $ECR_REGISTRY_PROD/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY_GOVCLOUD/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY_MP/$ECR_REPOSITORY_MP:$IMAGE_TAG
# docker push $ECR_REGISTRY_GOVCLOUD/$ECR_REPOSITORY:$IMAGE_TAG
# docker push $ECR_REGISTRY_MP/$ECR_REPOSITORY_MP:$IMAGE_TAG
1 change: 0 additions & 1 deletion catalog/.graphqlrc.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
schema: '../shared/graphql/schema.graphql'
documents: './app/**/*.{graphql,js,ts,tsx}'
extensions:
codegen:
hooks:
Expand Down
3 changes: 3 additions & 0 deletions catalog/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Sentry.init(cfg, history)
import 'sanitize.css'

// Import the rest of our modules
import * as Assistant from 'components/Assistant'
import * as Intercom from 'components/Intercom'
import Placeholder from 'components/Placeholder'
import App from 'containers/App'
Expand Down Expand Up @@ -119,6 +120,8 @@ const render = () => {
AWS.Config.Provider,
AWS.Athena.Provider,
AWS.S3.Provider,
Assistant.Provider,
Assistant.WithUI,
Notifications.WithNotifications,
WithGlobalDialogs,
Errors.ErrorBoundary,
Expand Down
95 changes: 95 additions & 0 deletions catalog/app/components/Assistant/Model/Assistant.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import * as Eff from 'effect'
import invariant from 'invariant'

Check warning on line 2 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L1-L2

Added lines #L1 - L2 were not covered by tests

import * as React from 'react'

Check warning on line 4 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L4

Added line #L4 was not covered by tests

import * as AWS from 'utils/AWS'
import * as Actor from 'utils/Actor'

Check warning on line 7 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L6-L7

Added lines #L6 - L7 were not covered by tests

import * as Bedrock from './Bedrock'
import * as Context from './Context'
import * as Conversation from './Conversation'
import * as GlobalContext from './GlobalContext'
import useIsEnabled from './enabled'

Check warning on line 13 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L9-L13

Added lines #L9 - L13 were not covered by tests

export const DISABLED = Symbol('DISABLED')

Check warning on line 15 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L15

Added line #L15 was not covered by tests

function usePassThru<T>(val: T) {
const ref = React.useRef(val)
ref.current = val
return ref

Check warning on line 20 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L17-L20

Added lines #L17 - L20 were not covered by tests
}

function useConstructAssistantAPI() {
const passThru = usePassThru({

Check warning on line 24 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L23-L24

Added lines #L23 - L24 were not covered by tests
bedrock: AWS.Bedrock.useClient(),
context: Context.useLayer(),
})
const layerEff = Eff.Effect.sync(() =>
Eff.Layer.merge(

Check warning on line 29 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L28-L29

Added lines #L28 - L29 were not covered by tests
Bedrock.LLMBedrock(passThru.current.bedrock),
passThru.current.context,
),
)
const [state, dispatch] = Actor.useActorLayer(

Check warning on line 34 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L34

Added line #L34 was not covered by tests
Conversation.ConversationActor,
Conversation.init,
layerEff,
)

GlobalContext.use()

Check warning on line 40 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L40

Added line #L40 was not covered by tests

// XXX: move this to actor state?
const [visible, setVisible] = React.useState(false)
const show = React.useCallback(() => setVisible(true), [])
const hide = React.useCallback(() => setVisible(false), [])

Check warning on line 45 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L43-L45

Added lines #L43 - L45 were not covered by tests

const assist = React.useCallback(
(msg?: string) => {

Check warning on line 48 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L47-L48

Added lines #L47 - L48 were not covered by tests
if (msg) dispatch(Conversation.Action.Ask({ content: msg }))
show()

Check warning on line 50 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L50

Added line #L50 was not covered by tests
},
[show, dispatch],
)

return {

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

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L55

Added line #L55 was not covered by tests
visible,
show,
hide,
assist,
state,
dispatch,
}
}

type AssistantAPI = ReturnType<typeof useConstructAssistantAPI>

const Ctx = React.createContext<AssistantAPI | typeof DISABLED | null>(null)

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

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L67

Added line #L67 was not covered by tests

function AssistantAPIProvider({ children }: React.PropsWithChildren<{}>) {
return <Ctx.Provider value={useConstructAssistantAPI()}>{children}</Ctx.Provider>

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

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L69-L70

Added lines #L69 - L70 were not covered by tests
}

function DisabledAPIProvider({ children }: React.PropsWithChildren<{}>) {
return <Ctx.Provider value={DISABLED}>{children}</Ctx.Provider>

Check warning on line 74 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L73-L74

Added lines #L73 - L74 were not covered by tests
}

export function AssistantProvider({ children }: React.PropsWithChildren<{}>) {

Check warning on line 77 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L77

Added line #L77 was not covered by tests
return useIsEnabled() ? (
<Context.ContextAggregatorProvider>

Check warning on line 79 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L79

Added line #L79 was not covered by tests
<AssistantAPIProvider>{children}</AssistantAPIProvider>
</Context.ContextAggregatorProvider>
) : (
<DisabledAPIProvider>{children}</DisabledAPIProvider>

Check warning on line 83 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L83

Added line #L83 was not covered by tests
)
}

export function useAssistantAPI() {
const api = React.useContext(Ctx)
invariant(api, 'AssistantAPI must be used within an AssistantProvider')

Check warning on line 89 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L87-L89

Added lines #L87 - L89 were not covered by tests
return api === DISABLED ? null : api
}

export function useAssistant() {

Check warning on line 93 in catalog/app/components/Assistant/Model/Assistant.tsx

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Assistant.tsx#L93

Added line #L93 was not covered by tests
return useAssistantAPI()?.assist
}
148 changes: 148 additions & 0 deletions catalog/app/components/Assistant/Model/Bedrock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import BedrockRuntime from 'aws-sdk/clients/bedrockruntime'
import * as Eff from 'effect'

Check warning on line 2 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L2

Added line #L2 was not covered by tests

import * as Log from 'utils/Logging'

Check warning on line 4 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L4

Added line #L4 was not covered by tests

import * as Content from './Content'
import * as LLM from './LLM'

Check warning on line 7 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L6-L7

Added lines #L6 - L7 were not covered by tests

const MODULE = 'Bedrock'

Check warning on line 9 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L9

Added line #L9 was not covered by tests

const MODEL_ID = 'anthropic.claude-3-5-sonnet-20240620-v1:0'

Check warning on line 11 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L11

Added line #L11 was not covered by tests

const mapContent = (contentBlocks: BedrockRuntime.ContentBlocks | undefined) =>
Eff.pipe(

Check warning on line 14 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L13-L14

Added lines #L13 - L14 were not covered by tests
contentBlocks,
Eff.Option.fromNullable,
Eff.Option.map(
Eff.Array.flatMapNullable((c) => {

Check warning on line 18 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L18

Added line #L18 was not covered by tests
if (c.document) {
return Content.ResponseMessageContentBlock.Document({

Check warning on line 20 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L20

Added line #L20 was not covered by tests
format: c.document.format as $TSFixMe,
source: c.document.source.bytes as $TSFixMe,
name: c.document.name,
})
}
if (c.image) {
return Content.ResponseMessageContentBlock.Image({

Check warning on line 27 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L27

Added line #L27 was not covered by tests
format: c.image.format as $TSFixMe,
source: c.image.source.bytes as $TSFixMe,
})
}
if (c.text) {
return Content.ResponseMessageContentBlock.Text({ text: c.text })

Check warning on line 33 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L33

Added line #L33 was not covered by tests
}
if (c.toolUse) {
return Content.ResponseMessageContentBlock.ToolUse(c.toolUse as $TSFixMe)

Check warning on line 36 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L36

Added line #L36 was not covered by tests
}
// if (c.guardContent) {
// // TODO
// return acc
// }
// if (c.toolResult) {
// // XXX: is it really supposed to occur here in LLM response?
// return acc
// }
return null

Check warning on line 46 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L46

Added line #L46 was not covered by tests
}),
),
)

// TODO: use Schema
const contentToBedrock = Content.PromptMessageContentBlock.$match({
GuardContent: ({ text }) => ({ guardContent: { text: { text } } }),
ToolResult: ({ toolUseId, status, content }) => ({

Check warning on line 54 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L52-L54

Added lines #L52 - L54 were not covered by tests
toolResult: {
toolUseId,
status,
content: content.map(
Content.ToolResultContentBlock.$match({
Json: ({ _tag, ...rest }) => rest,
Text: ({ _tag, ...rest }) => rest,

Check warning on line 61 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L60-L61

Added lines #L60 - L61 were not covered by tests
// XXX: be careful with base64/non-base64 encoding
Image: ({ format, source }) => ({

Check warning on line 63 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L63

Added line #L63 was not covered by tests
image: { format, source: { bytes: source } },
}),
Document: ({ format, source, name }) => ({

Check warning on line 66 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L66

Added line #L66 was not covered by tests
document: { format, source: { bytes: source }, name },
}),
}),
),
},
}),
ToolUse: ({ _tag, ...toolUse }) => ({ toolUse }),
Text: ({ _tag, ...rest }) => rest,
Image: ({ format, source }) => ({ image: { format, source: { bytes: source } } }),
Document: ({ format, source, name }) => ({

Check warning on line 76 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L73-L76

Added lines #L73 - L76 were not covered by tests
document: { format, source: { bytes: source }, name },
}),
})

const messagesToBedrock = (
messages: Eff.Array.NonEmptyArray<LLM.PromptMessage>,

Check warning on line 82 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L81-L82

Added lines #L81 - L82 were not covered by tests
): BedrockRuntime.Message[] =>
// create an array of alternating assistant and user messages
Eff.pipe(

Check warning on line 85 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L85

Added line #L85 was not covered by tests
messages,
Eff.Array.groupWith((m1, m2) => m1.role === m2.role),
Eff.Array.map((group) => ({

Check warning on line 88 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L87-L88

Added lines #L87 - L88 were not covered by tests
role: group[0].role,
content: group.map((m) => contentToBedrock(m.content)),

Check warning on line 90 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L90

Added line #L90 was not covered by tests
})),
)

const toolConfigToBedrock = (
toolConfig: LLM.ToolConfig,
): BedrockRuntime.ToolConfiguration => ({
tools: Object.entries(toolConfig.tools).map(([name, { description, schema }]) => ({

Check warning on line 97 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L94-L97

Added lines #L94 - L97 were not covered by tests
toolSpec: {
name,
description,
inputSchema: { json: schema },
},
})),
toolChoice:
toolConfig.choice &&
LLM.ToolChoice.$match(toolConfig.choice, {
Auto: () => ({ auto: {} }),
Any: () => ({ any: {} }),
Specific: ({ name }) => ({ tool: { name } }),

Check warning on line 109 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L106-L109

Added lines #L106 - L109 were not covered by tests
}),
})

// a layer providing the service over aws.bedrock
export function LLMBedrock(bedrock: BedrockRuntime) {
const converse = (prompt: LLM.Prompt, opts?: LLM.Options) =>
Log.scoped({

Check warning on line 116 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L114-L116

Added lines #L114 - L116 were not covered by tests
name: `${MODULE}.converse`,
enter: [
Log.br,
'model id:',
MODEL_ID,
Log.br,
'prompt:',
prompt,
Log.br,
'opts:',
opts,
],
})(
Eff.Effect.tryPromise(() =>
bedrock

Check warning on line 131 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L130-L131

Added lines #L130 - L131 were not covered by tests
.converse({
modelId: MODEL_ID,
system: [{ text: prompt.system }],
messages: messagesToBedrock(prompt.messages),
toolConfig: prompt.toolConfig && toolConfigToBedrock(prompt.toolConfig),
...opts,
})
.promise()
.then((backendResponse) => ({

Check warning on line 140 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L140

Added line #L140 was not covered by tests
backendResponse,
content: mapContent(backendResponse.output.message?.content),
})),
),
)

return Eff.Layer.succeed(LLM.LLM, { converse })

Check warning on line 147 in catalog/app/components/Assistant/Model/Bedrock.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Bedrock.ts#L147

Added line #L147 was not covered by tests
}
107 changes: 107 additions & 0 deletions catalog/app/components/Assistant/Model/Content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import * as Eff from 'effect'

import { JsonRecord } from 'utils/types'

// XXX: schema for en/decoding to/from aws bedrock types?

export const DOCUMENT_FORMATS = [
'pdf',
'csv',
'doc',
'docx',
'xls',
'xlsx',
'html',
'txt',
'md',
] as const
export type DocumentFormat = (typeof DOCUMENT_FORMATS)[number]

export interface DocumentBlock {
format: DocumentFormat
name: string
// A base64-encoded string of a UTF-8 encoded file, that is the document to include in the message.
source: Buffer | Uint8Array | Blob | string
}

export const IMAGE_FORMATS = ['png', 'jpeg', 'gif', 'webp'] as const
export type ImageFormat = (typeof IMAGE_FORMATS)[number]

export interface ImageBlock {
format: ImageFormat
// The raw image bytes for the image. If you use an AWS SDK, you don't need to base64 encode the image bytes.
source: Buffer | Uint8Array | Blob | string
}

export interface JsonBlock {
json: JsonRecord
}

export interface TextBlock {
text: string
}

export interface GuardBlock {
text: string
}

export interface ToolUseBlock {
toolUseId: string
name: string
input: JsonRecord
}

export type ToolResultContentBlock = Eff.Data.TaggedEnum<{
Json: JsonBlock
Text: TextBlock
Image: ImageBlock
Document: DocumentBlock
}>

// eslint-disable-next-line @typescript-eslint/no-redeclare
export const ToolResultContentBlock = Eff.Data.taggedEnum<ToolResultContentBlock>()

export type ToolResultStatus = 'success' | 'error'

export interface ToolResultBlock {
toolUseId: string
content: ToolResultContentBlock[]
status: ToolResultStatus
}

export type ResponseMessageContentBlock = Eff.Data.TaggedEnum<{
// GuardContent: {}
// ToolResult: {}
ToolUse: ToolUseBlock
Text: TextBlock
Image: ImageBlock
Document: DocumentBlock
}>

// eslint-disable-next-line @typescript-eslint/no-redeclare
export const ResponseMessageContentBlock =
Eff.Data.taggedEnum<ResponseMessageContentBlock>()

export type MessageContentBlock = Eff.Data.TaggedEnum<{
Text: TextBlock
Image: ImageBlock
Document: DocumentBlock
}>

// eslint-disable-next-line @typescript-eslint/no-redeclare
export const MessageContentBlock = Eff.Data.taggedEnum<MessageContentBlock>()

export type PromptMessageContentBlock = Eff.Data.TaggedEnum<{
GuardContent: GuardBlock
ToolResult: ToolResultBlock
ToolUse: ToolUseBlock
Text: TextBlock
Image: ImageBlock
Document: DocumentBlock
}>

// eslint-disable-next-line @typescript-eslint/no-redeclare
export const PromptMessageContentBlock = Eff.Data.taggedEnum<PromptMessageContentBlock>()

export const text = (first: string, ...rest: string[]) =>
PromptMessageContentBlock.Text({ text: [first, ...rest].join('') })

Check warning on line 107 in catalog/app/components/Assistant/Model/Content.ts

View check run for this annotation

Codecov / codecov/patch/informational

catalog/app/components/Assistant/Model/Content.ts#L107

Added line #L107 was not covered by tests
Loading