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.
Files changed (85) hide show
  1. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/PKG-INFO +1 -1
  2. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/pyproject.toml +1 -1
  3. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/interfaces.py +22 -3
  4. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/mcp/server.py +112 -0
  5. tribalmemory-0.3.0/src/tribalmemory/services/graph_store.py +627 -0
  6. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/memory.py +285 -11
  7. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/PKG-INFO +1 -1
  8. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/SOURCES.txt +4 -0
  9. tribalmemory-0.3.0/tests/test_graph_aware_recall.py +375 -0
  10. tribalmemory-0.3.0/tests/test_graph_memory_integration.py +216 -0
  11. tribalmemory-0.3.0/tests/test_graph_store.py +263 -0
  12. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/LICENSE +0 -0
  13. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/README.md +0 -0
  14. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/setup.cfg +0 -0
  15. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/__init__.py +0 -0
  16. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/__init__.py +0 -0
  17. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/config/__init__.py +0 -0
  18. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/config/providers.py +0 -0
  19. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/config/system.py +0 -0
  20. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/container/__init__.py +0 -0
  21. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/container/container.py +0 -0
  22. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/__init__.py +0 -0
  23. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/base.py +0 -0
  24. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/deduplication.py +0 -0
  25. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/lancedb.py +0 -0
  26. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/memory.py +0 -0
  27. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/mock.py +0 -0
  28. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/openai.py +0 -0
  29. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/providers/timestamp.py +0 -0
  30. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/a21/system.py +0 -0
  31. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/cli.py +0 -0
  32. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/mcp/__init__.py +0 -0
  33. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/mcp/__main__.py +0 -0
  34. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/performance/__init__.py +0 -0
  35. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/performance/benchmarks.py +0 -0
  36. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/performance/corpus_generator.py +0 -0
  37. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/portability/__init__.py +0 -0
  38. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/portability/embedding_metadata.py +0 -0
  39. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/__init__.py +0 -0
  40. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/__main__.py +0 -0
  41. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/app.py +0 -0
  42. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/config.py +0 -0
  43. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/models.py +0 -0
  44. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/server/routes.py +0 -0
  45. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/__init__.py +0 -0
  46. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/deduplication.py +0 -0
  47. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/embeddings.py +0 -0
  48. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/fts_store.py +0 -0
  49. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/import_export.py +0 -0
  50. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/reranker.py +0 -0
  51. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/session_store.py +0 -0
  52. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/services/vector_store.py +0 -0
  53. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/__init__.py +0 -0
  54. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/embedding_utils.py +0 -0
  55. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/fixtures.py +0 -0
  56. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/metrics.py +0 -0
  57. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/mocks.py +0 -0
  58. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/testing/semantic_expansions.py +0 -0
  59. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory/utils.py +0 -0
  60. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/dependency_links.txt +0 -0
  61. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/entry_points.txt +0 -0
  62. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/requires.txt +0 -0
  63. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/src/tribalmemory.egg-info/top_level.txt +0 -0
  64. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_a21_config.py +0 -0
  65. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_a21_container.py +0 -0
  66. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_a21_providers.py +0 -0
  67. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_a21_system.py +0 -0
  68. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_benchmarks.py +0 -0
  69. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_cli.py +0 -0
  70. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_embedding_portability.py +0 -0
  71. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_hybrid_search.py +0 -0
  72. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_import_export.py +0 -0
  73. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_local_embeddings.py +0 -0
  74. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_mcp_integration.py +0 -0
  75. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_mcp_server.py +0 -0
  76. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_memory_harness.py +0 -0
  77. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_negative_security.py +0 -0
  78. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_performance.py +0 -0
  79. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_reranking.py +0 -0
  80. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_server.py +0 -0
  81. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_services.py +0 -0
  82. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_session_store.py +0 -0
  83. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_tier1_functional.py +0 -0
  84. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_tier2_capability.py +0 -0
  85. {tribalmemory-0.2.0 → tribalmemory-0.3.0}/tests/test_tier3_emergence.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tribalmemory
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Shared memory infrastructure for multi-instance AI agents
5
5
  Author-email: Joe <joe@example.com>
6
6
  License: Apache-2.0
@@ -7,7 +7,7 @@ where = ["src"]
7
7
 
8
8
  [project]
9
9
  name = "tribalmemory"
10
- version = "0.2.0"
10
+ version = "0.3.0"
11
11
  description = "Shared memory infrastructure for multi-instance AI agents"
12
12
  readme = "README.md"
13
13
  license = {text = "Apache-2.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,