feat: implement DCOS source tree, tests, and build configuration
Complete implementation of the DCOS package including: - 40+ Python source files across agents, communication, core, learning, memory, protocols, utils - pyproject.toml build configuration - 102 unit tests across all subsystems - Fixed flake.nix (Python 3.12, proper dependencies, pyproject build) - Fixed .woodpecker.yml (correct paths, removed silent-fail flags) - Added .gitignore - Cleared stale pytest cache
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Memory subsystem tests."""
|
||||
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
Tests for ConversationMemory.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from dcos.memory.conversation import ConversationMemory
|
||||
|
||||
|
||||
class TestConversationMemory:
|
||||
def test_create_conversation(self):
|
||||
mem = ConversationMemory()
|
||||
conv = mem.create("conv_1", ["agent_a", "agent_b"])
|
||||
assert conv.conversation_id == "conv_1"
|
||||
assert len(conv.participants) == 2
|
||||
|
||||
def test_add_turn(self):
|
||||
mem = ConversationMemory()
|
||||
mem.create("conv_1", ["alice", "bob"])
|
||||
turn = mem.add_turn("conv_1", "alice", "Hello Bob!")
|
||||
assert turn is not None
|
||||
assert turn.content == "Hello Bob!"
|
||||
|
||||
def test_get_history(self):
|
||||
mem = ConversationMemory()
|
||||
mem.create("conv_1", ["a", "b"])
|
||||
mem.add_turn("conv_1", "a", "msg1")
|
||||
mem.add_turn("conv_1", "b", "msg2")
|
||||
history = mem.get_history("conv_1")
|
||||
assert history is not None
|
||||
assert len(history) == 2
|
||||
|
||||
def test_missing_conversation(self):
|
||||
mem = ConversationMemory()
|
||||
assert mem.add_turn("nonexistent", "a", "msg") is None
|
||||
assert mem.get_history("nonexistent") is None
|
||||
@@ -0,0 +1,33 @@
|
||||
"""
|
||||
Tests for EpisodicMemory.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from dcos.memory.episodic import EpisodicMemory
|
||||
|
||||
|
||||
class TestEpisodicMemory:
|
||||
def test_record_and_recall(self):
|
||||
mem = EpisodicMemory()
|
||||
ep = mem.record({"action": "test"}, "success", "test episode")
|
||||
assert ep.summary == "test episode"
|
||||
|
||||
def test_recall_recent(self):
|
||||
mem = EpisodicMemory()
|
||||
for i in range(5):
|
||||
mem.record({"i": i}, f"outcome_{i}")
|
||||
recent = mem.recall_recent(3)
|
||||
assert len(recent) == 3
|
||||
|
||||
def test_search_by_context(self):
|
||||
mem = EpisodicMemory()
|
||||
mem.record({"type": "exploration"}, "found gold")
|
||||
mem.record({"type": "exploitation"}, "mined ore")
|
||||
results = mem.search_by_context("type", "exploration")
|
||||
assert len(results) == 1
|
||||
|
||||
def test_count(self):
|
||||
mem = EpisodicMemory()
|
||||
assert mem.episode_count() == 0
|
||||
mem.record({}, "outcome")
|
||||
assert mem.episode_count() == 1
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Tests for LongTermMemory.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from dcos.memory.long_term import LongTermMemory, Importance
|
||||
|
||||
|
||||
class TestLongTermMemory:
|
||||
def test_commit_and_recall(self):
|
||||
mem = LongTermMemory()
|
||||
mem.commit("important_fact", "AI is valuable", Importance.HIGH)
|
||||
assert mem.recall("important_fact") == "AI is valuable"
|
||||
|
||||
def test_recall_missing(self):
|
||||
mem = LongTermMemory()
|
||||
assert mem.recall("nonexistent") is None
|
||||
|
||||
def test_consolidate(self):
|
||||
mem = LongTermMemory()
|
||||
count = mem.consolidate({"temp": "data"})
|
||||
assert count == 1
|
||||
assert mem.recall("temp") == "data"
|
||||
|
||||
def test_search(self):
|
||||
mem = LongTermMemory()
|
||||
mem.commit("python_info", "Python is a language", Importance.MEDIUM)
|
||||
mem.commit("java_info", "Java is a language", Importance.MEDIUM)
|
||||
results = mem.search("python")
|
||||
assert len(results) > 0
|
||||
@@ -0,0 +1,25 @@
|
||||
"""
|
||||
Tests for MemoryFacade.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from dcos.memory.memory_facade import MemoryFacade
|
||||
|
||||
|
||||
class TestMemoryFacade:
|
||||
def test_remember_and_recall(self):
|
||||
facade = MemoryFacade()
|
||||
facade.remember("key", "value", importance="low")
|
||||
assert facade.recall("key") == "value"
|
||||
|
||||
def test_search(self):
|
||||
facade = MemoryFacade()
|
||||
facade.remember("important", "data", importance="high")
|
||||
results = facade.search("important")
|
||||
assert "long_term" in results
|
||||
|
||||
def test_summary(self):
|
||||
facade = MemoryFacade()
|
||||
summary = facade.summary()
|
||||
assert "working" in summary
|
||||
assert "episodic" in summary
|
||||
@@ -0,0 +1,33 @@
|
||||
"""
|
||||
Tests for ProceduralMemory.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from dcos.memory.procedural import ProceduralMemory
|
||||
|
||||
|
||||
class TestProceduralMemory:
|
||||
def test_register_procedure(self):
|
||||
mem = ProceduralMemory()
|
||||
mem.register_procedure("build", ["init", "compile", "link"])
|
||||
proc = mem.get_procedure("build")
|
||||
assert proc is not None
|
||||
assert len(proc["steps"]) == 3
|
||||
|
||||
def test_execute_procedure(self):
|
||||
mem = ProceduralMemory()
|
||||
mem.register_procedure("test_proc", ["step1", "step2"])
|
||||
result = mem.execute_procedure("test_proc", {})
|
||||
assert result["executed"] is True
|
||||
|
||||
def test_missing_procedure(self):
|
||||
mem = ProceduralMemory()
|
||||
with pytest.raises(KeyError):
|
||||
mem.execute_procedure("nonexistent", {})
|
||||
|
||||
def test_list_procedures(self):
|
||||
mem = ProceduralMemory()
|
||||
mem.register_procedure("a", ["a1"])
|
||||
mem.register_procedure("b", ["b1"])
|
||||
procs = mem.list_procedures()
|
||||
assert len(procs) == 2
|
||||
@@ -0,0 +1,27 @@
|
||||
"""
|
||||
Tests for SemanticMemory.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from dcos.memory.semantic import SemanticMemory
|
||||
|
||||
|
||||
class TestSemanticMemory:
|
||||
def test_add_and_get_fact(self):
|
||||
mem = SemanticMemory()
|
||||
mem.add_fact("dog", "species", "canine")
|
||||
assert mem.get_fact("dog", "species") == "canine"
|
||||
|
||||
def test_add_relationship(self):
|
||||
mem = SemanticMemory()
|
||||
mem.add_relationship("dog", "wolf")
|
||||
related = mem.get_related("dog")
|
||||
assert "wolf" in related
|
||||
assert "dog" in mem.get_related("wolf")
|
||||
|
||||
def test_query(self):
|
||||
mem = SemanticMemory()
|
||||
mem.add_fact("cat", "species", "feline")
|
||||
mem.add_fact("lion", "species", "feline")
|
||||
results = mem.query("species", "feline")
|
||||
assert len(results) == 2
|
||||
@@ -0,0 +1,42 @@
|
||||
"""
|
||||
Tests for WorkingMemory.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from dcos.memory.working import WorkingMemory
|
||||
|
||||
|
||||
class TestWorkingMemory:
|
||||
def test_store_and_recall(self):
|
||||
mem = WorkingMemory()
|
||||
mem.store("key1", "value1")
|
||||
assert mem.recall("key1") == "value1"
|
||||
|
||||
def test_overwrite(self):
|
||||
mem = WorkingMemory()
|
||||
mem.store("k", "v1")
|
||||
mem.store("k", "v2")
|
||||
assert mem.recall("k") == "v2"
|
||||
|
||||
def test_missing_key(self):
|
||||
mem = WorkingMemory()
|
||||
assert mem.recall("nonexistent") is None
|
||||
|
||||
def test_contains(self):
|
||||
mem = WorkingMemory()
|
||||
mem.store("present", "data")
|
||||
assert mem.contains("present") is True
|
||||
assert mem.contains("absent") is False
|
||||
|
||||
def test_clear(self):
|
||||
mem = WorkingMemory()
|
||||
mem.store("a", 1)
|
||||
mem.store("b", 2)
|
||||
mem.clear()
|
||||
assert mem.size() == 0
|
||||
|
||||
def test_capacity(self):
|
||||
mem = WorkingMemory(capacity=5)
|
||||
for i in range(10):
|
||||
mem.store(f"key{i}", i)
|
||||
assert mem.size() <= 5
|
||||
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
Tests for WorldModel.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from dcos.memory.world_model import WorldModel
|
||||
|
||||
|
||||
class TestWorldModel:
|
||||
def test_add_and_get_entity(self):
|
||||
model = WorldModel()
|
||||
model.add_entity("e1", {"type": "robot", "status": "active"})
|
||||
entity = model.get_entity("e1")
|
||||
assert entity is not None
|
||||
assert entity["properties"]["type"] == "robot"
|
||||
|
||||
def test_update_entity(self):
|
||||
model = WorldModel()
|
||||
model.add_entity("e1", {"status": "inactive"})
|
||||
model.update_entity("e1", {"status": "active"})
|
||||
entity = model.get_entity("e1")
|
||||
assert entity["properties"]["status"] == "active"
|
||||
|
||||
def test_set_and_get_state(self):
|
||||
model = WorldModel()
|
||||
model.set_state("phase", "exploration")
|
||||
assert model.get_state("phase") == "exploration"
|
||||
|
||||
def test_query_entities(self):
|
||||
model = WorldModel()
|
||||
model.add_entity("drone1", {"type": "drone", "team": "alpha"})
|
||||
model.add_entity("drone2", {"type": "drone", "team": "beta"})
|
||||
model.add_entity("robot1", {"type": "robot", "team": "alpha"})
|
||||
drones = model.query_entities("type", "drone")
|
||||
assert len(drones) == 2
|
||||
Reference in New Issue
Block a user