Skip to content

Commit c7fbe2b

Browse files
author
Dongri Jin
authored
Merge pull request #64 from dongri/add-vision
Add vision
2 parents c8d376e + f99645c commit c7fbe2b

File tree

5 files changed

+89
-7
lines changed

5 files changed

+89
-7
lines changed

examples/chat_completion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
1010
GPT4.to_string(),
1111
vec![chat_completion::ChatCompletionMessage {
1212
role: chat_completion::MessageRole::user,
13-
content: String::from("What is Bitcoin?"),
13+
content: chat_completion::Content::Text(String::from("What is bitcoin?")),
1414
name: None,
1515
}],
1616
);

examples/function_call.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
3131
GPT3_5_TURBO_0613.to_string(),
3232
vec![chat_completion::ChatCompletionMessage {
3333
role: chat_completion::MessageRole::user,
34-
content: String::from("What is the price of Ethereum?"),
34+
content: chat_completion::Content::Text(String::from("What is the price of Ethereum?")),
3535
name: None,
3636
}],
3737
)

examples/function_call_role.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
3131
GPT3_5_TURBO_0613.to_string(),
3232
vec![chat_completion::ChatCompletionMessage {
3333
role: chat_completion::MessageRole::user,
34-
content: String::from("What is the price of Ethereum?"),
34+
content: chat_completion::Content::Text(String::from("What is the price of Ethereum?")),
3535
name: None,
3636
}],
3737
)
@@ -83,15 +83,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
8383
vec![
8484
chat_completion::ChatCompletionMessage {
8585
role: chat_completion::MessageRole::user,
86-
content: String::from("What is the price of Ethereum?"),
86+
content: chat_completion::Content::Text(String::from(
87+
"What is the price of Ethereum?",
88+
)),
8789
name: None,
8890
},
8991
chat_completion::ChatCompletionMessage {
9092
role: chat_completion::MessageRole::function,
91-
content: {
93+
content: chat_completion::Content::Text({
9294
let price = get_coin_price(&coin);
9395
format!("{{\"price\": {}}}", price)
94-
},
96+
}),
9597
name: Some(String::from("get_coin_price")),
9698
},
9799
],

examples/vision.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use openai_api_rs::v1::api::Client;
2+
use openai_api_rs::v1::chat_completion::{self, ChatCompletionRequest};
3+
use openai_api_rs::v1::common::GPT4_VISION_PREVIEW;
4+
use std::env;
5+
6+
fn main() -> Result<(), Box<dyn std::error::Error>> {
7+
let client = Client::new(env::var("OPENAI_API_KEY").unwrap().to_string());
8+
9+
let req = ChatCompletionRequest::new(
10+
GPT4_VISION_PREVIEW.to_string(),
11+
vec![chat_completion::ChatCompletionMessage {
12+
role: chat_completion::MessageRole::user,
13+
content: chat_completion::Content::ImageUrl(vec![
14+
chat_completion::ImageUrl {
15+
r#type: chat_completion::ContentType::text,
16+
text: Some(String::from("What’s in this image?")),
17+
image_url: None,
18+
},
19+
chat_completion::ImageUrl {
20+
r#type: chat_completion::ContentType::image_url,
21+
text: None,
22+
image_url: Some(chat_completion::ImageUrlType {
23+
url: String::from(
24+
"https://upload.wikimedia.org/wikipedia/commons/5/50/Bitcoin.png",
25+
),
26+
}),
27+
},
28+
]),
29+
name: None,
30+
}],
31+
);
32+
33+
let result = client.chat_completion(req)?;
34+
println!("{:?}", result.choices[0].message.content);
35+
36+
Ok(())
37+
}
38+
39+
// OPENAI_API_KEY=xxxx cargo run --package openai-api-rs --example chat_completion

src/v1/chat_completion.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,51 @@ pub enum MessageRole {
9898
function,
9999
}
100100

101+
#[derive(Debug, Deserialize, Clone)]
102+
pub enum Content {
103+
Text(String),
104+
ImageUrl(Vec<ImageUrl>),
105+
}
106+
107+
impl serde::Serialize for Content {
108+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
109+
where
110+
S: serde::Serializer,
111+
{
112+
match *self {
113+
Content::Text(ref text) => serializer.serialize_str(text),
114+
Content::ImageUrl(ref image_url) => image_url.serialize(serializer),
115+
}
116+
}
117+
}
118+
119+
#[derive(Debug, Serialize, Deserialize, Clone)]
120+
#[allow(non_camel_case_types)]
121+
pub enum ContentType {
122+
text,
123+
image_url,
124+
}
125+
126+
#[derive(Debug, Serialize, Deserialize, Clone)]
127+
#[allow(non_camel_case_types)]
128+
pub struct ImageUrlType {
129+
pub url: String,
130+
}
131+
132+
#[derive(Debug, Serialize, Deserialize, Clone)]
133+
#[allow(non_camel_case_types)]
134+
pub struct ImageUrl {
135+
pub r#type: ContentType,
136+
#[serde(skip_serializing_if = "Option::is_none")]
137+
pub text: Option<String>,
138+
#[serde(skip_serializing_if = "Option::is_none")]
139+
pub image_url: Option<ImageUrlType>,
140+
}
141+
101142
#[derive(Debug, Serialize, Deserialize, Clone)]
102143
pub struct ChatCompletionMessage {
103144
pub role: MessageRole,
104-
pub content: String,
145+
pub content: Content,
105146
#[serde(skip_serializing_if = "Option::is_none")]
106147
pub name: Option<String>,
107148
}

0 commit comments

Comments
 (0)