@sesamespace/hivemind 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -0
- package/config/TEAM-CHARTER.md +87 -0
- package/config/default.toml +39 -0
- package/dist/__tests__/fleet-integration.test.d.ts +9 -0
- package/dist/__tests__/fleet-integration.test.d.ts.map +1 -0
- package/dist/__tests__/fleet-integration.test.js +201 -0
- package/dist/__tests__/fleet-integration.test.js.map +1 -0
- package/dist/__tests__/fleet.test.d.ts +7 -0
- package/dist/__tests__/fleet.test.d.ts.map +1 -0
- package/dist/__tests__/fleet.test.js +171 -0
- package/dist/__tests__/fleet.test.js.map +1 -0
- package/dist/__tests__/integration.test.d.ts +2 -0
- package/dist/__tests__/integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration.test.js +348 -0
- package/dist/__tests__/integration.test.js.map +1 -0
- package/dist/agent.d.ts +27 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +217 -0
- package/dist/agent.js.map +1 -0
- package/dist/commands/fleet.d.ts +13 -0
- package/dist/commands/fleet.d.ts.map +1 -0
- package/dist/commands/fleet.js +193 -0
- package/dist/commands/fleet.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +170 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/start.d.ts +2 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +39 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +73 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +50 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +153 -0
- package/dist/context.js.map +1 -0
- package/dist/fleet/fleet-manager.d.ts +86 -0
- package/dist/fleet/fleet-manager.d.ts.map +1 -0
- package/dist/fleet/fleet-manager.js +298 -0
- package/dist/fleet/fleet-manager.js.map +1 -0
- package/dist/fleet/memory-sync.d.ts +91 -0
- package/dist/fleet/memory-sync.d.ts.map +1 -0
- package/dist/fleet/memory-sync.js +292 -0
- package/dist/fleet/memory-sync.js.map +1 -0
- package/dist/fleet/primary-client.d.ts +49 -0
- package/dist/fleet/primary-client.d.ts.map +1 -0
- package/dist/fleet/primary-client.js +222 -0
- package/dist/fleet/primary-client.js.map +1 -0
- package/dist/fleet/worker-protocol.d.ts +125 -0
- package/dist/fleet/worker-protocol.d.ts.map +1 -0
- package/dist/fleet/worker-protocol.js +27 -0
- package/dist/fleet/worker-protocol.js.map +1 -0
- package/dist/fleet/worker-server.d.ts +53 -0
- package/dist/fleet/worker-server.d.ts.map +1 -0
- package/dist/fleet/worker-server.js +191 -0
- package/dist/fleet/worker-server.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/llm-client.d.ts +24 -0
- package/dist/llm-client.d.ts.map +1 -0
- package/dist/llm-client.js +40 -0
- package/dist/llm-client.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +41 -0
- package/dist/main.js.map +1 -0
- package/dist/memory-client.d.ts +88 -0
- package/dist/memory-client.d.ts.map +1 -0
- package/dist/memory-client.js +185 -0
- package/dist/memory-client.js.map +1 -0
- package/dist/pipeline.d.ts +2 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +125 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/prompt.d.ts +6 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +75 -0
- package/dist/prompt.js.map +1 -0
- package/dist/sesame.d.ts +33 -0
- package/dist/sesame.d.ts.map +1 -0
- package/dist/sesame.js +67 -0
- package/dist/sesame.js.map +1 -0
- package/dist/start.d.ts +3 -0
- package/dist/start.d.ts.map +1 -0
- package/dist/start.js +20 -0
- package/dist/start.js.map +1 -0
- package/dist/task-engine.d.ts +32 -0
- package/dist/task-engine.d.ts.map +1 -0
- package/dist/task-engine.js +80 -0
- package/dist/task-engine.js.map +1 -0
- package/dist/worker.d.ts +73 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +279 -0
- package/dist/worker.js.map +1 -0
- package/install.sh +186 -0
- package/package.json +36 -0
- package/packages/memory/Cargo.lock +6480 -0
- package/packages/memory/Cargo.toml +21 -0
- package/packages/memory/src/src/context.rs +179 -0
- package/packages/memory/src/src/embeddings.rs +51 -0
- package/packages/memory/src/src/main.rs +626 -0
- package/packages/memory/src/src/promotion.rs +637 -0
- package/packages/memory/src/src/scoring.rs +131 -0
- package/packages/memory/src/src/store.rs +460 -0
- package/packages/memory/src/src/tasks.rs +321 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "hivemind-memory"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
|
|
6
|
+
[dependencies]
|
|
7
|
+
axum = "0.7"
|
|
8
|
+
tokio = { version = "1", features = ["full"] }
|
|
9
|
+
serde = { version = "1", features = ["derive"] }
|
|
10
|
+
serde_json = "1"
|
|
11
|
+
lancedb = "0.15"
|
|
12
|
+
arrow-array = "53"
|
|
13
|
+
arrow-schema = "53"
|
|
14
|
+
reqwest = { version = "0.12", features = ["json"] }
|
|
15
|
+
uuid = { version = "1", features = ["v4"] }
|
|
16
|
+
chrono = { version = "0.4", features = ["serde"] }
|
|
17
|
+
tracing = "0.1"
|
|
18
|
+
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
19
|
+
tower-http = { version = "0.5", features = ["cors", "trace"] }
|
|
20
|
+
anyhow = "1"
|
|
21
|
+
futures = "0.3"
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
use anyhow::Result;
|
|
2
|
+
use arrow_array::{RecordBatch, RecordBatchIterator, StringArray};
|
|
3
|
+
use arrow_schema::{DataType, Field, Schema};
|
|
4
|
+
use chrono::Utc;
|
|
5
|
+
use futures::stream::TryStreamExt;
|
|
6
|
+
use lancedb::{connection::Connection, query::ExecutableQuery, query::QueryBase, Table};
|
|
7
|
+
use serde::{Deserialize, Serialize};
|
|
8
|
+
use std::sync::Arc;
|
|
9
|
+
use uuid;
|
|
10
|
+
|
|
11
|
+
const CONTEXTS_TABLE: &str = "contexts";
|
|
12
|
+
|
|
13
|
+
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
14
|
+
pub struct ContextMetadata {
|
|
15
|
+
pub name: String,
|
|
16
|
+
pub description: String,
|
|
17
|
+
pub created_at: String,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
pub struct ContextStore {
|
|
21
|
+
db: Connection,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
impl ContextStore {
|
|
25
|
+
pub async fn new(db: Connection) -> Result<Self> {
|
|
26
|
+
let store = Self { db };
|
|
27
|
+
store.ensure_table().await?;
|
|
28
|
+
Ok(store)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fn schema() -> Arc<Schema> {
|
|
32
|
+
Arc::new(Schema::new(vec![
|
|
33
|
+
Field::new("name", DataType::Utf8, false),
|
|
34
|
+
Field::new("description", DataType::Utf8, false),
|
|
35
|
+
Field::new("created_at", DataType::Utf8, false),
|
|
36
|
+
]))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async fn ensure_table(&self) -> Result<()> {
|
|
40
|
+
let names = self.db.table_names().execute().await?;
|
|
41
|
+
if !names.contains(&CONTEXTS_TABLE.to_string()) {
|
|
42
|
+
let schema = Self::schema();
|
|
43
|
+
let batch = RecordBatch::new_empty(schema.clone());
|
|
44
|
+
let batches = RecordBatchIterator::new(vec![Ok(batch)], schema);
|
|
45
|
+
self.db
|
|
46
|
+
.create_table(CONTEXTS_TABLE, Box::new(batches))
|
|
47
|
+
.execute()
|
|
48
|
+
.await?;
|
|
49
|
+
tracing::info!("Created contexts metadata table");
|
|
50
|
+
}
|
|
51
|
+
Ok(())
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
pub async fn create_context(&self, name: &str, description: &str) -> Result<ContextMetadata> {
|
|
55
|
+
// Check if context already exists
|
|
56
|
+
if let Some(existing) = self.get_context(name).await? {
|
|
57
|
+
return Ok(existing);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let created_at = Utc::now().to_rfc3339();
|
|
61
|
+
|
|
62
|
+
let metadata = ContextMetadata {
|
|
63
|
+
name: name.to_string(),
|
|
64
|
+
description: description.to_string(),
|
|
65
|
+
created_at: created_at.clone(),
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
let schema = Self::schema();
|
|
69
|
+
let batch = RecordBatch::try_new(
|
|
70
|
+
schema.clone(),
|
|
71
|
+
vec![
|
|
72
|
+
Arc::new(StringArray::from(vec![name])),
|
|
73
|
+
Arc::new(StringArray::from(vec![description])),
|
|
74
|
+
Arc::new(StringArray::from(vec![created_at.as_str()])),
|
|
75
|
+
],
|
|
76
|
+
)?;
|
|
77
|
+
|
|
78
|
+
let table = self.db.open_table(CONTEXTS_TABLE).execute().await?;
|
|
79
|
+
let batches = RecordBatchIterator::new(vec![Ok(batch)], schema);
|
|
80
|
+
table.add(Box::new(batches)).execute().await?;
|
|
81
|
+
|
|
82
|
+
tracing::info!("Created context: {}", name);
|
|
83
|
+
Ok(metadata)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
pub async fn get_context(&self, name: &str) -> Result<Option<ContextMetadata>> {
|
|
87
|
+
let table = self.db.open_table(CONTEXTS_TABLE).execute().await?;
|
|
88
|
+
let results = table
|
|
89
|
+
.query()
|
|
90
|
+
.only_if(format!("name = '{}'", name))
|
|
91
|
+
.execute()
|
|
92
|
+
.await?;
|
|
93
|
+
|
|
94
|
+
let batches: Vec<RecordBatch> = results.try_collect().await?;
|
|
95
|
+
for batch in &batches {
|
|
96
|
+
if batch.num_rows() > 0 {
|
|
97
|
+
let names = batch
|
|
98
|
+
.column_by_name("name")
|
|
99
|
+
.unwrap()
|
|
100
|
+
.as_any()
|
|
101
|
+
.downcast_ref::<StringArray>()
|
|
102
|
+
.unwrap();
|
|
103
|
+
let descriptions = batch
|
|
104
|
+
.column_by_name("description")
|
|
105
|
+
.unwrap()
|
|
106
|
+
.as_any()
|
|
107
|
+
.downcast_ref::<StringArray>()
|
|
108
|
+
.unwrap();
|
|
109
|
+
let created_ats = batch
|
|
110
|
+
.column_by_name("created_at")
|
|
111
|
+
.unwrap()
|
|
112
|
+
.as_any()
|
|
113
|
+
.downcast_ref::<StringArray>()
|
|
114
|
+
.unwrap();
|
|
115
|
+
|
|
116
|
+
return Ok(Some(ContextMetadata {
|
|
117
|
+
name: names.value(0).to_string(),
|
|
118
|
+
description: descriptions.value(0).to_string(),
|
|
119
|
+
created_at: created_ats.value(0).to_string(),
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
Ok(None)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
pub async fn list_contexts(&self) -> Result<Vec<ContextMetadata>> {
|
|
128
|
+
let table = self.db.open_table(CONTEXTS_TABLE).execute().await?;
|
|
129
|
+
let results = table.query().execute().await?;
|
|
130
|
+
|
|
131
|
+
let batches: Vec<RecordBatch> = results.try_collect().await?;
|
|
132
|
+
let mut contexts = Vec::new();
|
|
133
|
+
|
|
134
|
+
for batch in &batches {
|
|
135
|
+
let names = batch
|
|
136
|
+
.column_by_name("name")
|
|
137
|
+
.unwrap()
|
|
138
|
+
.as_any()
|
|
139
|
+
.downcast_ref::<StringArray>()
|
|
140
|
+
.unwrap();
|
|
141
|
+
let descriptions = batch
|
|
142
|
+
.column_by_name("description")
|
|
143
|
+
.unwrap()
|
|
144
|
+
.as_any()
|
|
145
|
+
.downcast_ref::<StringArray>()
|
|
146
|
+
.unwrap();
|
|
147
|
+
let created_ats = batch
|
|
148
|
+
.column_by_name("created_at")
|
|
149
|
+
.unwrap()
|
|
150
|
+
.as_any()
|
|
151
|
+
.downcast_ref::<StringArray>()
|
|
152
|
+
.unwrap();
|
|
153
|
+
|
|
154
|
+
for i in 0..batch.num_rows() {
|
|
155
|
+
contexts.push(ContextMetadata {
|
|
156
|
+
name: names.value(i).to_string(),
|
|
157
|
+
description: descriptions.value(i).to_string(),
|
|
158
|
+
created_at: created_ats.value(i).to_string(),
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
Ok(contexts)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
pub async fn delete_context(&self, name: &str) -> Result<bool> {
|
|
167
|
+
if name == "global" {
|
|
168
|
+
anyhow::bail!("Cannot delete global context");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
let table = self.db.open_table(CONTEXTS_TABLE).execute().await?;
|
|
172
|
+
table
|
|
173
|
+
.delete(&format!("name = '{}'", name))
|
|
174
|
+
.await?;
|
|
175
|
+
|
|
176
|
+
tracing::info!("Deleted context metadata: {}", name);
|
|
177
|
+
Ok(true)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
use anyhow::Result;
|
|
2
|
+
use serde::{Deserialize, Serialize};
|
|
3
|
+
|
|
4
|
+
pub struct OllamaClient {
|
|
5
|
+
base_url: String,
|
|
6
|
+
model: String,
|
|
7
|
+
http: reqwest::Client,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
#[derive(Serialize)]
|
|
11
|
+
struct EmbedRequest {
|
|
12
|
+
model: String,
|
|
13
|
+
input: String,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#[derive(Deserialize)]
|
|
17
|
+
struct EmbedResponse {
|
|
18
|
+
embeddings: Vec<Vec<f32>>,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
impl OllamaClient {
|
|
22
|
+
pub fn new(base_url: &str, model: &str) -> Self {
|
|
23
|
+
Self {
|
|
24
|
+
base_url: base_url.to_string(),
|
|
25
|
+
model: model.to_string(),
|
|
26
|
+
http: reqwest::Client::new(),
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
pub async fn embed(&self, text: &str) -> Result<Vec<f32>> {
|
|
31
|
+
let url = format!("{}/api/embed", self.base_url);
|
|
32
|
+
let req = EmbedRequest {
|
|
33
|
+
model: self.model.clone(),
|
|
34
|
+
input: text.to_string(),
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
let resp = self
|
|
38
|
+
.http
|
|
39
|
+
.post(&url)
|
|
40
|
+
.json(&req)
|
|
41
|
+
.send()
|
|
42
|
+
.await?
|
|
43
|
+
.error_for_status()?;
|
|
44
|
+
|
|
45
|
+
let body: EmbedResponse = resp.json().await?;
|
|
46
|
+
body.embeddings
|
|
47
|
+
.into_iter()
|
|
48
|
+
.next()
|
|
49
|
+
.ok_or_else(|| anyhow::anyhow!("No embedding returned from Ollama"))
|
|
50
|
+
}
|
|
51
|
+
}
|