#[cfg(feature = "sync")]
use native_tls::TlsConnector;
#[cfg(feature = "sync")]
use std::{
env,
io::{BufReader, Read, Write},
net::TcpStream,
};
#[cfg(feature = "async")]
use async_std::io::{BufReader, Read, Write};
#[cfg(feature = "async")]
use async_std::net::TcpStream;
#[cfg(feature = "async")]
use async_tls::TlsConnector;
use dotenv::dotenv;
use crate::{
ConfigBuilder, ConfigNotPresent, Default, EnvVariableNotPresent, EnvVariablePresent, Gemini,
GeminiContentGen, InstructionNotPresent, Kind, MaxLenNotPresent, MemoryNot, MemoryOK,
MemoryType, Memorys, ModelNotPresent, ModelPresent, Models, PropertiesNotPresent,
TextNotPresent,
};
use super::{forgetful::forgetFul, memory::memory};
impl<'gemini>
Gemini<
'gemini,
EnvVariableNotPresent,
ModelNotPresent,
ConfigNotPresent,
TextNotPresent,
MaxLenNotPresent,
InstructionNotPresent,
PropertiesNotPresent,
Default,
>
{
pub fn new() -> Self {
Gemini {
model: "",
env_variable: "",
text: "",
instruction: "",
max_len: 8192,
config: ConfigBuilder {
r#type: Kind::Text,
propertiesstate: std::marker::PhantomData,
},
memory: MemoryType::NoMemory,
envstate: std::marker::PhantomData,
maxstate: std::marker::PhantomData,
instructionstate: std::marker::PhantomData,
modelstate: std::marker::PhantomData,
configstate: std::marker::PhantomData,
textstate: std::marker::PhantomData,
memorystate: std::marker::PhantomData,
}
}
}
impl<'gemini>
Gemini<
'gemini,
EnvVariableNotPresent,
ModelNotPresent,
ConfigNotPresent,
TextNotPresent,
MaxLenNotPresent,
InstructionNotPresent,
PropertiesNotPresent,
Default,
>
{
pub fn env(
mut self,
env_variable: &'gemini str,
) -> Gemini<
'gemini,
EnvVariablePresent,
ModelNotPresent,
ConfigNotPresent,
TextNotPresent,
MaxLenNotPresent,
InstructionNotPresent,
PropertiesNotPresent,
Default,
> {
self.env_variable = env_variable;
Gemini {
env_variable: self.env_variable,
model: &self.model,
text: self.text,
instruction: &self.instruction,
max_len: self.max_len,
memory: self.memory,
config: ConfigBuilder {
r#type: self.config.r#type,
propertiesstate: std::marker::PhantomData,
},
envstate: std::marker::PhantomData,
instructionstate: std::marker::PhantomData,
maxstate: std::marker::PhantomData,
modelstate: std::marker::PhantomData,
configstate: std::marker::PhantomData,
textstate: std::marker::PhantomData,
memorystate: std::marker::PhantomData,
}
}
}
impl<'gemini>
Gemini<
'gemini,
EnvVariablePresent,
ModelNotPresent,
ConfigNotPresent,
TextNotPresent,
MaxLenNotPresent,
InstructionNotPresent,
PropertiesNotPresent,
Default,
>
{
pub fn model(
mut self,
model: Models<'gemini>,
) -> Gemini<
'gemini,
EnvVariablePresent,
ModelPresent,
ConfigNotPresent,
TextNotPresent,
MaxLenNotPresent,
InstructionNotPresent,
PropertiesNotPresent,
Default,
> {
match model {
Models::GEMINI_1_0_PRO => self.model = "gemini-1.0-pro",
Models::GEMINI_1_5_FLASH => self.model = "gemini-1.5-flash",
Models::GEMINI_1_5_FLASH_002 => self.model = "gemini-1.5-flash-002",
Models::GEMINI_1_5_FLASH_8B => self.model = "gemini-1.5-flash-8b",
Models::GEMINI_1_5_PRO => self.model = "gemini-1.5-pro",
Models::GEMINI_1_5_PRO_002 => self.model = "gemini-1.5-pro-002",
Models::Custom(model) => self.model = model,
}
Gemini {
env_variable: self.env_variable,
model: &self.model,
text: self.text,
instruction: &self.instruction,
max_len: self.max_len,
memory: self.memory,
config: ConfigBuilder {
r#type: self.config.r#type,
propertiesstate: std::marker::PhantomData,
},
envstate: std::marker::PhantomData,
instructionstate: std::marker::PhantomData,
maxstate: std::marker::PhantomData,
modelstate: std::marker::PhantomData,
configstate: std::marker::PhantomData,
textstate: std::marker::PhantomData,
memorystate: std::marker::PhantomData,
}
}
}
impl<'gemini>
Gemini<
'gemini,
EnvVariablePresent,
ModelPresent,
ConfigNotPresent,
TextNotPresent,
MaxLenNotPresent,
InstructionNotPresent,
PropertiesNotPresent,
Default,
>
{
pub fn no_memory(
mut self,
) -> Gemini<
'gemini,
EnvVariablePresent,
ModelPresent,
ConfigNotPresent,
TextNotPresent,
MaxLenNotPresent,
InstructionNotPresent,
PropertiesNotPresent,
MemoryNot,
> {
self.memory = MemoryType::NoMemory;
Gemini {
env_variable: self.env_variable,
model: &self.model,
text: self.text,
instruction: &self.instruction,
max_len: self.max_len,
memory: self.memory,
config: ConfigBuilder {
r#type: self.config.r#type,
propertiesstate: std::marker::PhantomData,
},
envstate: std::marker::PhantomData,
instructionstate: std::marker::PhantomData,
maxstate: std::marker::PhantomData,
modelstate: std::marker::PhantomData,
configstate: std::marker::PhantomData,
textstate: std::marker::PhantomData,
memorystate: std::marker::PhantomData,
}
}
pub fn memory(
mut self,
memory: Memorys,
) -> Gemini<
'gemini,
EnvVariablePresent,
ModelPresent,
ConfigNotPresent,
TextNotPresent,
MaxLenNotPresent,
InstructionNotPresent,
PropertiesNotPresent,
MemoryOK,
> {
self.memory = MemoryType::Memory(memory);
Gemini {
env_variable: self.env_variable,
model: &self.model,
text: self.text,
instruction: &self.instruction,
max_len: self.max_len,
memory: self.memory,
config: ConfigBuilder {
r#type: self.config.r#type,
propertiesstate: std::marker::PhantomData,
},
envstate: std::marker::PhantomData,
instructionstate: std::marker::PhantomData,
maxstate: std::marker::PhantomData,
modelstate: std::marker::PhantomData,
configstate: std::marker::PhantomData,
textstate: std::marker::PhantomData,
memorystate: std::marker::PhantomData,
}
}
}
impl<'output> GeminiContentGen<'output> {
#[cfg(feature = "sync")]
pub fn output(self) -> String {
match self.memory {
MemoryType::NoMemory => {
forgetFul(&self)
}
MemoryType::Memory(directory) => memory(directory, &self),
}
}
#[cfg(feature = "async")]
pub async fn output(self) -> String {
match self.memory {
MemoryType::NoMemory => {
forgetFul(&self).await
}
MemoryType::Memory(directory) => memory(directory, &self).await,
}
}
}
#[cfg(feature = "sync")]
pub(crate) fn gemini(content: String, env: &str, model: &str, mime_type: &str) -> String {
let _dotenv = dotenv();
let env = env::var(env).expect("Env");
let tcp_stream = TcpStream::connect("generativelanguage.googleapis.com:443").unwrap();
let connector = TlsConnector::new().unwrap();
let mut stream = connector
.connect("generativelanguage.googleapis.com", tcp_stream)
.unwrap();
let models = format!(
"POST /v1beta/models/{}:generateContent?key={} HTTP/1.1\r\n\
Host: generativelanguage.googleapis.com\r\n\
Content-Type: {}\r\n\
Content-Length: {}\r\n\
Connection: close\r\n\r\n{}",
model,
env,
mime_type,
content.len(),
content
);
stream.write_all(models.as_bytes());
stream.flush();
let mut response = String::new();
let mut buffer = BufReader::new(stream);
buffer.read_to_string(&mut response);
response
}
#[cfg(feature = "async")]
pub(crate) async fn gemini(content: String, env: &str, model: &str, mime_type: &str) -> String {
use std::env;
use async_std::io::{ReadExt, WriteExt};
let _dotenv = dotenv();
let env = env::var(env).expect("Env");
let gemini = TlsConnector::new();
let stream = TcpStream::connect("generativelanguage.googleapis.com:443")
.await
.unwrap();
let mut stream = gemini
.connect("generativelanguage.googleapis.com", stream)
.await
.unwrap();
let models = format!(
"POST /v1beta/models/{}:generateContent?key={} HTTP/1.1\r\n\
Host: generativelanguage.googleapis.com\r\n\
Content-Type: {}\r\n\
Content-Length: {}\r\n\
Connection: close\r\n\r\n{}",
model,
env,
mime_type,
content.len(),
content
);
stream.write_all(models.as_bytes()).await;
stream.flush().await;
let mut response = String::new();
let mut buffer = BufReader::new(stream);
buffer.read_to_string(&mut response).await;
response
}