tribalmemory 0.2.0__tar.gz → 0.3.0__tar.gz
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.
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/PKG-INFO +1 -1
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/pyproject.toml +1 -1
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/interfaces.py +22 -3
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/mcp/server.py +112 -0
- tribalmemory-0.3.0/src/tribalmemory/services/graph_store.py +627 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/memory.py +285 -11
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/PKG-INFO +1 -1
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/SOURCES.txt +4 -0
- tribalmemory-0.3.0/tests/test_graph_aware_recall.py +375 -0
- tribalmemory-0.3.0/tests/test_graph_memory_integration.py +216 -0
- tribalmemory-0.3.0/tests/test_graph_store.py +263 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/LICENSE +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/README.md +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/setup.cfg +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/config/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/config/providers.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/config/system.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/container/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/container/container.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/base.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/deduplication.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/lancedb.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/memory.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/mock.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/openai.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/timestamp.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/system.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/cli.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/mcp/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/mcp/__main__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/performance/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/performance/benchmarks.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/performance/corpus_generator.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/portability/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/portability/embedding_metadata.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/__main__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/app.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/config.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/models.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/routes.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/deduplication.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/embeddings.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/fts_store.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/import_export.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/reranker.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/session_store.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/vector_store.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/__init__.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/embedding_utils.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/fixtures.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/metrics.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/mocks.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/semantic_expansions.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/utils.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/dependency_links.txt +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/entry_points.txt +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/requires.txt +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/top_level.txt +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_a21_config.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_a21_container.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_a21_providers.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_a21_system.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_benchmarks.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_cli.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_embedding_portability.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_hybrid_search.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_import_export.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_local_embeddings.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_mcp_integration.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_mcp_server.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_memory_harness.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_negative_security.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_performance.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_reranking.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_server.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_services.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_session_store.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_tier1_functional.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_tier2_capability.py +0 -0
- {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_tier3_emergence.py +0 -0
|
@@ -7,9 +7,12 @@ from abc import ABC, abstractmethod
|
|
|
7
7
|
from dataclasses import dataclass, field
|
|
8
8
|
from datetime import datetime
|
|
9
9
|
from enum import Enum
|
|
10
|
-
from typing import Optional
|
|
10
|
+
from typing import Literal, Optional
|
|
11
11
|
import uuid
|
|
12
12
|
|
|
13
|
+
# Valid retrieval methods for RecallResult
|
|
14
|
+
RetrievalMethod = Literal["vector", "graph", "hybrid", "entity"]
|
|
15
|
+
|
|
13
16
|
|
|
14
17
|
class MemorySource(Enum):
|
|
15
18
|
"""Source of a memory entry."""
|
|
@@ -69,13 +72,21 @@ class MemoryEntry:
|
|
|
69
72
|
|
|
70
73
|
@dataclass
|
|
71
74
|
class RecallResult:
|
|
72
|
-
"""Result of a memory recall query.
|
|
75
|
+
"""Result of a memory recall query.
|
|
76
|
+
|
|
77
|
+
Attributes:
|
|
78
|
+
memory: The recalled memory entry.
|
|
79
|
+
similarity_score: Relevance score (0.0-1.0 for vector, 1.0 for exact entity match).
|
|
80
|
+
retrieval_time_ms: Time taken for retrieval.
|
|
81
|
+
retrieval_method: How this result was found (see RetrievalMethod type).
|
|
82
|
+
"""
|
|
73
83
|
memory: MemoryEntry
|
|
74
84
|
similarity_score: float
|
|
75
85
|
retrieval_time_ms: float
|
|
86
|
+
retrieval_method: RetrievalMethod = "vector"
|
|
76
87
|
|
|
77
88
|
def __repr__(self) -> str:
|
|
78
|
-
return f"RecallResult(score={self.similarity_score:.3f}, memory_id={self.memory.id[:8]}...)"
|
|
89
|
+
return f"RecallResult(score={self.similarity_score:.3f}, method={self.retrieval_method}, memory_id={self.memory.id[:8]}...)"
|
|
79
90
|
|
|
80
91
|
|
|
81
92
|
@dataclass
|
|
@@ -315,6 +326,7 @@ class IMemoryService(ABC):
|
|
|
315
326
|
limit: int = 5,
|
|
316
327
|
min_relevance: float = 0.7,
|
|
317
328
|
tags: Optional[list[str]] = None,
|
|
329
|
+
graph_expansion: bool = True,
|
|
318
330
|
) -> list[RecallResult]:
|
|
319
331
|
"""Recall relevant memories for a query.
|
|
320
332
|
|
|
@@ -323,6 +335,13 @@ class IMemoryService(ABC):
|
|
|
323
335
|
limit: Maximum results
|
|
324
336
|
min_relevance: Minimum similarity score
|
|
325
337
|
tags: Filter by tags (e.g., ["work", "preferences"])
|
|
338
|
+
graph_expansion: Expand candidates via entity graph (default True)
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
List of RecallResult objects with retrieval_method indicating source:
|
|
342
|
+
- "vector": Vector similarity search
|
|
343
|
+
- "hybrid": Vector + BM25 merge
|
|
344
|
+
- "graph": Entity graph traversal
|
|
326
345
|
"""
|
|
327
346
|
pass
|
|
328
347
|
|
|
@@ -412,6 +412,118 @@ def create_server() -> FastMCP:
|
|
|
412
412
|
|
|
413
413
|
return json.dumps(stats)
|
|
414
414
|
|
|
415
|
+
@mcp.tool()
|
|
416
|
+
async def tribal_recall_entity(
|
|
417
|
+
entity_name: str,
|
|
418
|
+
hops: int = 1,
|
|
419
|
+
limit: int = 10,
|
|
420
|
+
) -> str:
|
|
421
|
+
"""Recall memories associated with an entity and its connections.
|
|
422
|
+
|
|
423
|
+
Enables entity-centric queries like:
|
|
424
|
+
- "Tell me everything about auth-service"
|
|
425
|
+
- "What do we know about PostgreSQL?"
|
|
426
|
+
- "What services connect to the user database?"
|
|
427
|
+
|
|
428
|
+
Args:
|
|
429
|
+
entity_name: Name of the entity to query (required).
|
|
430
|
+
Examples: "auth-service", "PostgreSQL", "user-db"
|
|
431
|
+
hops: Number of relationship hops to traverse (default 1).
|
|
432
|
+
1 = direct connections only
|
|
433
|
+
2 = connections of connections
|
|
434
|
+
limit: Maximum number of results (1-50, default 10)
|
|
435
|
+
|
|
436
|
+
Returns:
|
|
437
|
+
JSON with: results (list of memories), entity, hops, count
|
|
438
|
+
"""
|
|
439
|
+
if not entity_name or not entity_name.strip():
|
|
440
|
+
return json.dumps({
|
|
441
|
+
"results": [],
|
|
442
|
+
"entity": entity_name,
|
|
443
|
+
"hops": hops,
|
|
444
|
+
"count": 0,
|
|
445
|
+
"error": "Entity name cannot be empty",
|
|
446
|
+
})
|
|
447
|
+
|
|
448
|
+
hops = max(1, min(10, hops)) # Clamp to reasonable range
|
|
449
|
+
limit = max(1, min(50, limit))
|
|
450
|
+
|
|
451
|
+
service = await get_memory_service()
|
|
452
|
+
|
|
453
|
+
if not service.graph_enabled:
|
|
454
|
+
return json.dumps({
|
|
455
|
+
"results": [],
|
|
456
|
+
"entity": entity_name,
|
|
457
|
+
"hops": hops,
|
|
458
|
+
"count": 0,
|
|
459
|
+
"error": "Graph search not enabled. Requires db_path for persistent storage.",
|
|
460
|
+
})
|
|
461
|
+
|
|
462
|
+
results = await service.recall_entity(
|
|
463
|
+
entity_name=entity_name,
|
|
464
|
+
hops=hops,
|
|
465
|
+
limit=limit,
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
return json.dumps({
|
|
469
|
+
"results": [
|
|
470
|
+
{
|
|
471
|
+
"memory_id": r.memory.id,
|
|
472
|
+
"content": r.memory.content,
|
|
473
|
+
"source_type": r.memory.source_type.value,
|
|
474
|
+
"source_instance": r.memory.source_instance,
|
|
475
|
+
"tags": r.memory.tags,
|
|
476
|
+
"created_at": r.memory.created_at.isoformat(),
|
|
477
|
+
}
|
|
478
|
+
for r in results
|
|
479
|
+
],
|
|
480
|
+
"entity": entity_name,
|
|
481
|
+
"hops": hops,
|
|
482
|
+
"count": len(results),
|
|
483
|
+
})
|
|
484
|
+
|
|
485
|
+
@mcp.tool()
|
|
486
|
+
async def tribal_entity_graph(
|
|
487
|
+
entity_name: str,
|
|
488
|
+
hops: int = 2,
|
|
489
|
+
) -> str:
|
|
490
|
+
"""Get the relationship graph around an entity.
|
|
491
|
+
|
|
492
|
+
Useful for understanding how concepts/services/technologies
|
|
493
|
+
are connected in your project knowledge base.
|
|
494
|
+
|
|
495
|
+
Args:
|
|
496
|
+
entity_name: Name of the entity to explore (required)
|
|
497
|
+
hops: How many relationship hops to include (default 2)
|
|
498
|
+
|
|
499
|
+
Returns:
|
|
500
|
+
JSON with: entities (list with name/type), relationships (list with source/target/type)
|
|
501
|
+
"""
|
|
502
|
+
if not entity_name or not entity_name.strip():
|
|
503
|
+
return json.dumps({
|
|
504
|
+
"entities": [],
|
|
505
|
+
"relationships": [],
|
|
506
|
+
"error": "Entity name cannot be empty",
|
|
507
|
+
})
|
|
508
|
+
|
|
509
|
+
hops = max(1, min(5, hops)) # Clamp to reasonable range
|
|
510
|
+
|
|
511
|
+
service = await get_memory_service()
|
|
512
|
+
|
|
513
|
+
if not service.graph_enabled:
|
|
514
|
+
return json.dumps({
|
|
515
|
+
"entities": [],
|
|
516
|
+
"relationships": [],
|
|
517
|
+
"error": "Graph search not enabled. Requires db_path for persistent storage.",
|
|
518
|
+
})
|
|
519
|
+
|
|
520
|
+
graph = service.get_entity_graph(
|
|
521
|
+
entity_name=entity_name,
|
|
522
|
+
hops=hops,
|
|
523
|
+
)
|
|
524
|
+
|
|
525
|
+
return json.dumps(graph)
|
|
526
|
+
|
|
415
527
|
@mcp.tool()
|
|
416
528
|
async def tribal_export(
|
|
417
529
|
tags: Optional[list[str]] = None,
|