Skip to content

Commit

Permalink
Merge pull request #208 from dcSpark/rob/finishing-vec-fs-impl
Browse files Browse the repository at this point in the history
Resource-Related Node Changes To Prepare For Release
  • Loading branch information
robkorn authored Jan 26, 2024
2 parents 10cb5ee + 84eeae6 commit 229bdda
Show file tree
Hide file tree
Showing 29 changed files with 546 additions and 1,074 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use crate::{
shinkai_utils::shinkai_logging::{shinkai_log, ShinkaiLogLevel, ShinkaiLogOption},
};
use regex::Regex;
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
#[derive(Debug, Clone, Eq, Hash)]
pub struct ShinkaiName {
pub full_name: String,
pub node_name: String,
Expand Down Expand Up @@ -498,3 +498,35 @@ impl AsRef<str> for ShinkaiName {
&self.full_name
}
}

impl Serialize for ShinkaiName {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = self.full_name.clone();
serializer.serialize_str(&s)
}
}

impl<'de> Deserialize<'de> for ShinkaiName {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
ShinkaiName::new(s).map_err(serde::de::Error::custom)
}
}

impl PartialEq for ShinkaiName {
fn eq(&self, other: &Self) -> bool {
self.full_name.to_lowercase() == other.full_name.to_lowercase()
&& self.node_name.to_lowercase() == other.node_name.to_lowercase()
&& self.profile_name.as_ref().map(|s| s.to_lowercase())
== other.profile_name.as_ref().map(|s| s.to_lowercase())
&& self.subidentity_type == other.subidentity_type
&& self.subidentity_name.as_ref().map(|s| s.to_lowercase())
== other.subidentity_name.as_ref().map(|s| s.to_lowercase())
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use shinkai_vector_resources::vector_resource::VRPath;
use shinkai_vector_resources::vector_resource::{VectorResource, VectorResourceCore};
use shinkai_vector_resources::{
source::{SourceFile, VRSource},
Expand All @@ -8,29 +9,29 @@ use shinkai_vector_resources::{
use std::fmt;

#[derive(Serialize, Deserialize, Clone, PartialEq)]
/// Job's scope which includes both local entries (source/vector resource stored locally only in job)
/// and DB entries (source/vector resource stored in the DB, accessible to all jobs)
/// Job's scope which includes both Local entries (source/vector resource stored locally only in job)
/// and VecFS entries (source/vector resource stored in the DB, accessible to all jobs)
pub struct JobScope {
pub local: Vec<LocalScopeEntry>,
pub database: Vec<DBScopeEntry>,
pub vector_fs: Vec<VectorFSScopeEntry>,
}

impl JobScope {}
impl JobScope {
pub fn new(local: Vec<LocalScopeEntry>, database: Vec<DBScopeEntry>) -> Self {
Self { local, database }
pub fn new(local: Vec<LocalScopeEntry>, vector_fs: Vec<VectorFSScopeEntry>) -> Self {
Self { local, vector_fs }
}

pub fn new_default() -> Self {
Self {
local: Vec::new(),
database: Vec::new(),
vector_fs: Vec::new(),
}
}

/// Checks if the Job Scope is empty (has no entries pointing to VRs)
pub fn is_empty(&self) -> bool {
self.local.is_empty() && self.database.is_empty()
self.local.is_empty() && self.vector_fs.is_empty()
}

pub fn to_bytes(&self) -> serde_json::Result<Vec<u8>> {
Expand Down Expand Up @@ -64,24 +65,24 @@ impl fmt::Debug for JobScope {
})
.collect();

let db_ids: Vec<String> = self
.database
let vector_fs_ids: Vec<String> = self
.vector_fs
.iter()
.map(|entry| entry.resource_header.reference_string())
.collect();

f.debug_struct("JobScope")
.field("local", &format_args!("{:?}", local_ids))
.field("database", &format_args!("{:?}", db_ids))
.field("vector_fs", &format_args!("{:?}", vector_fs_ids))
.finish()
}
}

/// Enum holding both Local and DB scope entries
/// Enum holding both Local and VectorFS scope entries
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum ScopeEntry {
Local(LocalScopeEntry),
Database(DBScopeEntry),
VectorFS(VectorFSScopeEntry),
}

/// A Scope Entry for a local file/vector resource that only lives in the
Expand All @@ -92,9 +93,9 @@ pub struct LocalScopeEntry {
pub source: SourceFile,
}

/// A Scope Entry for a file/vector resource that is saved in the DB
/// A Scope Entry for a file/vector resource that is saved in the VectorFS
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct DBScopeEntry {
pub struct VectorFSScopeEntry {
pub resource_header: VRHeader,
pub source: VRSource,
pub vector_fs_path: VRPath,
}
6 changes: 3 additions & 3 deletions shinkai-libs/shinkai-message-pyo3/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Create a virtual environment if it doesn't exist
if [ ! -d "./venv" ]
then
python -m venv venv
python3 -m venv venv
fi

# Activate your virtual environment
Expand All @@ -13,7 +13,7 @@ source ./venv/bin/activate
rm ./target/wheels/shinkai_message_pyo3*.whl

# Run maturin develop and capture its output
output=$(maturin build -i python)
output=$(maturin build -i python3)

# If maturin develop is successful, extract the path of the built wheel file
if [ $? -eq 0 ]; then
Expand All @@ -27,4 +27,4 @@ if [ $? -eq 0 ]; then
python3 -m unittest tests.test_shinkai_message_pyo3
else
echo "maturin develop failed"
fi
fi
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
use pyo3::types::PyString;
use shinkai_message_primitives::shinkai_utils::job_scope::DBScopeEntry;
use pyo3::wrap_pyfunction;
use shinkai_message_primitives::shinkai_utils::job_scope::JobScope;
use shinkai_message_primitives::shinkai_utils::job_scope::LocalScopeEntry;
use shinkai_message_primitives::shinkai_utils::job_scope::VectorFSScopeEntry;

#[pyclass]
#[derive(Debug, Clone)]
Expand All @@ -14,26 +14,34 @@ pub struct PyJobScope {
#[pymethods]
impl PyJobScope {
#[new]
pub fn new() -> Self { // TODO: Someday add args
Self { inner: JobScope::new(Vec::new(), Vec::new()) }
pub fn new() -> Self {
// TODO: Someday add args
Self {
inner: JobScope::new(Vec::new(), Vec::new()),
}
}

#[staticmethod]
pub fn new_empty() -> Self {
Self { inner: JobScope::new(Vec::new(), Vec::new()) }
Self {
inner: JobScope::new(Vec::new(), Vec::new()),
}
}

#[staticmethod]
pub fn from_json_str(s: &str) -> PyResult<Self> {
let inner = JobScope::from_json_str(s).map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))?;
let inner =
JobScope::from_json_str(s).map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))?;
Ok(Self { inner })
}

pub fn to_json_str(&self) -> PyResult<String> {
self.inner.to_json_str().map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))
self.inner
.to_json_str()
.map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))
}

pub fn is_empty(&self) -> bool {
self.inner.local.is_empty() && self.inner.database.is_empty()
self.inner.local.is_empty() && self.inner.vector_fs.is_empty()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def test_job_creation(self):
result_json = json.loads(result)

# Add assertions to check the fields of the result
self.assertEqual(result_json["body"]["unencrypted"]["message_data"]["unencrypted"]["message_raw_content"], "{\"scope\":{\"local\":[],\"database\":[]}}")
self.assertEqual(result_json["body"]["unencrypted"]["message_data"]["unencrypted"]["message_raw_content"], "{\"scope\":{\"local\":[],\"vector_fs\":[]}}")
self.assertEqual(result_json["body"]["unencrypted"]["message_data"]["unencrypted"]["message_content_schema"], "JobCreationSchema")
self.assertEqual(result_json["body"]["unencrypted"]["internal_metadata"]["sender_subidentity"], "main")
self.assertEqual(result_json["body"]["unencrypted"]["internal_metadata"]["recipient_subidentity"], "main/agent/agent_1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ mod tests {
// Check the content
// assert_eq!(content["inbox"], "inbox::@@node.shinkai::true");
// assert_eq!(content["is_e2e"], true);
// assert_eq!(content["identities"][0]["full_name"], "@@node.shinkai");
// assert_eq!(content["identities"][0], "@@node.shinkai");
// assert_eq!(content["identities"][0]["node_name"], "@@node.shinkai");
// assert_eq!(content["count"], 10);
// assert_eq!(content["offset"], "offset_string");
Expand Down Expand Up @@ -959,14 +959,8 @@ mod tests {
"inbox::@@node.shinkai::true"
);
assert_eq!(content["inbox_name"]["RegularInbox"]["is_e2e"], true);
assert_eq!(
content["inbox_name"]["RegularInbox"]["identities"][0]["full_name"],
"@@node.shinkai"
);
assert_eq!(
content["inbox_name"]["RegularInbox"]["identities"][0]["node_name"],
"@@node.shinkai"
);
assert_eq!(content["inbox_name"]["RegularInbox"]["identities"][0], "@@node.shinkai");
assert_eq!(content["inbox_name"]["RegularInbox"]["identities"][0], "@@node.shinkai");
assert_eq!(content["up_to_time"], "2023-07-02T20:53:34Z");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,14 @@ impl Node {
}
}

/// Attempts to return a reference to the VRHeader from the Node. Errors if content is not VRHeader
pub fn get_vr_header_content(&self) -> Result<&VRHeader, VRError> {
match &self.content {
NodeContent::VRHeader(vr_header) => Ok(vr_header),
_ => Err(VRError::ContentIsNonMatchingType),
}
}

/// Attempts to return a mutable reference to the text content from the Node. Errors if is different type
pub fn get_text_content_mut(&mut self) -> Result<&mut String, VRError> {
match &mut self.content {
Expand All @@ -389,6 +397,14 @@ impl Node {
}
}

/// Attempts to return a mutable reference to the VRHeader from the Node. Errors if content is not VRHeader
pub fn get_vr_header_content_mut(&mut self) -> Result<&mut VRHeader, VRError> {
match &mut self.content {
NodeContent::VRHeader(vr_header) => Ok(vr_header),
_ => Err(VRError::ContentIsNonMatchingType),
}
}

/// Returns the keys of all kv pairs in the Node's metadata field,
/// and all metadata keys of internal nodes for Vector Resources and VRHeaders.
/// None if no keys exist.
Expand Down Expand Up @@ -685,13 +701,19 @@ impl VRPath {
new_path
}

/// Creates a cloned VRPath and removes an element from the end
/// Returns a cloned VRPath with the last id removed from the end
pub fn pop_cloned(&self) -> Self {
let mut new_path = self.clone();
new_path.pop();
new_path
}

/// Returns a VRPath which is the path prior to self (the "parent path").
/// Ie. For path "/a/b/c", this will return "/a/b".
pub fn parent_path(&self) -> Self {
self.pop_cloned()
}

/// Create a VRPath from a path string
pub fn from_string(path_string: &str) -> Result<Self, VRError> {
if !path_string.starts_with('/') {
Expand Down
Loading

0 comments on commit 229bdda

Please sign in to comment.