...
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
module actionprocessor
|
||||
|
||||
|
||||
import freeflowuniverse.herolib.circles.models.core
|
||||
import freeflowuniverse.herolib.circles.dbs.core
|
||||
import freeflowuniverse.herolib.circles.models
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
import os
|
||||
|
||||
__global (
|
||||
circle_global map[string]&CircleCoordinator
|
||||
@@ -17,10 +16,10 @@ __global (
|
||||
pub struct CircleCoordinator {
|
||||
pub mut:
|
||||
name string //is a unique name on planetary scale is a dns name
|
||||
agents &core.AgentManager
|
||||
circles &core.CircleManager
|
||||
names &core.NameManager
|
||||
session_state model.SessionState
|
||||
agents &core.AgentDB
|
||||
// circles &core.CircleDB
|
||||
// names &core.NameDB
|
||||
session_state models.SessionState
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +29,7 @@ pub mut:
|
||||
name string = "local"
|
||||
pubkey string // pubkey of user who called this
|
||||
addr string //mycelium address
|
||||
path string
|
||||
}
|
||||
|
||||
// new creates a new CircleCoordinator instance
|
||||
@@ -38,12 +38,11 @@ pub fn new(args_ CircleCoordinatorArgs) !&CircleCoordinator {
|
||||
args.name = texttools.name_fix(args.name)
|
||||
|
||||
if args.name in circle_global {
|
||||
mut c:=circle_global[args.name]
|
||||
c.args = args
|
||||
mut c:=circle_global[args.name] or {panic("bug")}
|
||||
return c
|
||||
}
|
||||
|
||||
mut session_state:=models.new(name: args.name, pubkey: args.pubkey, addr: args.addr, path: args.path)!
|
||||
mut session_state:=models.new_session(name: args.name, pubkey: args.pubkey, addr: args.addr, path: args.path)!
|
||||
|
||||
// os.mkdir_all(mypath)!
|
||||
// Create the directories if they don't exist// SHOULD BE AUTOMATIC
|
||||
@@ -53,15 +52,15 @@ pub fn new(args_ CircleCoordinatorArgs) !&CircleCoordinator {
|
||||
// os.mkdir_all(os.join_path(mypath, 'meta_mcc'))! //message, contacts, calendar
|
||||
|
||||
|
||||
// Initialize the managers with proper ourdb instances
|
||||
mut agent_manager := core.new_agentmanager(session_state)!
|
||||
mut circle_manager := core.new_circlemanager(session_state)!
|
||||
mut name_manager := core.new_namemanager(session_state)!
|
||||
// Initialize the db handlers with proper ourdb instances
|
||||
mut agent_db := core.new_agentdb(session_state)!
|
||||
// mut circle_db := core.new_circledb(session_state)!
|
||||
// mut name_db := core.new_namedb(session_state)!
|
||||
|
||||
mut cm := &CircleCoordinator{
|
||||
agents: &agent_manager
|
||||
circles: &circle_manager
|
||||
names: &name_manager
|
||||
agents: &agent_db
|
||||
// circles: &circle_db
|
||||
// names: &name_db
|
||||
session_state: session_state
|
||||
}
|
||||
|
||||
|
||||
121
lib/circles/dbs/core/agent_db.v
Normal file
121
lib/circles/dbs/core/agent_db.v
Normal file
@@ -0,0 +1,121 @@
|
||||
module core
|
||||
|
||||
import freeflowuniverse.herolib.data.ourtime
|
||||
import freeflowuniverse.herolib.circles.models { DBHandler, SessionState }
|
||||
import freeflowuniverse.herolib.circles.models.core { Agent, AgentService, AgentServiceAction, AgentState }
|
||||
|
||||
|
||||
@[heap]
|
||||
pub struct AgentDB {
|
||||
pub mut:
|
||||
db DBHandler[Agent]
|
||||
}
|
||||
|
||||
pub fn new_agentdb(session_state SessionState) !AgentDB {
|
||||
return AgentDB{
|
||||
db:models.new_dbhandler[Agent]('agent', session_state)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut m AgentDB) new() Agent {
|
||||
return Agent{}
|
||||
}
|
||||
|
||||
// set adds or updates an agent
|
||||
pub fn (mut m AgentDB) set(agent Agent) !Agent {
|
||||
return m.db.set(agent)!
|
||||
}
|
||||
|
||||
// get retrieves an agent by its ID
|
||||
pub fn (mut m AgentDB) get(id u32) !Agent {
|
||||
return m.db.get(id)!
|
||||
}
|
||||
// list returns all agent IDs
|
||||
pub fn (mut m AgentDB) list() ![]u32 {
|
||||
return m.db.list()!
|
||||
}
|
||||
|
||||
pub fn (mut m AgentDB) getall() ![]Agent {
|
||||
return m.db.getall()!
|
||||
}
|
||||
|
||||
// delete removes an agent by its ID
|
||||
pub fn (mut m AgentDB) delete(id u32) ! {
|
||||
m.db.delete(id)!
|
||||
}
|
||||
|
||||
//////////////////CUSTOM METHODS//////////////////////////////////
|
||||
|
||||
// get_by_pubkey retrieves an agent by its public key
|
||||
pub fn (mut m AgentDB) get_by_pubkey(pubkey string) !Agent {
|
||||
return m.db.get_by_key('pubkey', pubkey)!
|
||||
}
|
||||
|
||||
// delete_by_pubkey removes an agent by its public key
|
||||
pub fn (mut m AgentDB) delete_by_pubkey(pubkey string) ! {
|
||||
// Get the agent by pubkey
|
||||
agent := m.get_by_pubkey(pubkey) or {
|
||||
// Agent not found, nothing to delete
|
||||
return
|
||||
}
|
||||
|
||||
// Delete the agent by ID
|
||||
m.delete(agent.id)!
|
||||
}
|
||||
|
||||
// update_status updates just the status of an agent
|
||||
pub fn (mut m AgentDB) update_status(pubkey string, status AgentState) !Agent {
|
||||
// Get the agent by pubkey
|
||||
mut agent := m.get_by_pubkey(pubkey)!
|
||||
|
||||
// Update the status
|
||||
agent.status.status = status
|
||||
agent.status.timestamp_last = ourtime.now()
|
||||
|
||||
// Save the updated agent
|
||||
return m.set(agent)!
|
||||
}
|
||||
|
||||
// get_all_agent_pubkeys returns all agent pubkeys
|
||||
pub fn (mut m AgentDB) get_all_agent_pubkeys() ![]string {
|
||||
// Get all agent IDs
|
||||
agent_ids := m.list()!
|
||||
|
||||
// Get pubkeys for all agents
|
||||
mut pubkeys := []string{}
|
||||
for id in agent_ids {
|
||||
agent := m.get(id) or { continue }
|
||||
pubkeys << agent.pubkey
|
||||
}
|
||||
|
||||
return pubkeys
|
||||
}
|
||||
|
||||
// get_by_service returns all agents that provide a specific service
|
||||
pub fn (mut m AgentDB) get_by_service(actor string, action string) ![]Agent {
|
||||
mut matching_agents := []Agent{}
|
||||
|
||||
// Get all agent IDs
|
||||
agent_ids := m.list()!
|
||||
|
||||
// Filter agents that provide the specified service
|
||||
for id in agent_ids {
|
||||
// Get the agent by ID
|
||||
agent := m.get(id) or { continue }
|
||||
|
||||
// Check if agent provides the specified service
|
||||
for service in agent.services {
|
||||
if service.actor == actor {
|
||||
for service_action in service.actions {
|
||||
if service_action.action == action {
|
||||
matching_agents << agent
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matching_agents
|
||||
}
|
||||
@@ -2,14 +2,15 @@ module core
|
||||
|
||||
import os
|
||||
import rand
|
||||
|
||||
fn test_agents_model() {
|
||||
import freeflowuniverse.herolib.circles.actionprocessor
|
||||
import freeflowuniverse.herolib.circles.models.core
|
||||
fn test_agent_db() {
|
||||
// Create a temporary directory for testing
|
||||
test_dir := os.join_path(os.temp_dir(), 'hero_agent_test_${rand.intn(9000) or { 0 } + 1000}')
|
||||
os.mkdir_all(test_dir) or { panic(err) }
|
||||
defer { os.rmdir_all(test_dir) or {} }
|
||||
|
||||
mut runner := new(path: test_dir)!
|
||||
mut runner := actionprocessor.new(path: test_dir)!
|
||||
|
||||
// Create multiple agents for testing
|
||||
mut agent1 := runner.agents.new()
|
||||
@@ -27,29 +28,19 @@ fn test_agents_model() {
|
||||
agent3.address = '127.0.0.3'
|
||||
agent3.description = 'Test Agent 3'
|
||||
|
||||
// Create a service action
|
||||
mut action := AgentServiceAction{
|
||||
action: 'start'
|
||||
description: 'Start a VM'
|
||||
params: {
|
||||
// Create a service using the factory method
|
||||
mut service := agent1.new_service(actor: 'vm_manager', description: 'VM Management Service')
|
||||
|
||||
// Create a service action using the factory method
|
||||
mut action := service.new_action(action:'start', description: 'Start a VM')
|
||||
|
||||
// Set additional properties for the action
|
||||
action.params = {
|
||||
'name': 'string'
|
||||
}
|
||||
params_example: {
|
||||
action.params_example = {
|
||||
'name': 'myvm'
|
||||
}
|
||||
status: .ok
|
||||
public: true
|
||||
}
|
||||
|
||||
// Create a service
|
||||
mut service := AgentService{
|
||||
actor: 'vm_manager'
|
||||
actions: [action]
|
||||
description: 'VM Management Service'
|
||||
status: .ok
|
||||
}
|
||||
|
||||
agent1.services = [service]
|
||||
|
||||
// Add the agents
|
||||
println('Adding agent 1')
|
||||
@@ -72,11 +63,14 @@ fn test_agents_model() {
|
||||
println('Agent IDs in list: ${agent_ids}')
|
||||
|
||||
// Debug: Print the 'all' key from the radix tree
|
||||
if all_bytes := runner.agents.manager.db_meta.search('agent:all') {
|
||||
all_bytes := runner.agents.db.session_state.dbs.db_meta_core.get('agent:id') or {
|
||||
println('No agent:id key found in radix tree')
|
||||
[]u8{}
|
||||
}
|
||||
|
||||
if all_bytes.len > 0 {
|
||||
all_str := all_bytes.bytestr()
|
||||
println('Raw agent:all key content: "${all_str}"')
|
||||
} else {
|
||||
println('No agent:all key found in radix tree')
|
||||
println('Raw agent:id key content: "${all_str}"')
|
||||
}
|
||||
|
||||
// Get all agents
|
||||
@@ -174,7 +168,7 @@ fn test_agents_model() {
|
||||
agents_after_all_deleted := runner.agents.getall() or {
|
||||
// This is expected to fail with 'No agents found' error
|
||||
assert err.msg() == 'No agents found'
|
||||
[]Agent{}
|
||||
[]core.Agent{cap: 0}
|
||||
}
|
||||
assert agents_after_all_deleted.len == 0, 'Expected 0 agents after all deletions, got ${agents_after_all_deleted.len}'
|
||||
|
||||
@@ -3,19 +3,58 @@ module core
|
||||
import freeflowuniverse.herolib.data.ourtime
|
||||
import freeflowuniverse.herolib.data.encoder
|
||||
|
||||
// Agent represents a service provider that can execute jobs
|
||||
// Agent represents self service provider that can execute jobs
|
||||
pub struct Agent {
|
||||
pub mut:
|
||||
id u32
|
||||
pubkey string // pubkey using ed25519
|
||||
address string // where we can find the agent
|
||||
port int // default 9999
|
||||
port u16 // default 9999
|
||||
description string // optional
|
||||
status AgentStatus
|
||||
services []AgentService // these are the public services
|
||||
signature string // signature as done by private key of $address+$port+$description+$status
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ServiceParams {
|
||||
pub mut:
|
||||
actor string
|
||||
description string
|
||||
}
|
||||
|
||||
// new_service creates self new AgentService for this agent
|
||||
pub fn (mut self Agent) new_service(args ServiceParams) &AgentService {
|
||||
mut service := AgentService{
|
||||
actor: args.actor
|
||||
description: args.description
|
||||
status: .ok
|
||||
public: true
|
||||
}
|
||||
self.services << service
|
||||
return &self.services[self.services.len - 1]
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ActionParams {
|
||||
pub mut:
|
||||
action string
|
||||
description string
|
||||
}
|
||||
|
||||
|
||||
// new_service_action creates self new AgentServiceAction for the specified service
|
||||
pub fn (mut service AgentService) new_action(args ActionParams) &AgentServiceAction {
|
||||
mut service_action := AgentServiceAction{
|
||||
action: args.action
|
||||
description: args.description
|
||||
status: .ok
|
||||
public: true
|
||||
}
|
||||
service.actions << service_action
|
||||
return &service.actions[service.actions.len - 1]
|
||||
}
|
||||
|
||||
// AgentStatus represents the current state of an agent
|
||||
pub struct AgentStatus {
|
||||
pub mut:
|
||||
@@ -25,7 +64,7 @@ pub mut:
|
||||
status AgentState // current state of the agent
|
||||
}
|
||||
|
||||
// AgentService represents a service provided by an agent
|
||||
// AgentService represents self service provided by an agent
|
||||
pub struct AgentService {
|
||||
pub mut:
|
||||
actor string // name of the actor providing the service
|
||||
@@ -35,7 +74,7 @@ pub mut:
|
||||
public bool // if everyone can use then true, if restricted means only certain people can use
|
||||
}
|
||||
|
||||
// AgentServiceAction represents an action that can be performed by a service
|
||||
// AgentServiceAction represents an action that can be performed by self service
|
||||
pub struct AgentServiceAction {
|
||||
pub mut:
|
||||
action string // which action
|
||||
@@ -62,34 +101,34 @@ pub enum AgentServiceState {
|
||||
halted // service/action has been manually stopped
|
||||
}
|
||||
|
||||
pub fn (c Agent) index_keys() map[string]string {
|
||||
return {"pubkey": c.pubkey}
|
||||
pub fn (self Agent) index_keys() map[string]string {
|
||||
return {"pubkey": self.pubkey}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// dumps serializes the Agent struct to binary format using the encoder
|
||||
pub fn (a Agent) dumps() ![]u8 {
|
||||
pub fn (self Agent) dumps() ![]u8 {
|
||||
mut e := encoder.new()
|
||||
|
||||
// Add unique encoding ID to identify this type of data
|
||||
e.add_u16(100)
|
||||
|
||||
// Encode Agent fields
|
||||
e.add_string(a.pubkey)
|
||||
e.add_string(a.address)
|
||||
e.add_int(a.port)
|
||||
e.add_string(a.description)
|
||||
e.add_string(self.pubkey)
|
||||
e.add_string(self.address)
|
||||
e.add_u16(self.port)
|
||||
e.add_string(self.description)
|
||||
|
||||
// Encode AgentStatus
|
||||
e.add_string(a.status.guid)
|
||||
e.add_ourtime(a.status.timestamp_first)
|
||||
e.add_ourtime(a.status.timestamp_last)
|
||||
e.add_u8(u8(a.status.status))
|
||||
e.add_string(self.status.guid)
|
||||
e.add_ourtime(self.status.timestamp_first)
|
||||
e.add_ourtime(self.status.timestamp_last)
|
||||
e.add_u8(u8(self.status.status))
|
||||
|
||||
// Encode services array
|
||||
e.add_u16(u16(a.services.len))
|
||||
for service in a.services {
|
||||
e.add_u16(u16(self.services.len))
|
||||
for service in self.services {
|
||||
// Encode AgentService fields
|
||||
e.add_string(service.actor)
|
||||
e.add_string(service.description)
|
||||
@@ -114,15 +153,14 @@ pub fn (a Agent) dumps() ![]u8 {
|
||||
}
|
||||
|
||||
// Encode signature
|
||||
e.add_string(a.signature)
|
||||
e.add_string(self.signature)
|
||||
|
||||
return e.data
|
||||
}
|
||||
|
||||
// loads deserializes binary data into an Agent struct
|
||||
pub fn Agent.loads(data []u8) !Agent {
|
||||
pub fn agent_loads(data []u8) !Agent {
|
||||
mut d := encoder.decoder_new(data)
|
||||
mut agent := Agent{}
|
||||
|
||||
// Check encoding ID to verify this is the correct type of data
|
||||
encoding_id := d.get_u16()!
|
||||
@@ -130,18 +168,20 @@ pub fn Agent.loads(data []u8) !Agent {
|
||||
return error('Wrong file type: expected encoding ID 100, got ${encoding_id}, for agent')
|
||||
}
|
||||
|
||||
mut self:=Agent{}
|
||||
|
||||
// Decode Agent fields
|
||||
agent.pubkey = d.get_string()!
|
||||
agent.address = d.get_string()!
|
||||
agent.port = d.get_int()!
|
||||
agent.description = d.get_string()!
|
||||
self.pubkey = d.get_string()!
|
||||
self.address = d.get_string()!
|
||||
self.port = d.get_u16()!
|
||||
self.description = d.get_string()!
|
||||
|
||||
// Decode AgentStatus
|
||||
agent.status.guid = d.get_string()!
|
||||
agent.status.timestamp_first = d.get_ourtime()!
|
||||
agent.status.timestamp_last = d.get_ourtime()!
|
||||
self.status.guid = d.get_string()!
|
||||
self.status.timestamp_first = d.get_ourtime()!
|
||||
self.status.timestamp_last = d.get_ourtime()!
|
||||
status_val := d.get_u8()!
|
||||
agent.status.status = match status_val {
|
||||
self.status.status = match status_val {
|
||||
0 { AgentState.ok }
|
||||
1 { AgentState.down }
|
||||
2 { AgentState.error }
|
||||
@@ -151,7 +191,7 @@ pub fn Agent.loads(data []u8) !Agent {
|
||||
|
||||
// Decode services array
|
||||
services_len := d.get_u16()!
|
||||
agent.services = []AgentService{len: int(services_len)}
|
||||
self.services = []AgentService{len: int(services_len)}
|
||||
for i in 0 .. services_len {
|
||||
mut service := AgentService{}
|
||||
|
||||
@@ -196,11 +236,12 @@ pub fn Agent.loads(data []u8) !Agent {
|
||||
service.actions[j] = action
|
||||
}
|
||||
|
||||
agent.services[i] = service
|
||||
self.services[i] = service
|
||||
}
|
||||
|
||||
// Decode signature
|
||||
agent.signature = d.get_string()!
|
||||
self.signature = d.get_string()!
|
||||
|
||||
return self
|
||||
|
||||
return agent
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
module models
|
||||
|
||||
import freeflowuniverse.herolib.data.radixtree
|
||||
import freeflowuniverse.herolib.data.ourdb
|
||||
import json
|
||||
|
||||
import freeflowuniverse.herolib.circles.models.core { agent_loads, Agent }
|
||||
|
||||
pub struct DBHandler[T] {
|
||||
pub mut:
|
||||
@@ -25,7 +22,7 @@ pub fn (mut m DBHandler[T]) set(item_ T) !T {
|
||||
mut item := item_
|
||||
|
||||
// Store the item data in the database and get the assigned ID
|
||||
item.id = m.session_state.dbs.db_data_core.set(id: item.id, data: item.dumps()!)!
|
||||
item.id = m.session_state.dbs.db_data_core.set(data: item.dumps()!)!
|
||||
|
||||
// Update index keys
|
||||
for key, value in m.index_keys(item)! {
|
||||
@@ -42,13 +39,23 @@ pub fn (mut m DBHandler[T]) get(id u32) !T {
|
||||
item_data := m.session_state.dbs.db_data_core.get(id) or {
|
||||
return error('Item data not found for ID ${id}')
|
||||
}
|
||||
mut o:=T.loads(item_data)!
|
||||
mut o:= T{}
|
||||
match o {
|
||||
Agent {
|
||||
o=agent_loads(item_data)!
|
||||
}else{
|
||||
return panic('Not implemented object')
|
||||
}
|
||||
}
|
||||
|
||||
// o.loads(item_data)!
|
||||
o.id = id
|
||||
return o
|
||||
}
|
||||
|
||||
pub fn (mut m DBHandler[T]) exists(id u32) !bool {
|
||||
return m.db_data.get(id) or { return false } != []u8{}
|
||||
item_data := m.session_state.dbs.db_data_core.get(id) or { return false }
|
||||
return item_data != []u8{}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,12 +106,33 @@ fn (mut m DBHandler[T]) index_keys(item T) !map[string]string {
|
||||
return keymap
|
||||
}
|
||||
|
||||
// list returns all ids from the manager
|
||||
// list returns all ids from the db handler
|
||||
pub fn (mut m DBHandler[T]) list() ![]u32 {
|
||||
// Use the RadixTree's prefix capabilities to list all items
|
||||
defaultkey:=m.index_keys(T{})[0] or {panic('no index keys')}
|
||||
keys := m.session_state.dbs.db_meta_core.getall('${m.prefix}:${defaultkey}')!
|
||||
return keys
|
||||
mut empty_item := T{}
|
||||
mut keys_map := m.index_keys(empty_item)!
|
||||
if keys_map.len == 0 {
|
||||
return error('No index keys defined for this type')
|
||||
}
|
||||
|
||||
// Get the first key from the map
|
||||
mut default_key := ''
|
||||
for k, _ in keys_map {
|
||||
default_key = k
|
||||
break
|
||||
}
|
||||
|
||||
// Get all IDs from the meta database
|
||||
id_bytes := m.session_state.dbs.db_meta_core.getall('${m.prefix}:${default_key}')!
|
||||
|
||||
// Convert bytes to u32 IDs
|
||||
mut result := []u32{}
|
||||
for id_byte in id_bytes {
|
||||
id_str := id_byte.bytestr()
|
||||
result << id_str.u32()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ pub mut:
|
||||
name string
|
||||
pubkey string // pubkey of user who called this
|
||||
addr string //mycelium address
|
||||
dbs Databases
|
||||
}
|
||||
|
||||
pub struct Databases{
|
||||
@@ -42,21 +43,26 @@ pub fn new_session(args_ StateArgs) !SessionState {
|
||||
|
||||
mypath:=os.join_path(args.path, args.name)
|
||||
|
||||
mut dbs:=Databases{
|
||||
db_data_core : ourdb.new(
|
||||
mut db_data_core := ourdb.new(
|
||||
path: os.join_path(mypath, 'data_core')
|
||||
incremental_mode: true
|
||||
)!
|
||||
db_meta_core : radixtree.new(
|
||||
mut db_meta_core := radixtree.new(
|
||||
path: os.join_path(mypath, 'meta_core')
|
||||
)!
|
||||
db_data_mcc : ourdb.new(
|
||||
mut db_data_mcc := ourdb.new(
|
||||
path: os.join_path(mypath, 'data_mcc')
|
||||
incremental_mode: false
|
||||
)!
|
||||
db_meta_mcc : radixtree.new(
|
||||
mut db_meta_mcc := radixtree.new(
|
||||
path: os.join_path(mypath, 'meta_mcc')
|
||||
)!
|
||||
|
||||
mut dbs := Databases{
|
||||
db_data_core: &db_data_core
|
||||
db_meta_core: &db_meta_core
|
||||
db_data_mcc: &db_data_mcc
|
||||
db_meta_mcc: &db_meta_mcc
|
||||
}
|
||||
|
||||
mut s := SessionState{
|
||||
|
||||
@@ -1,59 +1,58 @@
|
||||
module core
|
||||
|
||||
import freeflowuniverse.herolib.data.ourtime
|
||||
import freeflowuniverse.herolib.data.ourdb
|
||||
import freeflowuniverse.herolib.data.radixtree
|
||||
import freeflowuniverse.herolib.circles.models
|
||||
import freeflowuniverse.herolib.circles.models { DBHandler, SessionState }
|
||||
import freeflowuniverse.herolib.circles.models.core { Agent, AgentService, AgentServiceAction, AgentState }
|
||||
|
||||
|
||||
@[heap]
|
||||
pub struct AgentManager {
|
||||
pub struct AgentDB {
|
||||
pub mut:
|
||||
db models.DBHandler[Agent]
|
||||
}
|
||||
|
||||
pub fn new_agentdb(session_state SessionState) AgentManager {
|
||||
return AgentManager{
|
||||
pub fn new_agentdb(session_state SessionState) !AgentDB {
|
||||
return AgentDB{
|
||||
db:models.new_dbhandler[Agent]('agent', session_state)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut m AgentManager) new() Agent {
|
||||
pub fn (mut m AgentDB) new() Agent {
|
||||
return Agent{}
|
||||
}
|
||||
|
||||
// set adds or updates an agent
|
||||
pub fn (mut m AgentManager) set(agent Agent) !Agent {
|
||||
pub fn (mut m AgentDB) set(agent Agent) !Agent {
|
||||
return m.db.set(agent)!
|
||||
}
|
||||
|
||||
// get retrieves an agent by its ID
|
||||
pub fn (mut m AgentManager) get(id u32) !Agent {
|
||||
pub fn (mut m AgentDB) get(id u32) !Agent {
|
||||
return m.db.get(id)!
|
||||
}
|
||||
// list returns all agent IDs
|
||||
pub fn (mut m AgentManager) list() ![]u32 {
|
||||
pub fn (mut m AgentDB) list() ![]u32 {
|
||||
return m.db.list()!
|
||||
}
|
||||
|
||||
pub fn (mut m AgentManager) getall() ![]Agent {
|
||||
pub fn (mut m AgentDB) getall() ![]Agent {
|
||||
return m.db.getall()!
|
||||
}
|
||||
|
||||
// delete removes an agent by its ID
|
||||
pub fn (mut m AgentManager) delete(id u32) ! {
|
||||
pub fn (mut m AgentDB) delete(id u32) ! {
|
||||
m.db.delete(id)!
|
||||
}
|
||||
|
||||
//////////////////CUSTOM METHODS//////////////////////////////////
|
||||
|
||||
// get_by_pubkey retrieves an agent by its public key
|
||||
pub fn (mut m AgentManager) get_by_pubkey(pubkey string) !Agent {
|
||||
pub fn (mut m AgentDB) get_by_pubkey(pubkey string) !Agent {
|
||||
return m.db.get_by_key('pubkey', pubkey)!
|
||||
}
|
||||
|
||||
// delete_by_pubkey removes an agent by its public key
|
||||
pub fn (mut m AgentManager) delete_by_pubkey(pubkey string) ! {
|
||||
pub fn (mut m AgentDB) delete_by_pubkey(pubkey string) ! {
|
||||
// Get the agent by pubkey
|
||||
agent := m.get_by_pubkey(pubkey) or {
|
||||
// Agent not found, nothing to delete
|
||||
@@ -65,7 +64,7 @@ pub fn (mut m AgentManager) delete_by_pubkey(pubkey string) ! {
|
||||
}
|
||||
|
||||
// update_status updates just the status of an agent
|
||||
pub fn (mut m AgentManager) update_status(pubkey string, status AgentState) !Agent {
|
||||
pub fn (mut m AgentDB) update_status(pubkey string, status AgentState) !Agent {
|
||||
// Get the agent by pubkey
|
||||
mut agent := m.get_by_pubkey(pubkey)!
|
||||
|
||||
@@ -78,7 +77,7 @@ pub fn (mut m AgentManager) update_status(pubkey string, status AgentState) !Age
|
||||
}
|
||||
|
||||
// get_all_agent_pubkeys returns all agent pubkeys
|
||||
fn (mut m AgentManager) get_all_agent_pubkeys() ![]string {
|
||||
pub fn (mut m AgentDB) get_all_agent_pubkeys() ![]string {
|
||||
// Get all agent IDs
|
||||
agent_ids := m.list()!
|
||||
|
||||
@@ -93,7 +92,7 @@ fn (mut m AgentManager) get_all_agent_pubkeys() ![]string {
|
||||
}
|
||||
|
||||
// get_by_service returns all agents that provide a specific service
|
||||
pub fn (mut m AgentManager) get_by_service(actor string, action string) ![]Agent {
|
||||
pub fn (mut m AgentDB) get_by_service(actor string, action string) ![]Agent {
|
||||
mut matching_agents := []Agent{}
|
||||
|
||||
// Get all agent IDs
|
||||
@@ -70,7 +70,8 @@ fn test_agent_dumps_loads() {
|
||||
}
|
||||
|
||||
// Test binary decoding
|
||||
decoded_agent := agent_loads(binary_data) or {
|
||||
mut decoded_agent := Agent{}
|
||||
decoded_agent.loads(binary_data) or {
|
||||
assert false, 'Failed to decode agent: ${err}'
|
||||
return
|
||||
}
|
||||
@@ -232,7 +233,8 @@ fn test_agent_complex_structure() {
|
||||
}
|
||||
|
||||
// Test binary decoding
|
||||
decoded_agent := agent_loads(binary_data) or {
|
||||
mut decoded_agent := Agent{}
|
||||
decoded_agent.loads(binary_data) or {
|
||||
assert false, 'Failed to decode complex agent: ${err}'
|
||||
return
|
||||
}
|
||||
@@ -303,7 +305,8 @@ fn test_agent_empty_structures() {
|
||||
}
|
||||
|
||||
// Test binary decoding
|
||||
decoded_agent := agent_loads(binary_data) or {
|
||||
mut decoded_agent := Agent{}
|
||||
decoded_agent.loads(binary_data) or {
|
||||
assert false, 'Failed to decode empty agent: ${err}'
|
||||
return
|
||||
}
|
||||
@@ -3,56 +3,57 @@ module core
|
||||
import freeflowuniverse.herolib.data.ourdb
|
||||
import freeflowuniverse.herolib.data.radixtree
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.circles.models
|
||||
|
||||
@[heap]
|
||||
pub struct CircleManager {
|
||||
pub struct CircleDB {
|
||||
pub mut:
|
||||
manager DBSession[Circle]
|
||||
db models.DBHandler[Circle]
|
||||
}
|
||||
|
||||
pub fn new_circlemanager(db_data &ourdb.OurDB, db_meta &radixtree.RadixTree) CircleManager {
|
||||
return CircleManager{
|
||||
manager: session.new_dbsession[Circle](db_data, db_meta, 'circle')
|
||||
pub fn new_circledb(session_state models.SessionState) !CircleDB {
|
||||
return CircleDB{
|
||||
db: models.new_dbhandler[Circle]('circle', session_state)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut m CircleManager) new() Circle {
|
||||
pub fn (mut m CircleDB) new() Circle {
|
||||
return Circle{}
|
||||
}
|
||||
|
||||
// set adds or updates a circle
|
||||
pub fn (mut m CircleManager) set(circle Circle) !Circle {
|
||||
return m.manager.set(circle)!
|
||||
pub fn (mut m CircleDB) set(circle Circle) !Circle {
|
||||
return m.db.set(circle)!
|
||||
}
|
||||
|
||||
// get retrieves a circle by its ID
|
||||
pub fn (mut m CircleManager) get(id u32) !Circle {
|
||||
return m.manager.get(id)!
|
||||
pub fn (mut m CircleDB) get(id u32) !Circle {
|
||||
return m.db.get(id)!
|
||||
}
|
||||
|
||||
// list returns all circle IDs
|
||||
pub fn (mut m CircleManager) list() ![]u32 {
|
||||
return m.manager.list()!
|
||||
pub fn (mut m CircleDB) list() ![]u32 {
|
||||
return m.db.list()!
|
||||
}
|
||||
|
||||
pub fn (mut m CircleManager) getall() ![]Circle {
|
||||
return m.manager.getall()!
|
||||
pub fn (mut m CircleDB) getall() ![]Circle {
|
||||
return m.db.getall()!
|
||||
}
|
||||
|
||||
// delete removes a circle by its ID
|
||||
pub fn (mut m CircleManager) delete(id u32) ! {
|
||||
m.manager.delete(id)!
|
||||
pub fn (mut m CircleDB) delete(id u32) ! {
|
||||
m.db.delete(id)!
|
||||
}
|
||||
|
||||
//////////////////CUSTOM METHODS//////////////////////////////////
|
||||
|
||||
// get_by_name retrieves a circle by its name
|
||||
pub fn (mut m CircleManager) get_by_name(name string) !Circle {
|
||||
return m.manager.get_by_key('name', name)!
|
||||
pub fn (mut m CircleDB) get_by_name(name string) !Circle {
|
||||
return m.db.get_by_key('name', name)!
|
||||
}
|
||||
|
||||
// delete_by_name removes a circle by its name
|
||||
pub fn (mut m CircleManager) delete_by_name(name string) ! {
|
||||
pub fn (mut m CircleDB) delete_by_name(name string) ! {
|
||||
// Get the circle by name
|
||||
circle := m.get_by_name(name) or {
|
||||
// Circle not found, nothing to delete
|
||||
@@ -64,7 +65,7 @@ pub fn (mut m CircleManager) delete_by_name(name string) ! {
|
||||
}
|
||||
|
||||
// add_member adds a member to a circle
|
||||
pub fn (mut m CircleManager) add_member(circle_id u32, member Member) !Circle {
|
||||
pub fn (mut m CircleDB) add_member(circle_id u32, member Member) !Circle {
|
||||
// Get the circle by ID
|
||||
mut circle := m.get(circle_id)!
|
||||
|
||||
@@ -91,7 +92,7 @@ pub fn (mut m CircleManager) add_member(circle_id u32, member Member) !Circle {
|
||||
}
|
||||
|
||||
// remove_member removes a member from a circle by pubkey
|
||||
pub fn (mut m CircleManager) remove_member(circle_id u32, pubkey string) !Circle {
|
||||
pub fn (mut m CircleDB) remove_member(circle_id u32, pubkey string) !Circle {
|
||||
// Get the circle by ID
|
||||
mut circle := m.get(circle_id)!
|
||||
|
||||
@@ -127,7 +128,7 @@ pub fn (mut m CircleManager) remove_member(circle_id u32, pubkey string) !Circle
|
||||
}
|
||||
|
||||
// update_member_role updates the role of a member in a circle
|
||||
pub fn (mut m CircleManager) update_member_role(circle_id u32, pubkey string, role Role) !Circle {
|
||||
pub fn (mut m CircleDB) update_member_role(circle_id u32, pubkey string, role Role) !Circle {
|
||||
// Get the circle by ID
|
||||
mut circle := m.get(circle_id)!
|
||||
|
||||
@@ -156,7 +157,7 @@ pub fn (mut m CircleManager) update_member_role(circle_id u32, pubkey string, ro
|
||||
}
|
||||
|
||||
// get_members returns all members of a circle
|
||||
pub fn (mut m CircleManager) get_members(circle_id u32) ![]Member {
|
||||
pub fn (mut m CircleDB) get_members(circle_id u32) ![]Member {
|
||||
// Get the circle by ID
|
||||
circle := m.get(circle_id)!
|
||||
|
||||
@@ -164,7 +165,7 @@ pub fn (mut m CircleManager) get_members(circle_id u32) ![]Member {
|
||||
}
|
||||
|
||||
// get_members_by_role returns all members of a circle with a specific role
|
||||
pub fn (mut m CircleManager) get_members_by_role(circle_id u32, role Role) ![]Member {
|
||||
pub fn (mut m CircleDB) get_members_by_role(circle_id u32, role Role) ![]Member {
|
||||
// Get the circle by ID
|
||||
circle := m.get(circle_id)!
|
||||
|
||||
@@ -181,7 +182,7 @@ pub fn (mut m CircleManager) get_members_by_role(circle_id u32, role Role) ![]Me
|
||||
}
|
||||
|
||||
// play processes heroscript commands for circles
|
||||
pub fn play_circle(mut cm CircleManager, mut plbook playbook.PlayBook) ! {
|
||||
pub fn play_circle(mut cm CircleDB, mut plbook playbook.PlayBook) ! {
|
||||
// Find all actions that start with 'circle.'
|
||||
circle_actions := plbook.actions_find(actor: 'circle')!
|
||||
if circle_actions.len == 0 {
|
||||
@@ -3,7 +3,7 @@ module core
|
||||
import os
|
||||
import rand
|
||||
|
||||
fn test_circle_manager() {
|
||||
fn test_circle_db() {
|
||||
// Create a temporary directory for testing
|
||||
test_dir := os.join_path(os.temp_dir(), 'hero_circle_test_${rand.intn(9000) or { 0 } + 1000}')
|
||||
os.mkdir_all(test_dir) or { panic(err) }
|
||||
@@ -3,56 +3,57 @@ module core
|
||||
import freeflowuniverse.herolib.data.ourdb
|
||||
import freeflowuniverse.herolib.data.radixtree
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.circles.models
|
||||
|
||||
@[heap]
|
||||
pub struct NameManager {
|
||||
pub struct NameDB {
|
||||
pub mut:
|
||||
manager DBSession[Name]
|
||||
db models.DBHandler[Name]
|
||||
}
|
||||
|
||||
pub fn new_namemanager(db_data &ourdb.OurDB, db_meta &radixtree.RadixTree) NameManager {
|
||||
return NameManager{
|
||||
manager: session.new_dbsession[Name](db_data, db_meta, 'name')
|
||||
pub fn new_namedb(session_state models.SessionState) !NameDB {
|
||||
return NameDB{
|
||||
db: models.new_dbhandler[Name]('name', session_state)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut m NameManager) new() Name {
|
||||
pub fn (mut m NameDB) new() Name {
|
||||
return Name{}
|
||||
}
|
||||
|
||||
// set adds or updates a name
|
||||
pub fn (mut m NameManager) set(name Name) !Name {
|
||||
return m.manager.set(name)!
|
||||
pub fn (mut m NameDB) set(name Name) !Name {
|
||||
return m.db.set(name)!
|
||||
}
|
||||
|
||||
// get retrieves a name by its ID
|
||||
pub fn (mut m NameManager) get(id u32) !Name {
|
||||
return m.manager.get(id)!
|
||||
pub fn (mut m NameDB) get(id u32) !Name {
|
||||
return m.db.get(id)!
|
||||
}
|
||||
|
||||
// list returns all name IDs
|
||||
pub fn (mut m NameManager) list() ![]u32 {
|
||||
return m.manager.list()!
|
||||
pub fn (mut m NameDB) list() ![]u32 {
|
||||
return m.db.list()!
|
||||
}
|
||||
|
||||
pub fn (mut m NameManager) getall() ![]Name {
|
||||
return m.manager.getall()!
|
||||
pub fn (mut m NameDB) getall() ![]Name {
|
||||
return m.db.getall()!
|
||||
}
|
||||
|
||||
// delete removes a name by its ID
|
||||
pub fn (mut m NameManager) delete(id u32) ! {
|
||||
m.manager.delete(id)!
|
||||
pub fn (mut m NameDB) delete(id u32) ! {
|
||||
m.db.delete(id)!
|
||||
}
|
||||
|
||||
//////////////////CUSTOM METHODS//////////////////////////////////
|
||||
|
||||
// get_by_domain retrieves a name by its domain
|
||||
pub fn (mut m NameManager) get_by_domain(domain string) !Name {
|
||||
return m.manager.get_by_key('domain', domain)!
|
||||
pub fn (mut m NameDB) get_by_domain(domain string) !Name {
|
||||
return m.db.get_by_key('domain', domain)!
|
||||
}
|
||||
|
||||
// delete_by_domain removes a name by its domain
|
||||
pub fn (mut m NameManager) delete_by_domain(domain string) ! {
|
||||
pub fn (mut m NameDB) delete_by_domain(domain string) ! {
|
||||
// Get the name by domain
|
||||
name := m.get_by_domain(domain) or {
|
||||
// Name not found, nothing to delete
|
||||
@@ -64,7 +65,7 @@ pub fn (mut m NameManager) delete_by_domain(domain string) ! {
|
||||
}
|
||||
|
||||
// add_record adds a record to a name
|
||||
pub fn (mut m NameManager) add_record(name_id u32, record Record) !Name {
|
||||
pub fn (mut m NameDB) add_record(name_id u32, record Record) !Name {
|
||||
// Get the name by ID
|
||||
mut name := m.get(name_id)!
|
||||
|
||||
@@ -83,7 +84,7 @@ pub fn (mut m NameManager) add_record(name_id u32, record Record) !Name {
|
||||
}
|
||||
|
||||
// remove_record removes a record from a name by name and category
|
||||
pub fn (mut m NameManager) remove_record(name_id u32, record_name string, category RecordType) !Name {
|
||||
pub fn (mut m NameDB) remove_record(name_id u32, record_name string, category RecordType) !Name {
|
||||
// Get the name by ID
|
||||
mut name := m.get(name_id)!
|
||||
|
||||
@@ -111,7 +112,7 @@ pub fn (mut m NameManager) remove_record(name_id u32, record_name string, catego
|
||||
}
|
||||
|
||||
// update_record updates a record in a name
|
||||
pub fn (mut m NameManager) update_record(name_id u32, record_name string, category RecordType, new_record Record) !Name {
|
||||
pub fn (mut m NameDB) update_record(name_id u32, record_name string, category RecordType, new_record Record) !Name {
|
||||
// Get the name by ID
|
||||
mut name := m.get(name_id)!
|
||||
|
||||
@@ -145,7 +146,7 @@ pub fn (mut m NameManager) update_record(name_id u32, record_name string, catego
|
||||
}
|
||||
|
||||
// get_records returns all records of a name
|
||||
pub fn (mut m NameManager) get_records(name_id u32) ![]Record {
|
||||
pub fn (mut m NameDB) get_records(name_id u32) ![]Record {
|
||||
// Get the name by ID
|
||||
name := m.get(name_id)!
|
||||
|
||||
@@ -153,7 +154,7 @@ pub fn (mut m NameManager) get_records(name_id u32) ![]Record {
|
||||
}
|
||||
|
||||
// get_records_by_category returns all records of a name with a specific category
|
||||
pub fn (mut m NameManager) get_records_by_category(name_id u32, category RecordType) ![]Record {
|
||||
pub fn (mut m NameDB) get_records_by_category(name_id u32, category RecordType) ![]Record {
|
||||
// Get the name by ID
|
||||
name := m.get(name_id)!
|
||||
|
||||
@@ -170,7 +171,7 @@ pub fn (mut m NameManager) get_records_by_category(name_id u32, category RecordT
|
||||
}
|
||||
|
||||
// add_admin adds an admin to a name
|
||||
pub fn (mut m NameManager) add_admin(name_id u32, pubkey string) !Name {
|
||||
pub fn (mut m NameDB) add_admin(name_id u32, pubkey string) !Name {
|
||||
// Get the name by ID
|
||||
mut name := m.get(name_id)!
|
||||
|
||||
@@ -189,7 +190,7 @@ pub fn (mut m NameManager) add_admin(name_id u32, pubkey string) !Name {
|
||||
}
|
||||
|
||||
// remove_admin removes an admin from a name
|
||||
pub fn (mut m NameManager) remove_admin(name_id u32, pubkey string) !Name {
|
||||
pub fn (mut m NameDB) remove_admin(name_id u32, pubkey string) !Name {
|
||||
// Get the name by ID
|
||||
mut name := m.get(name_id)!
|
||||
|
||||
@@ -222,7 +223,7 @@ pub fn (mut m NameManager) remove_admin(name_id u32, pubkey string) !Name {
|
||||
}
|
||||
|
||||
// play processes heroscript commands for names
|
||||
pub fn (mut m NameManager) play(mut plbook playbook.PlayBook) ! {
|
||||
pub fn (mut m NameDB) play(mut plbook playbook.PlayBook) ! {
|
||||
// Find all actions that start with 'name.'
|
||||
name_actions := plbook.actions_find(actor: 'name')!
|
||||
if name_actions.len == 0 {
|
||||
@@ -3,7 +3,7 @@ module core
|
||||
import os
|
||||
import rand
|
||||
|
||||
fn test_name_manager() {
|
||||
fn test_name_db() {
|
||||
// Create a temporary directory for testing
|
||||
test_dir := os.join_path(os.temp_dir(), 'hero_name_test_${rand.intn(9000) or { 0 } + 1000}')
|
||||
os.mkdir_all(test_dir) or { panic(err) }
|
||||
@@ -122,15 +122,14 @@ pub fn (mut d Decoder) get_i64() !i64 {
|
||||
}
|
||||
|
||||
pub fn (mut d Decoder) get_time() !time.Time {
|
||||
nano_time := d.get_i64()!
|
||||
seconds := nano_time / int(1e9)
|
||||
nano_seconds := int(nano_time % int(1e9))
|
||||
return time.unix_nanosecond(seconds, nano_seconds)
|
||||
secs_:=d.get_u32()!
|
||||
secs := i64(secs_)
|
||||
return time.unix(secs)
|
||||
}
|
||||
|
||||
pub fn (mut d Decoder) get_ourtime() !ourtime.OurTime {
|
||||
return ourtime.OurTime{
|
||||
unixt: d.get_i64()!
|
||||
unixt: d.get_u32()!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,11 +86,11 @@ pub fn (mut b Encoder) add_i64(data i64) {
|
||||
}
|
||||
|
||||
pub fn (mut b Encoder) add_time(data time.Time) {
|
||||
b.add_u64(u64(data.unix_nano())) // add as epoch time
|
||||
b.add_u32(u32(data.unix())) // add as epoch time
|
||||
}
|
||||
|
||||
pub fn (mut b Encoder) add_ourtime(data ourtime.OurTime) {
|
||||
b.add_i64(data.unixt)
|
||||
b.add_u32(u32(data.unixt))
|
||||
}
|
||||
|
||||
pub fn (mut b Encoder) add_list_string(data []string) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module radixtree
|
||||
|
||||
import freeflowuniverse.herolib.data.ourdb
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
// import freeflowuniverse.herolib.ui.console
|
||||
|
||||
// Represents a node in the radix tree
|
||||
struct Node {
|
||||
@@ -34,7 +34,7 @@ pub mut:
|
||||
}
|
||||
|
||||
// Creates a new radix tree with the specified database path
|
||||
pub fn new(args NewArgs) !&RadixTree {
|
||||
pub fn new(args NewArgs) !RadixTree {
|
||||
mut db := ourdb.new(
|
||||
path: args.path
|
||||
record_size_max: 1024 * 4 // 4KB max record size
|
||||
@@ -58,11 +58,12 @@ pub fn new(args NewArgs) !&RadixTree {
|
||||
} else {
|
||||
//console.print_debug('Debug: Using existing root node')
|
||||
root_data := db.get(1)! // Get root node with ID 1
|
||||
root_node := deserialize_node(root_data)!
|
||||
// root_node :=
|
||||
deserialize_node(root_data)!
|
||||
//console.print_debug('Debug: Root node has ${root_node.children.len} children')
|
||||
}
|
||||
|
||||
return &RadixTree{
|
||||
return RadixTree{
|
||||
db: &db
|
||||
root_id: root_id
|
||||
}
|
||||
@@ -128,7 +129,7 @@ pub fn (mut rt RadixTree) set(key string, value []u8) ! {
|
||||
|
||||
// First verify we can deserialize the data correctly
|
||||
//console.print_debug('Debug: Verifying serialization...')
|
||||
if test_node := deserialize_node(parent_data) {
|
||||
if _ := deserialize_node(parent_data) {
|
||||
//console.print_debug('Debug: Serialization test successful - node has ${test_node.children.len} children')
|
||||
} else {
|
||||
//console.print_debug('Debug: ERROR - Failed to deserialize test data')
|
||||
|
||||
Reference in New Issue
Block a user