mirror of
https://github.com/aljazceru/notedeck.git
synced 2025-12-18 17:14:21 +01:00
dave: include anonymous user identifier in api call
- don't include users pubkey This could be used to associate requests with real users, rendering the anonymized user_id pointless TODO: Implement a new tool call that lets dave ask for your pubkey Fixes: #834 Fixes: #836 Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -3281,6 +3281,7 @@ dependencies = [
|
||||
"rand 0.9.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use enostr::Keypair;
|
||||
use enostr::{Keypair, KeypairUnowned};
|
||||
use tokenator::{ParseError, TokenParser, TokenSerializable};
|
||||
|
||||
use crate::wallet::ZapWallet;
|
||||
@@ -13,6 +13,13 @@ impl UserAccount {
|
||||
Self { key, wallet: None }
|
||||
}
|
||||
|
||||
pub fn keypair(&self) -> KeypairUnowned {
|
||||
KeypairUnowned {
|
||||
pubkey: &self.key.pubkey,
|
||||
secret_key: self.key.secret_key.as_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_wallet(mut self, wallet: ZapWallet) -> Self {
|
||||
self.wallet = Some(wallet);
|
||||
self
|
||||
|
||||
@@ -6,6 +6,7 @@ version.workspace = true
|
||||
[dependencies]
|
||||
async-openai = "0.28.0"
|
||||
egui = { workspace = true }
|
||||
sha2 = { workspace = true }
|
||||
notedeck = { workspace = true }
|
||||
notedeck_ui = { workspace = true }
|
||||
eframe = { workspace = true }
|
||||
|
||||
@@ -5,6 +5,7 @@ use async_openai::{
|
||||
};
|
||||
use chrono::{Duration, Local};
|
||||
use egui_wgpu::RenderState;
|
||||
use enostr::KeypairUnowned;
|
||||
use futures::StreamExt;
|
||||
use nostrdb::Transaction;
|
||||
use notedeck::{AppAction, AppContext};
|
||||
@@ -37,20 +38,31 @@ pub struct Dave {
|
||||
/// A 3d representation of dave.
|
||||
avatar: Option<DaveAvatar>,
|
||||
input: String,
|
||||
pubkey: String,
|
||||
tools: Arc<HashMap<String, Tool>>,
|
||||
client: async_openai::Client<OpenAIConfig>,
|
||||
incoming_tokens: Option<Receiver<DaveApiResponse>>,
|
||||
model_config: ModelConfig,
|
||||
}
|
||||
|
||||
/// Calculate an anonymous user_id from a keypair
|
||||
fn calculate_user_id(keypair: KeypairUnowned) -> String {
|
||||
use sha2::{Digest, Sha256};
|
||||
// pubkeys have degraded privacy, don't do that
|
||||
let key_input = keypair
|
||||
.secret_key
|
||||
.map(|sk| sk.as_secret_bytes())
|
||||
.unwrap_or(keypair.pubkey.bytes());
|
||||
let hex_key = hex::encode(key_input);
|
||||
let input = format!("{hex_key}notedeck_dave_user_id");
|
||||
hex::encode(Sha256::digest(input))
|
||||
}
|
||||
|
||||
impl Dave {
|
||||
pub fn avatar_mut(&mut self) -> Option<&mut DaveAvatar> {
|
||||
self.avatar.as_mut()
|
||||
}
|
||||
|
||||
fn system_prompt() -> Message {
|
||||
let pubkey = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245".to_string();
|
||||
let now = Local::now();
|
||||
let yesterday = now - Duration::hours(24);
|
||||
let date = now.format("%Y-%m-%d %H:%M:%S");
|
||||
@@ -65,8 +77,6 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
|
||||
|
||||
- Yesterday (-24hrs) was {yesterday_timestamp}. You can use this in combination with `since` queries for pulling notes for summarizing notes the user might have missed while they were away.
|
||||
|
||||
- The current users pubkey is {pubkey}
|
||||
|
||||
# Response Guidelines
|
||||
|
||||
- You *MUST* call the present_notes tool with a list of comma-separated note id references when referring to notes so that the UI can display them. Do *NOT* include note id references in the text response, but you *SHOULD* use ^1, ^2, etc to reference note indices passed to present_notes.
|
||||
@@ -84,19 +94,18 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
|
||||
let input = "".to_string();
|
||||
let avatar = render_state.map(DaveAvatar::new);
|
||||
let mut tools: HashMap<String, Tool> = HashMap::new();
|
||||
let pubkey = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245".to_string();
|
||||
for tool in tools::dave_tools() {
|
||||
tools.insert(tool.name().to_string(), tool);
|
||||
}
|
||||
|
||||
Dave {
|
||||
client,
|
||||
pubkey: pubkey.clone(),
|
||||
avatar,
|
||||
incoming_tokens: None,
|
||||
tools: Arc::new(tools),
|
||||
input,
|
||||
model_config,
|
||||
chat: vec![Self::system_prompt()],
|
||||
chat: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +179,7 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
|
||||
}
|
||||
|
||||
fn handle_new_chat(&mut self) {
|
||||
self.chat = vec![Self::system_prompt()];
|
||||
self.chat = vec![];
|
||||
self.input.clear();
|
||||
}
|
||||
|
||||
@@ -190,7 +199,13 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
|
||||
.collect()
|
||||
};
|
||||
tracing::debug!("sending messages, latest: {:?}", messages.last().unwrap());
|
||||
let pubkey = self.pubkey.clone();
|
||||
|
||||
let user_id = app_ctx
|
||||
.accounts
|
||||
.get_selected_account()
|
||||
.map(|sa| calculate_user_id(sa.keypair()))
|
||||
.unwrap_or_else(|| "unknown_user".to_string());
|
||||
|
||||
let ctx = ctx.clone();
|
||||
let client = self.client.clone();
|
||||
let tools = self.tools.clone();
|
||||
@@ -207,7 +222,7 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
|
||||
stream: Some(true),
|
||||
messages,
|
||||
tools: Some(tools::dave_tools().iter().map(|t| t.to_api()).collect()),
|
||||
user: Some(pubkey),
|
||||
user: Some(user_id),
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@@ -321,6 +336,11 @@ impl notedeck::App for Dave {
|
||||
*/
|
||||
let mut app_action: Option<AppAction> = None;
|
||||
|
||||
// always insert system prompt if we have no context
|
||||
if self.chat.is_empty() {
|
||||
self.chat.push(Dave::system_prompt());
|
||||
}
|
||||
|
||||
//update_dave(self, ctx, ui.ctx());
|
||||
let should_send = self.process_events(ctx);
|
||||
if let Some(action) = self.ui(ctx, ui).action {
|
||||
|
||||
Reference in New Issue
Block a user