gproxy_protocol/adapt/generate/resources/
chat.rs1use super::*;
2use crate::wire::{DeclaredFields, openai::chat as h};
3
4impl<R: ResourceAccess> GenerationResources<'_, R> {
5 pub async fn chat(
6 &self,
7 input: h::GenerateContentRequestBody,
8 ) -> Result<h::GenerateContentRequestBody, TransformError> {
9 let mut input = input.into_declared();
10 let mut budget = self.budget(crate::Dialect::OpenAiChat);
11 for message in &mut input.messages {
12 if let h::ChatMessage::User(message) = message
13 && let h::UserContent::Parts(parts) = &mut message.content
14 {
15 for part in parts {
16 match part {
17 h::UserContentPart::Image(part)
18 if !part.image_url.url.starts_with("data:") =>
19 {
20 let Some(media) = budget
21 .read(ResourceReference::Url(part.image_url.url.clone()), true)
22 .await?
23 else {
24 continue;
25 };
26 part.image_url.url = media.data_uri();
27 }
28 h::UserContentPart::File(part) if part.file.file_id.is_some() => {
29 if part.file.file_data.is_some() {
30 return Err(TransformError::shape(
31 "file",
32 "ambiguous inline data and native ID",
33 ));
34 }
35 let Some(media) = budget
36 .read(
37 ResourceReference::Id(
38 part.file.file_id.clone().expect("matched"),
39 ),
40 false,
41 )
42 .await?
43 else {
44 continue;
45 };
46 part.file.file_data = Some(media.data_uri());
47 part.file.file_id = None;
48 if part.file.filename.is_none() {
49 part.file.filename = media.filename;
50 }
51 }
52 _ => {}
53 }
54 }
55 }
56 }
57 Ok(input)
58 }
59}