Add assistant api

This commit is contained in:
Dongri Jin
2023-11-11 18:24:51 +09:00
parent 6e07047c27
commit cfca665c21
19 changed files with 966 additions and 48 deletions

View File

@ -1,3 +1,7 @@
use crate::v1::assistant::{
AssistantFileObject, AssistantFileRequest, AssistantObject, AssistantRequest, DeletionStatus,
ListAssistant, ListAssistantFile,
};
use crate::v1::audio::{
AudioTranscriptionRequest, AudioTranscriptionResponse, AudioTranslationRequest,
AudioTranslationResponse,
@ -22,7 +26,16 @@ use crate::v1::image::{
ImageEditRequest, ImageEditResponse, ImageGenerationRequest, ImageGenerationResponse,
ImageVariationRequest, ImageVariationResponse,
};
use crate::v1::message::{
CreateMessageRequest, ListMessage, ListMessageFile, MessageFileObject, MessageObject,
ModifyMessageRequest,
};
use crate::v1::moderation::{CreateModerationRequest, CreateModerationResponse};
use crate::v1::run::{
CreateRunRequest, CreateThreadAndRunRequest, ListRun, ListRunStep, ModifyRunRequest, RunObject,
RunStepObject,
};
use crate::v1::thread::{CreateThreadRequest, ModifyThreadRequest, ThreadObject};
use minreq::Response;
@ -57,13 +70,16 @@ impl Client {
}
}
pub fn build_request(&self, request: minreq::Request) -> minreq::Request {
pub fn build_request(&self, request: minreq::Request, is_beta: bool) -> minreq::Request {
let mut request = request
.with_header("Content-Type", "application/json")
.with_header("Authorization", format!("Bearer {}", self.api_key));
if let Some(organization) = &self.organization {
request = request.with_header("openai-organization", organization);
}
if is_beta {
request = request.with_header("OpenAI-Beta", "assistants=v1");
}
request
}
@ -77,8 +93,7 @@ impl Client {
api_endpoint = self.api_endpoint,
path = path
);
let request = self.build_request(minreq::post(url));
let request = self.build_request(minreq::post(url), Self::is_beta(path));
let res = request.with_json(params).unwrap().send();
match res {
Ok(res) => {
@ -100,8 +115,7 @@ impl Client {
api_endpoint = self.api_endpoint,
path = path
);
let request = self.build_request(minreq::get(url));
let request = self.build_request(minreq::get(url), Self::is_beta(path));
let res = request.send();
match res {
Ok(res) => {
@ -123,8 +137,7 @@ impl Client {
api_endpoint = self.api_endpoint,
path = path
);
let request = self.build_request(minreq::delete(url));
let request = self.build_request(minreq::delete(url), Self::is_beta(path));
let res = request.send();
match res {
Ok(res) => {
@ -368,9 +381,396 @@ impl Client {
}
}
pub fn create_assistant(&self, req: AssistantRequest) -> Result<AssistantObject, APIError> {
let res = self.post("/assistants", &req)?;
let r = res.json::<AssistantObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn retrieve_assistant(&self, assistant_id: String) -> Result<AssistantObject, APIError> {
let res = self.get(&format!("/assistants/{}", assistant_id))?;
let r = res.json::<AssistantObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn modify_assistant(
&self,
assistant_id: String,
req: AssistantRequest,
) -> Result<AssistantObject, APIError> {
let res = self.post(&format!("/assistants/{}", assistant_id), &req)?;
let r = res.json::<AssistantObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn delete_assistant(&self, assistant_id: String) -> Result<DeletionStatus, APIError> {
let res = self.delete(&format!("/assistants/{}", assistant_id))?;
let r = res.json::<DeletionStatus>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn list_assistant(
&self,
limit: Option<i64>,
order: Option<String>,
after: Option<String>,
before: Option<String>,
) -> Result<ListAssistant, APIError> {
let mut url = "/assistants".to_owned();
url = Self::query_params(limit, order, after, before, url);
let res = self.get(&url)?;
let r = res.json::<ListAssistant>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn create_assistant_file(
&self,
assistant_id: String,
req: AssistantFileRequest,
) -> Result<AssistantFileObject, APIError> {
let res = self.post(&format!("/assistants/{}/files", assistant_id), &req)?;
let r = res.json::<AssistantFileObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn retrieve_assistant_file(
&self,
assistant_id: String,
file_id: String,
) -> Result<AssistantFileObject, APIError> {
let res = self.get(&format!("/assistants/{}/files/{}", assistant_id, file_id))?;
let r = res.json::<AssistantFileObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn delete_assistant_file(
&self,
assistant_id: String,
file_id: String,
) -> Result<DeletionStatus, APIError> {
let res = self.delete(&format!("/assistants/{}/files/{}", assistant_id, file_id))?;
let r = res.json::<DeletionStatus>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn list_assistant_file(
&self,
assistant_id: String,
limit: Option<i64>,
order: Option<String>,
after: Option<String>,
before: Option<String>,
) -> Result<ListAssistantFile, APIError> {
let mut url = format!("/assistants/{}/files", assistant_id);
url = Self::query_params(limit, order, after, before, url);
let res = self.get(&url)?;
let r = res.json::<ListAssistantFile>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn create_thread(&self, req: CreateThreadRequest) -> Result<ThreadObject, APIError> {
let res = self.post("/threads", &req)?;
let r = res.json::<ThreadObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn retrieve_thread(&self, thread_id: String) -> Result<ThreadObject, APIError> {
let res = self.get(&format!("/threads/{}", thread_id))?;
let r = res.json::<ThreadObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn modify_thread(
&self,
thread_id: String,
req: ModifyThreadRequest,
) -> Result<ThreadObject, APIError> {
let res = self.post(&format!("/threads/{}", thread_id), &req)?;
let r = res.json::<ThreadObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn delete_thread(&self, thread_id: String) -> Result<DeletionStatus, APIError> {
let res = self.delete(&format!("/threads/{}", thread_id))?;
let r = res.json::<DeletionStatus>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn create_message(
&self,
thread_id: String,
req: CreateMessageRequest,
) -> Result<MessageObject, APIError> {
let res = self.post(&format!("/threads/{}/messages", thread_id), &req)?;
let r = res.json::<MessageObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn retrieve_message(
&self,
thread_id: String,
message_id: String,
) -> Result<MessageObject, APIError> {
let res = self.get(&format!("/threads/{}/messages/{}", thread_id, message_id))?;
let r = res.json::<MessageObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn modify_message(
&self,
thread_id: String,
message_id: String,
req: ModifyMessageRequest,
) -> Result<MessageObject, APIError> {
let res = self.post(
&format!("/threads/{}/messages/{}", thread_id, message_id),
&req,
)?;
let r = res.json::<MessageObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn list_messages(&self, thread_id: String) -> Result<ListMessage, APIError> {
let res = self.get(&format!("/threads/{}/messages", thread_id))?;
let r = res.json::<ListMessage>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn retrieve_message_file(
&self,
thread_id: String,
message_id: String,
file_id: String,
) -> Result<MessageFileObject, APIError> {
let res = self.get(&format!(
"/threads/{}/messages/{}/files/{}",
thread_id, message_id, file_id
))?;
let r = res.json::<MessageFileObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn list_message_file(
&self,
thread_id: String,
message_id: String,
limit: Option<i64>,
order: Option<String>,
after: Option<String>,
before: Option<String>,
) -> Result<ListMessageFile, APIError> {
let mut url = format!("/threads/{}/messages/{}/files", thread_id, message_id);
url = Self::query_params(limit, order, after, before, url);
let res = self.get(&url)?;
let r = res.json::<ListMessageFile>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn create_run(
&self,
thread_id: String,
req: CreateRunRequest,
) -> Result<RunObject, APIError> {
let res = self.post(&format!("/threads/{}/runs", thread_id), &req)?;
let r = res.json::<RunObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn retrieve_run(&self, thread_id: String, run_id: String) -> Result<RunObject, APIError> {
let res = self.get(&format!("/threads/{}/runs/{}", thread_id, run_id))?;
let r = res.json::<RunObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn modify_run(
&self,
thread_id: String,
run_id: String,
req: ModifyRunRequest,
) -> Result<RunObject, APIError> {
let res = self.post(&format!("/threads/{}/runs/{}", thread_id, run_id), &req)?;
let r = res.json::<RunObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn list_run(
&self,
thread_id: String,
limit: Option<i64>,
order: Option<String>,
after: Option<String>,
before: Option<String>,
) -> Result<ListRun, APIError> {
let mut url = format!("/threads/{}/runs", thread_id);
url = Self::query_params(limit, order, after, before, url);
let res = self.get(&url)?;
let r = res.json::<ListRun>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn cancel_run(&self, thread_id: String, run_id: String) -> Result<RunObject, APIError> {
let empty_req = ModifyRunRequest::new();
let res = self.post(
&format!("/threads/{}/runs/{}/cancel", thread_id, run_id),
&empty_req,
)?;
let r = res.json::<RunObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn create_thread_and_run(
&self,
req: CreateThreadAndRunRequest,
) -> Result<RunObject, APIError> {
let res = self.post("/threads/runs", &req)?;
let r = res.json::<RunObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn retrieve_run_step(
&self,
thread_id: String,
run_id: String,
step_id: String,
) -> Result<RunStepObject, APIError> {
let res = self.get(&format!(
"/threads/{}/runs/{}/steps/{}",
thread_id, run_id, step_id
))?;
let r = res.json::<RunStepObject>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
pub fn list_run_step(
&self,
thread_id: String,
run_id: String,
limit: Option<i64>,
order: Option<String>,
after: Option<String>,
before: Option<String>,
) -> Result<ListRunStep, APIError> {
let mut url = format!("/threads/{}/runs/{}/steps", thread_id, run_id);
url = Self::query_params(limit, order, after, before, url);
let res = self.get(&url)?;
let r = res.json::<ListRunStep>();
match r {
Ok(r) => Ok(r),
Err(e) => Err(self.new_error(e)),
}
}
fn new_error(&self, err: minreq::Error) -> APIError {
APIError {
message: err.to_string(),
}
}
fn is_beta(path: &str) -> bool {
path.starts_with("/assistants") || path.starts_with("/threads")
}
fn query_params(
limit: Option<i64>,
order: Option<String>,
after: Option<String>,
before: Option<String>,
mut url: String,
) -> String {
let mut params = vec![];
if let Some(limit) = limit {
params.push(format!("limit={}", limit));
}
if let Some(order) = order {
params.push(format!("order={}", order));
}
if let Some(after) = after {
params.push(format!("after={}", after));
}
if let Some(before) = before {
params.push(format!("before={}", before));
}
if !params.is_empty() {
url = format!("{}?{}", url, params.join("&"));
}
url
}
}