mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-09-09 04:00:52 +00:00
* feat(explorer): add Markdown editing write path * fix(explorer): address markdown editor review findings * feat(explorer): add Markdown editor write path --------- Co-authored-by: Sameer Kadam <sskadam6305@gmail.com>
116 lines
3.9 KiB
Python
116 lines
3.9 KiB
Python
from datetime import datetime
|
|
|
|
import pytest
|
|
|
|
from semantica.context.agent_memory import AgentMemory
|
|
from semantica.context.context_graph import ContextGraph
|
|
from semantica.explorer.markdown_resources import (
|
|
MarkdownResourceKind,
|
|
MarkdownResourceNotFound,
|
|
MarkdownResourceRef,
|
|
MarkdownResourceRegistry,
|
|
MarkdownRevisionConflict,
|
|
MarkdownSaveFailed,
|
|
document_revision,
|
|
)
|
|
|
|
|
|
def _resources():
|
|
graph = ContextGraph(advanced_analytics=False)
|
|
graph.add_node("node-1", "Note", "Original node")
|
|
graph.add_node("node-2", "Note", "Second node")
|
|
memory = AgentMemory()
|
|
memory.store(
|
|
"Original memory",
|
|
memory_id="mem-1",
|
|
timestamp=datetime.fromisoformat("2026-07-22T09:00:00+00:00"),
|
|
metadata={
|
|
"type": "note",
|
|
"updated_at": "2026-07-22T10:00:00+00:00",
|
|
},
|
|
)
|
|
return graph, memory, MarkdownResourceRegistry(graph, memory)
|
|
|
|
|
|
def test_registry_routes_context_nodes_and_returns_canonical_revision():
|
|
graph, _, resources = _resources()
|
|
ref = MarkdownResourceRef(MarkdownResourceKind.CONTEXT_NODE, "node-1")
|
|
|
|
document = resources.read(ref)
|
|
|
|
assert document.body == "Original node"
|
|
assert document.revision == document_revision(document.source)
|
|
edited = document.source.replace("Original node", "Updated node")
|
|
result = resources.apply(ref, edited, document.revision)
|
|
assert result.changed is True
|
|
assert result.body == "Updated node"
|
|
assert graph.nodes["node-1"].content == "Updated node"
|
|
|
|
|
|
def test_registry_routes_agent_memory_without_touching_context_graph():
|
|
graph, memory, resources = _resources()
|
|
ref = MarkdownResourceRef(MarkdownResourceKind.AGENT_MEMORY, "mem-1")
|
|
before_nodes = dict(graph.nodes)
|
|
document = resources.read(ref)
|
|
|
|
result = resources.apply(
|
|
ref,
|
|
document.source.replace("Original memory", "Updated memory"),
|
|
document.revision,
|
|
)
|
|
|
|
assert result.body == "Updated memory"
|
|
assert memory.get("mem-1")["content"] == "Updated memory"
|
|
assert graph.nodes == before_nodes
|
|
|
|
|
|
def test_registry_rejects_stale_revision_and_preserves_current_state():
|
|
graph, _, resources = _resources()
|
|
ref = MarkdownResourceRef(MarkdownResourceKind.CONTEXT_NODE, "node-1")
|
|
first = resources.read(ref)
|
|
resources.apply(
|
|
ref,
|
|
first.source.replace("Original node", "First update"),
|
|
first.revision,
|
|
)
|
|
|
|
with pytest.raises(MarkdownRevisionConflict) as error:
|
|
resources.apply(
|
|
ref,
|
|
first.source.replace("Original node", "Stale update"),
|
|
first.revision,
|
|
)
|
|
|
|
assert error.value.current_revision == resources.read(ref).revision
|
|
assert graph.nodes["node-1"].content == "First update"
|
|
|
|
|
|
def test_registry_missing_adapter_and_resources_are_structured():
|
|
graph, _, _ = _resources()
|
|
resources = MarkdownResourceRegistry(graph)
|
|
|
|
with pytest.raises(MarkdownResourceNotFound, match="not available"):
|
|
resources.read(MarkdownResourceRef(MarkdownResourceKind.AGENT_MEMORY, "mem-1"))
|
|
with pytest.raises(MarkdownResourceNotFound, match="missing"):
|
|
resources.read(
|
|
MarkdownResourceRef(MarkdownResourceKind.CONTEXT_NODE, "missing")
|
|
)
|
|
|
|
|
|
def test_registry_does_not_expose_adapter_failure_details(monkeypatch):
|
|
graph, _, resources = _resources()
|
|
ref = MarkdownResourceRef(MarkdownResourceKind.CONTEXT_NODE, "node-1")
|
|
document = resources.read(ref)
|
|
|
|
def fail(_resource_id, _source):
|
|
raise RuntimeError("private backend failure")
|
|
|
|
monkeypatch.setattr(graph, "apply_node_markdown", fail)
|
|
with pytest.raises(MarkdownSaveFailed) as error:
|
|
resources.apply(ref, document.source + "changed", document.revision)
|
|
|
|
assert error.value.message == (
|
|
"The edit could not be applied. The existing item was not changed."
|
|
)
|
|
assert "private backend failure" not in error.value.message
|