Skip to content

Commit

Permalink
better error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
nl0 committed Nov 29, 2024
1 parent bdbfc95 commit b0c9a16
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 23 deletions.
42 changes: 27 additions & 15 deletions catalog/app/components/Assistant/Model/Bedrock.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type * as AWSSDK from 'aws-sdk'
import BedrockRuntime from 'aws-sdk/clients/bedrockruntime'
import * as Eff from 'effect'

Expand Down Expand Up @@ -114,6 +115,10 @@ const toolConfigToBedrock = (
}),
})

function isAWSError(e: any): e is AWSSDK.AWSError {
return e.code !== undefined && e.message !== undefined
}

// a layer providing the service over aws.bedrock
export function LLMBedrock(bedrock: BedrockRuntime) {
const converse = (prompt: LLM.Prompt, opts?: LLM.Options) =>
Expand All @@ -131,21 +136,28 @@ export function LLMBedrock(bedrock: BedrockRuntime) {
opts,
],
})(
Eff.Effect.tryPromise(() =>
bedrock
.converse({
modelId: getModelId(),
system: [{ text: prompt.system }],
messages: messagesToBedrock(prompt.messages),
toolConfig: prompt.toolConfig && toolConfigToBedrock(prompt.toolConfig),
...opts,
})
.promise()
.then((backendResponse) => ({
backendResponse,
content: mapContent(backendResponse.output.message?.content),
})),
),
Eff.Effect.tryPromise({
try: () =>
bedrock
.converse({
modelId: getModelId(),
system: [{ text: prompt.system }],
messages: messagesToBedrock(prompt.messages),
toolConfig: prompt.toolConfig && toolConfigToBedrock(prompt.toolConfig),
...opts,
})
.promise()
.then((backendResponse) => ({
backendResponse,
content: mapContent(backendResponse.output.message?.content),
})),
catch: (e) =>
new LLM.LLMError({
message: isAWSError(e)
? `Bedrock error (${e.code}): ${e.message}`
: `Unexpected error: ${e}`,
}),
}),
)

return Eff.Layer.succeed(LLM.LLM, { converse })
Expand Down
10 changes: 5 additions & 5 deletions catalog/app/components/Assistant/Model/Conversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export type Action = Eff.Data.TaggedEnum<{
readonly content: string
}
LLMError: {
readonly error: Eff.Cause.UnknownException
readonly error: LLM.LLMError
}
LLMResponse: {
readonly content: Exclude<Content.ResponseMessageContentBlock, { _tag: 'ToolUse' }>[]
Expand Down Expand Up @@ -144,8 +144,8 @@ const llmRequest = (events: Event[]) =>
const response = yield* llm.converse(prompt)

if (Eff.Option.isNone(response.content)) {
return yield* new Eff.Cause.UnknownException(
new Error('No content in LLM response'),
return yield* Eff.Effect.fail(
new LLM.LLMError({ message: 'No content in LLM response' }),
)
}

Expand Down Expand Up @@ -193,8 +193,8 @@ export const ConversationActor = Eff.Effect.succeed(
WaitingForAssistant: {
LLMError: ({ events }, { error }) =>
idle(events, {
message: 'Error while interacting with LLM. Please try again.',
details: `${error}`,
message: 'Error while interacting with LLM.',
details: error.message,
}),
LLMResponse: (state, { content, toolUses }, dispatch) =>
Eff.Effect.gen(function* () {
Expand Down
10 changes: 9 additions & 1 deletion catalog/app/components/Assistant/Model/LLM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,21 @@ interface ConverseResponse {
backendResponse: BedrockRuntime.ConverseResponse
}

export class LLMError {
message: string

constructor({ message }: { message: string }) {
this.message = message
}
}

// a service
export class LLM extends Eff.Context.Tag('LLM')<
LLM,
{
converse: (
prompt: Prompt,
opts?: Options,
) => Eff.Effect.Effect<ConverseResponse, Eff.Cause.UnknownException>
) => Eff.Effect.Effect<ConverseResponse, LLMError>
}
>() {}
5 changes: 3 additions & 2 deletions catalog/app/components/Assistant/UI/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -465,8 +465,9 @@ export default function Chat({ state, dispatch }: ChatProps) {
Eff.Option.match(s.error, {
onSome: (e) => (
<MessageContainer timestamp={s.timestamp}>
Error occurred: {e.message}
<div>{e.details}</div>
<b>{e.message}</b>
<br />
{e.details}
</MessageContainer>
// TODO: retry / discard
),
Expand Down

0 comments on commit b0c9a16

Please sign in to comment.