Skip to content

Commit bd5725e

Browse files
committed
chore: cleaned up redundant unwraps to make error handling more declarative
1 parent dec4b6f commit bd5725e

File tree

4 files changed

+129
-129
lines changed

4 files changed

+129
-129
lines changed

llm-bedrock/src/client.rs

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -52,39 +52,39 @@ impl Bedrock {
5252
tool_results: Option<Vec<(llm::ToolCall, llm::ToolResult)>>,
5353
) -> llm::ChatEvent {
5454
let bedrock_input = BedrockInput::from(messages, config, tool_results);
55-
if let Err(err) = bedrock_input {
56-
return llm::ChatEvent::Error(err);
57-
}
58-
59-
let input = bedrock_input.unwrap();
6055

6156
let runtime = get_async_runtime();
6257

63-
trace!("Sending request to AWS Bedrock: {input:?}");
64-
runtime.block_on(async {
65-
let model_id = input.model_id.clone();
66-
let response = self
67-
.init_converse(input)
68-
.send()
69-
.await
70-
.map_err(|e| from_converse_sdk_error(model_id, e));
71-
72-
if let Err(err) = response {
73-
return llm::ChatEvent::Error(err);
58+
match bedrock_input {
59+
Err(err) => llm::ChatEvent::Error(err),
60+
Ok(input) => {
61+
trace!("Sending request to AWS Bedrock: {input:?}");
62+
runtime.block_on(async {
63+
let model_id = input.model_id.clone();
64+
let response = self
65+
.init_converse(input)
66+
.send()
67+
.await
68+
.map_err(|e| from_converse_sdk_error(model_id, e));
69+
70+
match response {
71+
Err(err) => llm::ChatEvent::Error(err),
72+
Ok(response) => {
73+
let event = match response.stop_reason() {
74+
bedrock::types::StopReason::ToolUse => {
75+
conversions::converse_output_to_tool_calls(response)
76+
.map(llm::ChatEvent::ToolRequest)
77+
}
78+
_ => conversions::converse_output_to_complete_response(response)
79+
.map(llm::ChatEvent::Message),
80+
};
81+
82+
event.unwrap_or_else(llm::ChatEvent::Error)
83+
}
84+
}
85+
})
7486
}
75-
let response = response.unwrap();
76-
77-
let event = match response.stop_reason() {
78-
bedrock::types::StopReason::ToolUse => {
79-
conversions::converse_output_to_tool_calls(response)
80-
.map(llm::ChatEvent::ToolRequest)
81-
}
82-
_ => conversions::converse_output_to_complete_response(response)
83-
.map(llm::ChatEvent::Message),
84-
};
85-
86-
event.unwrap_or_else(llm::ChatEvent::Error)
87-
})
87+
}
8888
}
8989

9090
pub fn converse_stream(
@@ -93,27 +93,28 @@ impl Bedrock {
9393
config: llm::Config,
9494
) -> BedrockChatStream {
9595
let bedrock_input = BedrockInput::from(messages, config, None);
96-
if let Err(err) = bedrock_input {
97-
return BedrockChatStream::failed(err);
98-
}
99-
let input = bedrock_input.unwrap();
10096

101-
let runtime = get_async_runtime();
102-
trace!("Sending request to AWS Bedrock: {input:?}");
103-
runtime.block_on(async {
104-
let model_id = input.model_id.clone();
105-
let response = self
106-
.init_converse_stream(input)
107-
.send()
108-
.await
109-
.map_err(|e| from_converse_stream_sdk_error(model_id, e));
110-
111-
trace!("Creating AWS Bedrock event stream");
112-
match response {
113-
Ok(response) => BedrockChatStream::new(response.stream),
114-
Err(error) => BedrockChatStream::failed(error),
97+
match bedrock_input {
98+
Err(err) => BedrockChatStream::failed(err),
99+
Ok(input) => {
100+
let runtime = get_async_runtime();
101+
trace!("Sending request to AWS Bedrock: {input:?}");
102+
runtime.block_on(async {
103+
let model_id = input.model_id.clone();
104+
let response = self
105+
.init_converse_stream(input)
106+
.send()
107+
.await
108+
.map_err(|e| from_converse_stream_sdk_error(model_id, e));
109+
110+
trace!("Creating AWS Bedrock event stream");
111+
match response {
112+
Ok(response) => BedrockChatStream::new(response.stream),
113+
Err(error) => BedrockChatStream::failed(error),
114+
}
115+
})
115116
}
116-
})
117+
}
117118
}
118119

119120
fn init_converse(&self, input: conversions::BedrockInput) -> ConverseFluentBuilder {

llm-bedrock/src/conversions.rs

Lines changed: 65 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -205,17 +205,18 @@ fn get_image_content_block_from_url(url: &str) -> Result<bedrock::types::Content
205205

206206
let kind = infer::get(&bytes);
207207

208-
if kind.is_none() {
209-
return Err(custom_error(
210-
llm::ErrorCode::InvalidRequest,
211-
format!(
212-
"Could not infer the mime type of the image downloaded from url: {}",
213-
url
214-
),
215-
));
216-
}
217-
218-
let mime = str_to_bedrock_mime_type(kind.unwrap().mime_type())?;
208+
let mime = match kind {
209+
Some(kind) => str_to_bedrock_mime_type(kind.mime_type())?,
210+
None => {
211+
return Err(custom_error(
212+
llm::ErrorCode::InvalidRequest,
213+
format!(
214+
"Could not infer the mime type of the image downloaded from url: {}",
215+
url
216+
),
217+
));
218+
}
219+
};
219220

220221
Ok(bedrock::types::ContentBlock::Image(
221222
ImageBlock::builder()
@@ -280,24 +281,22 @@ pub fn converse_output_to_tool_calls(
280281
.to_owned(),
281282
))?;
282283

283-
if !output.is_message() {
284-
return Err(custom_error(
284+
match output.as_message() {
285+
Err(_) => Err(custom_error(
285286
llm::ErrorCode::InternalError,
286287
"An error occurred while converting to tool calls: expected output to be a Message"
287288
.to_owned(),
288-
));
289-
}
290-
291-
let message = output.as_message().unwrap().clone();
292-
let mut tool_calls: Vec<llm::ToolCall> = vec![];
293-
294-
for block in message.content {
295-
if let bedrock::types::ContentBlock::ToolUse(tool) = block {
296-
tool_calls.push(bedrock_tool_use_to_llm_tool_call(tool)?);
289+
)),
290+
Ok(message) => {
291+
let mut tool_calls: Vec<llm::ToolCall> = vec![];
292+
for block in message.content.clone() {
293+
if let bedrock::types::ContentBlock::ToolUse(tool) = block {
294+
tool_calls.push(bedrock_tool_use_to_llm_tool_call(tool)?);
295+
}
296+
}
297+
Ok(tool_calls)
297298
}
298299
}
299-
300-
Ok(tool_calls)
301300
}
302301

303302
pub fn converse_output_to_complete_response(
@@ -309,44 +308,46 @@ pub fn converse_output_to_complete_response(
309308
.to_owned(),
310309
))?;
311310

312-
if !output.is_message() {
313-
return Err(custom_error(
311+
match output.as_message() {
312+
Err(_) => Err(custom_error(
314313
llm::ErrorCode::InternalError,
315-
"An error occurred while converting to complete response: expected output to be a Message".to_owned(),
316-
));
317-
}
318-
319-
let message = output.as_message().unwrap().clone();
320-
321-
let mut content_parts: Vec<llm::ContentPart> = vec![];
322-
let mut tool_calls: Vec<llm::ToolCall> = vec![];
323-
for block in message.content {
324-
match block {
325-
bedrock::types::ContentBlock::Text(text) => {
326-
content_parts.push(llm::ContentPart::Text(text.to_owned()));
327-
}
328-
bedrock::types::ContentBlock::Image(image) => {
329-
content_parts.push(bedrock_image_to_llm_content_part(image));
330-
}
331-
bedrock::types::ContentBlock::ToolUse(tool) => {
332-
tool_calls.push(bedrock_tool_use_to_llm_tool_call(tool)?);
314+
"An error occurred while converting to complete response: expected output to be a Message"
315+
.to_owned(),
316+
)),
317+
Ok(message) => {
318+
let mut content_parts: Vec<llm::ContentPart> = vec![];
319+
let mut tool_calls: Vec<llm::ToolCall> = vec![];
320+
for block in message.content.clone() {
321+
match block {
322+
bedrock::types::ContentBlock::Text(text) => {
323+
content_parts.push(llm::ContentPart::Text(text.to_owned()));
324+
}
325+
bedrock::types::ContentBlock::Image(image) => {
326+
content_parts.push(bedrock_image_to_llm_content_part(image));
327+
}
328+
bedrock::types::ContentBlock::ToolUse(tool) => {
329+
tool_calls.push(bedrock_tool_use_to_llm_tool_call(tool)?);
330+
}
331+
_ => {}
332+
}
333333
}
334-
_ => {}
334+
335+
let metadata = converse_output_to_response_metadata(&response);
336+
337+
Ok(llm::CompleteResponse {
338+
// bedrock does not return an id as part of the response struct.
339+
// there may be one present in `additional_model_response_fields`
340+
// but the schema varies depending on the model being invoked. Leaving it empty for now
341+
// until we have a better solution for this.
342+
id: "".to_owned(),
343+
content: content_parts,
344+
tool_calls,
345+
metadata,
346+
})
347+
335348
}
336349
}
337350

338-
let metadata = converse_output_to_response_metadata(&response);
339-
340-
Ok(llm::CompleteResponse {
341-
// bedrock does not return an id as part of the response struct.
342-
// there may be one present in `additional_model_response_fields`
343-
// but the schema varies depending on the model being invoked. Leaving it empty for now
344-
// until we have a better solution for this.
345-
id: "".to_owned(),
346-
content: content_parts,
347-
tool_calls,
348-
metadata,
349-
})
350351
}
351352

352353
fn bedrock_tool_use_to_llm_tool_call(tool: ToolUseBlock) -> Result<llm::ToolCall, llm::Error> {
@@ -445,13 +446,12 @@ pub fn converse_stream_output_to_stream_event(
445446

446447
fn process_content_block_start_event(block: ContentBlockStartEvent) -> Option<llm::StreamEvent> {
447448
if let Some(start_info) = block.start {
448-
if start_info.is_tool_use() {
449-
let tool_use = start_info.as_tool_use().unwrap().clone();
449+
if let Ok(tool_use) = start_info.as_tool_use() {
450450
return Some(llm::StreamEvent::Delta(llm::StreamDelta {
451451
content: None,
452452
tool_calls: Some(vec![llm::ToolCall {
453-
id: tool_use.tool_use_id,
454-
name: tool_use.name,
453+
id: tool_use.tool_use_id.clone(),
454+
name: tool_use.name.clone(),
455455
arguments_json: "".to_owned(),
456456
}]),
457457
}));
@@ -462,20 +462,18 @@ fn process_content_block_start_event(block: ContentBlockStartEvent) -> Option<ll
462462

463463
fn process_content_block_delta_event(block: ContentBlockDeltaEvent) -> Option<llm::StreamEvent> {
464464
if let Some(block_info) = block.delta {
465-
if block_info.is_tool_use() {
466-
let tool_use = block_info.as_tool_use().unwrap().clone();
465+
if let Ok(tool_use) = block_info.as_tool_use() {
467466
return Some(llm::StreamEvent::Delta(llm::StreamDelta {
468467
content: None,
469468
tool_calls: Some(vec![llm::ToolCall {
470469
id: "".to_owned(),
471470
name: "".to_owned(),
472-
arguments_json: tool_use.input,
471+
arguments_json: tool_use.input.clone(),
473472
}]),
474473
}));
475-
} else if block_info.is_text() {
476-
let text = block_info.as_text().unwrap().clone();
474+
} else if let Ok(text) = block_info.as_text() {
477475
return Some(llm::StreamEvent::Delta(llm::StreamDelta {
478-
content: Some(vec![llm::ContentPart::Text(text)]),
476+
content: Some(vec![llm::ContentPart::Text(text.clone())]),
479477
tool_calls: None,
480478
}));
481479
}

llm-bedrock/src/lib.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ impl Guest for BedrockComponent {
2121
LOGGING_STATE.with_borrow_mut(|state| state.init());
2222

2323
let bedrock = get_bedrock_client();
24-
if let Err(err) = bedrock {
25-
return ChatEvent::Error(err);
26-
}
2724

28-
bedrock.unwrap().converse(messages, config, None)
25+
match bedrock {
26+
Ok(client) => client.converse(messages, config, None),
27+
Err(err) => ChatEvent::Error(err),
28+
}
2929
}
3030

3131
fn continue_(
@@ -36,13 +36,11 @@ impl Guest for BedrockComponent {
3636
LOGGING_STATE.with_borrow_mut(|state| state.init());
3737

3838
let bedrock = get_bedrock_client();
39-
if let Err(err) = bedrock {
40-
return ChatEvent::Error(err);
41-
}
4239

43-
bedrock
44-
.unwrap()
45-
.converse(messages, config, Some(tool_results))
40+
match bedrock {
41+
Ok(client) => client.converse(messages, config, Some(tool_results)),
42+
Err(err) => ChatEvent::Error(err),
43+
}
4644
}
4745

4846
fn stream(messages: Vec<Message>, config: Config) -> ChatStream {
@@ -58,11 +56,11 @@ impl ExtendedGuest for BedrockComponent {
5856
LOGGING_STATE.with_borrow_mut(|state| state.init());
5957

6058
let bedrock = get_bedrock_client();
61-
if let Err(err) = bedrock {
62-
return BedrockChatStream::failed(err);
63-
}
6459

65-
bedrock.unwrap().converse_stream(messages, config)
60+
match bedrock {
61+
Ok(client) => client.converse_stream(messages, config),
62+
Err(err) => BedrockChatStream::failed(err),
63+
}
6664
}
6765

6866
fn subscribe(_stream: &Self::ChatStream) -> golem_rust::wasm_rpc::Pollable {

llm-bedrock/src/stream.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,20 @@ impl BedrockChatStream {
5757

5858
runtime.block_on(async move {
5959
let token = stream.recv().await;
60+
log::trace!("Bedrock stream event: {token:?}");
6061

6162
match token {
6263
Ok(Some(output)) => {
6364
log::trace!("Processing bedrock stream event: {output:?}");
6465
converse_stream_output_to_stream_event(output)
6566
}
6667
Ok(None) => {
68+
log::trace!("running set_finished on stream due to None event received");
6769
self.set_finished();
6870
None
6971
}
7072
Err(error) => {
73+
log::trace!("running set_finished on stream due to error: {error:?}");
7174
self.set_finished();
7275
Some(llm::StreamEvent::Error(custom_error(
7376
llm::ErrorCode::InternalError,

0 commit comments

Comments
 (0)