Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/bots prompt multi model #66

Merged
merged 8 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,653 changes: 2,645 additions & 8 deletions config/bot.json

Large diffs are not rendered by default.

16 changes: 1 addition & 15 deletions core/src/model/app_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ pub struct AppInfo {
user: Option<User>,
cfg: AppCfg,
cur_channel_id: Option<Uuid>,
quick_launcher_id: Option<Uuid>,
}

#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
Expand Down Expand Up @@ -62,7 +61,7 @@ impl AppInfo {
fn save_local(&self) {
if let Some(user) = &self.user {
let uid = user.uid();
let local_state = LocalState::new(self.cur_channel_id, self.quick_launcher_id, Some(uid));
let local_state = LocalState::new(self.cur_channel_id, Some(uid));
utils::write_local_state(&uid.to_string(), &local_state).expect("Failed to save local state");
}
}
Expand All @@ -83,13 +82,6 @@ impl AppInfo {
self.save_local();
}

pub fn quick_launcher_id(&self) -> Option<&Uuid> { self.quick_launcher_id.as_ref() }

pub fn set_quick_launcher_id(&mut self, quick_launcher_id: Option<Uuid>) {
self.quick_launcher_id = quick_launcher_id;
self.save_local();
}

pub fn bots(&self) -> &[Bot] { &self.bots }

pub fn bots_rc(&self) -> Rc<Vec<Bot>> { self.bots.clone() }
Expand Down Expand Up @@ -186,7 +178,6 @@ pub fn init_app_data() -> AppData {
user,
cfg,
cur_channel_id,
quick_launcher_id: *local_state.quick_launcher_id(),
};

let info = Box::new(info);
Expand Down Expand Up @@ -364,10 +355,6 @@ impl AppData {
let uid = user.uid();
self.info.as_mut().set_user(Some(user));
let local_state = utils::read_local_state(&uid.to_string()).unwrap_or_default();
self
.info
.as_mut()
.set_quick_launcher_id(*local_state.quick_launcher_id());

let (db, mut channels) = init_db(Some(uid));
self.db = db;
Expand Down Expand Up @@ -395,7 +382,6 @@ impl AppData {

pub fn logout(&mut self) {
self.info.as_mut().set_user(None);
self.info.as_mut().set_quick_launcher_id(None);
self.db = None;
utils::del_current_user().expect("Failed to delete current user");
utils::token::del_token().expect("Failed to delete token");
Expand Down
9 changes: 9 additions & 0 deletions core/src/model/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,12 @@ pub enum ChannelMode {
#[serde(rename = "performance")]
Performance,
}

impl ChannelMode {
pub fn context_number(&self) -> usize {
match self {
ChannelMode::Balanced => 6,
ChannelMode::Performance => 10,
}
}
}
1 change: 1 addition & 0 deletions core/src/model/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl Msg {
#[inline]
pub fn cont_list(&self) -> &Vec<MsgCont> { &self.cont_list }

#[inline]
pub fn create_at(&self) -> &DateTime<Utc> { &self.created_at }
}

Expand Down
12 changes: 11 additions & 1 deletion core/src/service/open_ai.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use futures_util::{Stream, StreamExt};
use reqwest_eventsource::Event;
use serde::{Deserialize, Serialize};

use crate::error::PolestarError;
use crate::{error::PolestarError, model::MsgRole};

#[derive(Debug, Deserialize, Clone, Serialize)]
pub struct CreateChatCompletionStreamResponse {
Expand Down Expand Up @@ -44,6 +44,16 @@ pub enum Role {
Function,
}

impl From<MsgRole> for Role {
fn from(role: MsgRole) -> Self {
match role {
MsgRole::System(_) => Role::System,
MsgRole::User => Role::User,
MsgRole::Bot(_) => Role::Assistant,
}
}
}

pub async fn deal_open_ai_stream(
stream: &mut (impl Stream<Item = Result<Event, reqwest_eventsource::Error>> + Unpin),
mut delta_op: impl FnMut(String),
Expand Down
54 changes: 49 additions & 5 deletions core/src/service/req.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ use serde_json_path::JsonPath;
use crate::{
error::{PolestarError, PolestarResult},
model::{
AppInfo, Bot, BotId, FeedbackMessageListForServer, FeedbackTimestamp, GlbVar, Quota,
AppInfo, Bot, BotId, Channel, FeedbackMessageListForServer, FeedbackTimestamp, GlbVar, Quota,
ServerProvider, UserFeedbackMessageForServer, GLOBAL_VARS,
},
};

use super::open_ai::{ChatCompletionResponseStreamMessage, Role};

const POLESTAR_STREAM_URL: &str = "https://api.ribir.org/stream/open_ai";

pub fn req_builder(
Expand Down Expand Up @@ -63,6 +65,51 @@ pub fn create_text_request(info: &AppInfo, bot_id: BotId) -> TextStreamReq {
}
}

pub fn open_ai_request_content<'a>(bot: &'a Bot, channel: &'a Channel, content: &'a str) -> String {
let mut messages = vec![];
if let Some(prompt) = bot.params().get("prompt").and_then(|v| v.as_str()) {
messages.push(ChatCompletionResponseStreamMessage {
content: Some(prompt.to_string()),
role: Some(super::open_ai::Role::System),
});
}
let context_numbers = channel.cfg().mode().context_number();
let content_with_context = channel
.msgs()
.iter()
.rev()
.skip(2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the msg iter can be pass from the caller, skip(2) is odd

.take(context_numbers)
.rev()
.map(|m| {
let quote_text = m.meta().quote_id().and_then(|id| {
channel
.msg(id)
.and_then(|m| m.cur_cont_ref().text().map(|s| s.to_owned()))
});
let cont_text = m.cur_cont_ref().text().map(|s| s.to_owned());
ChatCompletionResponseStreamMessage {
content: Some(quote_text.unwrap_or_default() + &cont_text.unwrap_or_default()),
role: Some(Role::from(m.role().clone())),
}
})
.collect::<Vec<_>>();
messages.extend(content_with_context);
messages.push(ChatCompletionResponseStreamMessage {
content: Some(content.to_owned()),
role: Some(Role::User),
});

// TODO:
let params = json!({
"model": "gpt-3.5-turbo",
"messages": messages,
"stream": true,
});

serde_json::to_string(&params).unwrap_or_default()
}

fn default_polestar_provider(model: &str, info: &AppInfo) -> Option<ServerProvider> {
if model == "OpenAI" {
if let Some(polestar_token) = info.user().and_then(|user| user.token()) {
Expand Down Expand Up @@ -151,17 +198,14 @@ pub async fn req_feedback(content: String) -> Result<(), PolestarError> {
}
}

#[derive(Debug)]
pub struct TextStreamReq {
url: String,
headers: HeaderMap,
}

impl TextStreamReq {
pub async fn request(self, body: String) -> Result<EventSource, PolestarError> {
let body = format!(
r#"{{"model":"gpt-3.5-turbo","messages":[{{"role":"user","content":"{}"}}],"stream":true}}"#,
body
);
req_stream(
self.url.clone(),
Method::POST,
Expand Down
43 changes: 38 additions & 5 deletions core/src/utils/fs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::path::PathBuf;
use std::path::{Path, PathBuf};

use home::home_dir;

Expand All @@ -15,6 +15,7 @@ static CURRENT_USER: &str = "current_user";
static NONCE_FILE: &str = "nonce";
static TOKEN_FILE: &str = "token";
static LOCAL_STATE: &str = "local_state";
static POLESTAR_STATIC: &str = "static";

pub fn project_home_path() -> PathBuf {
home_dir()
Expand Down Expand Up @@ -103,6 +104,14 @@ pub fn create_if_not_exist_dir(path: PathBuf) {
}
}

pub fn get_static_file(file: &str) -> PolestarResult<Vec<u8>> {
let mut path = project_home_path();
path.push(POLESTAR_STATIC);
path.push(file);
let content = std::fs::read(&path)?;
Ok(content)
}

pub mod encrypt {
use std::{fs::File, io::Write};

Expand Down Expand Up @@ -156,18 +165,18 @@ pub mod encrypt {
}

pub mod launch {
use std::{fs, io::Write};
use std::{fs, io::Write, path::PathBuf};

use super::{
create_if_not_exist_dir, project_bot_config_path, project_config_path, project_home_path,
project_user_path,
copy_dir_all, create_if_not_exist_dir, project_bot_config_path, project_config_path,
project_home_path, project_user_path, POLESTAR_STATIC,
};

pub fn setup_project() {
create_if_not_exist_dir(project_home_path());
create_if_not_exist_dir(project_user_path());
create_if_not_exist_dir(project_config_path());
write_default_bot_config();
copy_static_files_to_user_data();
}

pub fn write_default_bot_config() {
Expand All @@ -183,4 +192,28 @@ pub mod launch {
.write_all(content.as_bytes())
.expect("can't write bot.json");
}

pub fn copy_static_files_to_user_data() {
let mut src = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
src.push("../gui/static");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is CARGO_MANIFEST_DIR valid after pack to install package

let mut dst = project_home_path();
dst.push(POLESTAR_STATIC);
copy_dir_all(src, dst).expect("Failed to copy static files");
}
}

use std::{fs, io};

fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
fs::create_dir_all(&dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let ty = entry.file_type()?;
if ty.is_dir() {
copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?;
} else {
fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
}
}
Ok(())
}
15 changes: 2 additions & 13 deletions core/src/utils/local_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,15 @@ use uuid::Uuid;
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct LocalState {
cur_channel_id: Option<Uuid>,
quick_launcher_id: Option<Uuid>,
uid: Option<u64>,
}

impl LocalState {
pub fn new(
cur_channel_id: Option<Uuid>,
quick_launcher_id: Option<Uuid>,
uid: Option<u64>,
) -> Self {
Self {
cur_channel_id,
quick_launcher_id,
uid,
}
pub fn new(cur_channel_id: Option<Uuid>, uid: Option<u64>) -> Self {
Self { cur_channel_id, uid }
}

pub fn cur_channel_id(&self) -> &Option<Uuid> { &self.cur_channel_id }

pub fn quick_launcher_id(&self) -> &Option<Uuid> { &self.quick_launcher_id }

pub fn uid(&self) -> &Option<u64> { &self.uid }
}
4 changes: 2 additions & 2 deletions gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ description.workspace = true

[dependencies]
polestar-core = { path = "../core", features = ["persistence"] }
ribir = { git = "https://github.com/RibirX/Ribir", features = ["png", "tokio-async"] }
ribir_algo = { git = "https://github.com/RibirX/Ribir" }
ribir = { version= "0.1.0-alpha.0", features = ["png", "tokio-async"] }
ribir_algo = "0.1.0-alpha.0"

serde.workspace = true
serde_json.workspace = true
Expand Down
63 changes: 0 additions & 63 deletions gui/src/hotkey.rs

This file was deleted.

Loading
Loading