memuron 0.1.1__py3-none-any.whl

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 (74) hide show
  1. memuron/__init__.py +3 -0
  2. memuron/actions/__init__.py +12 -0
  3. memuron/actions/context.py +63 -0
  4. memuron/actions/helpers.py +88 -0
  5. memuron/actions/memory.py +340 -0
  6. memuron/actions/memory_write.py +290 -0
  7. memuron/actions/nodes.py +340 -0
  8. memuron/actions/registry.py +5 -0
  9. memuron/actions/runtime.py +37 -0
  10. memuron/actions/spaces_documents.py +720 -0
  11. memuron/actions/sync.py +155 -0
  12. memuron/application/__init__.py +1 -0
  13. memuron/application/api.py +206 -0
  14. memuron/application/app.py +103 -0
  15. memuron/application/capabilities.py +82 -0
  16. memuron/application/cli.py +35 -0
  17. memuron/application/config.py +176 -0
  18. memuron/application/mcp.py +44 -0
  19. memuron/application/mcp_oauth.py +290 -0
  20. memuron/application/registry.py +52 -0
  21. memuron/context.py +532 -0
  22. memuron/documents/__init__.py +1 -0
  23. memuron/documents/link_guardian.py +192 -0
  24. memuron/documents/linking.py +292 -0
  25. memuron/documents/parser.py +1152 -0
  26. memuron/documents/storage.py +151 -0
  27. memuron/documents/url_ingest.py +375 -0
  28. memuron/domain/__init__.py +1 -0
  29. memuron/domain/decoders.py +1 -0
  30. memuron/domain/encoders.py +185 -0
  31. memuron/domain/lifecycles.py +8 -0
  32. memuron/domain/limits.py +6 -0
  33. memuron/domain/representations.py +56 -0
  34. memuron/domain/schemas.py +581 -0
  35. memuron/domain/scope_filter.py +104 -0
  36. memuron/graphfs/__init__.py +1 -0
  37. memuron/graphfs/manual.py +635 -0
  38. memuron/graphfs/projection.py +578 -0
  39. memuron/graphfs/query.py +1782 -0
  40. memuron/graphfs/read_model.py +574 -0
  41. memuron/ingest/__init__.py +1 -0
  42. memuron/ingest/guardian.py +213 -0
  43. memuron/ingest/jobs.py +424 -0
  44. memuron/ingest/prompts.py +147 -0
  45. memuron/memory/__init__.py +1 -0
  46. memuron/memory/engine.py +35 -0
  47. memuron/memory/projections.py +452 -0
  48. memuron/memory/recipes.py +3247 -0
  49. memuron/persistence/__init__.py +1 -0
  50. memuron/persistence/db_pool.py +57 -0
  51. memuron/persistence/identity_store.py +918 -0
  52. memuron/persistence/store_helpers.py +16 -0
  53. memuron/search/__init__.py +1 -0
  54. memuron/search/fulltext.py +110 -0
  55. memuron/search/hybrid.py +284 -0
  56. memuron/search/pgvector.py +252 -0
  57. memuron/security/__init__.py +1 -0
  58. memuron/security/auth.py +143 -0
  59. memuron/security/auth_provider.py +119 -0
  60. memuron/security/authorization.py +53 -0
  61. memuron/security/clerk_scopes.py +94 -0
  62. memuron/security/clerk_webhooks.py +61 -0
  63. memuron/security/jwt_tokens.py +53 -0
  64. memuron/security/passwords.py +38 -0
  65. memuron/security/tenant.py +58 -0
  66. memuron/spaces/__init__.py +1 -0
  67. memuron/spaces/model.py +35 -0
  68. memuron/spaces/service.py +155 -0
  69. memuron/sync/__init__.py +25 -0
  70. memuron/sync/folder.py +828 -0
  71. memuron-0.1.1.dist-info/METADATA +242 -0
  72. memuron-0.1.1.dist-info/RECORD +74 -0
  73. memuron-0.1.1.dist-info/WHEEL +4 -0
  74. memuron-0.1.1.dist-info/entry_points.txt +4 -0
@@ -0,0 +1,185 @@
1
+ """Product-specific encoders."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import Any
7
+ from uuid import uuid4
8
+
9
+ from artha_engine.embeddings import TextEmbedder
10
+ from artha_engine.encoders.base import Encoder
11
+
12
+ from memuron.domain.representations import (
13
+ MemoryArthaanu,
14
+ MemoryLinkArthaanu,
15
+ MemoryLinkValue,
16
+ MemoryPlacementArthaanu,
17
+ MemoryPlacementValue,
18
+ MemoryValue,
19
+ )
20
+
21
+
22
+ @dataclass(frozen=True)
23
+ class MemoryEncoderInput:
24
+ content: str
25
+ scope: list[str] = field(default_factory=list)
26
+ node_type: str = "text"
27
+ payload: dict[str, Any] = field(default_factory=dict)
28
+ perception: str | None = None
29
+ encoding: str = "memory"
30
+ metadata: dict[str, Any] = field(default_factory=dict)
31
+ artha_id: str | None = None
32
+ name: str = "memory"
33
+ retrieval_count: int = 0
34
+
35
+
36
+ @dataclass(frozen=True)
37
+ class MemoryLinkEncoderInput:
38
+ source_id: str
39
+ target_id: str
40
+ description: str
41
+ metadata: dict[str, Any] = field(default_factory=dict)
42
+ name: str = "memory_link"
43
+ artha_id: str | None = None
44
+
45
+
46
+ @dataclass(frozen=True)
47
+ class MemoryPlacementEncoderInput:
48
+ parent_id: str
49
+ child_id: str
50
+ name: str
51
+ scope: list[str] = field(default_factory=list)
52
+ metadata: dict[str, Any] = field(default_factory=dict)
53
+ inherit_parent_scope: bool = True
54
+ artha_id: str | None = None
55
+
56
+
57
+ class MemoryEncoder(Encoder[MemoryEncoderInput, MemoryArthaanu]):
58
+ name = "memory"
59
+ version = "0.1.0"
60
+ output_value_type = "memory"
61
+
62
+ def __init__(self, embedder: TextEmbedder | None = None) -> None:
63
+ self.embedder = embedder
64
+
65
+ def encode(self, source: MemoryEncoderInput) -> MemoryArthaanu:
66
+ embedding: list[float] = []
67
+ perception = source.perception or source.content
68
+ if self.embedder is not None and perception.strip():
69
+ embedding = self.embedder.embed_documents([perception])[0]
70
+ artha_id = source.artha_id or f"artha_{uuid4().hex}"
71
+ return MemoryArthaanu(
72
+ artha_id=artha_id,
73
+ name=source.name,
74
+ value=MemoryValue(
75
+ content=source.content,
76
+ node_type=source.node_type, # type: ignore[arg-type]
77
+ payload=dict(source.payload),
78
+ perception=perception,
79
+ encoding=source.encoding,
80
+ metadata=dict(source.metadata),
81
+ scope=list(source.scope),
82
+ embedding=embedding,
83
+ retrieval_count=source.retrieval_count,
84
+ ),
85
+ )
86
+
87
+
88
+ class MemoryLinkEncoder(Encoder[MemoryLinkEncoderInput, MemoryLinkArthaanu]):
89
+ name = "memory_link"
90
+ version = "0.1.0"
91
+ output_value_type = "memory_link"
92
+
93
+ def __init__(self, embedder: TextEmbedder | None = None) -> None:
94
+ self.embedder = embedder
95
+
96
+ def encode(self, source: MemoryLinkEncoderInput) -> MemoryLinkArthaanu:
97
+ embedding: list[float] = []
98
+ if self.embedder is not None and source.description.strip():
99
+ embedding = self.embedder.embed_documents([source.description])[0]
100
+ artha_id = source.artha_id or f"artha_{uuid4().hex}"
101
+ return MemoryLinkArthaanu(
102
+ artha_id=artha_id,
103
+ name=source.name,
104
+ value=MemoryLinkValue(
105
+ source_id=source.source_id,
106
+ target_id=source.target_id,
107
+ description=source.description,
108
+ metadata=dict(source.metadata),
109
+ embedding=embedding,
110
+ ),
111
+ )
112
+
113
+
114
+ class MemoryPlacementEncoder(Encoder[MemoryPlacementEncoderInput, MemoryPlacementArthaanu]):
115
+ name = "memory_placement"
116
+ version = "0.1.0"
117
+ output_value_type = "memory_placement"
118
+
119
+ def encode(self, source: MemoryPlacementEncoderInput) -> MemoryPlacementArthaanu:
120
+ artha_id = source.artha_id or f"placement_{uuid4().hex}"
121
+ return MemoryPlacementArthaanu(
122
+ artha_id=artha_id,
123
+ name="memory_placement",
124
+ value=MemoryPlacementValue(
125
+ parent_id=source.parent_id,
126
+ child_id=source.child_id,
127
+ name=source.name,
128
+ scope=list(source.scope),
129
+ metadata=dict(source.metadata),
130
+ inherit_parent_scope=source.inherit_parent_scope,
131
+ ),
132
+ )
133
+
134
+
135
+ def normalize_memory_encoder_input(raw_input: object) -> MemoryEncoderInput:
136
+ if isinstance(raw_input, MemoryEncoderInput):
137
+ return raw_input
138
+ if isinstance(raw_input, dict):
139
+ data: dict[str, Any] = raw_input
140
+ return MemoryEncoderInput(
141
+ content=str(data["content"]),
142
+ scope=[str(item) for item in data.get("scope") or []],
143
+ node_type=str(data.get("node_type") or data.get("type") or "text"),
144
+ payload=dict(data.get("payload") or {}),
145
+ perception=str(data["perception"]) if data.get("perception") is not None else None,
146
+ encoding=str(data.get("encoding") or "memory"),
147
+ metadata=dict(data.get("metadata") or {}),
148
+ artha_id=data.get("artha_id"),
149
+ name=str(data.get("name") or "memory"),
150
+ retrieval_count=int(data.get("retrieval_count") or 0),
151
+ )
152
+ raise ValueError("memory encoder requires MemoryEncoderInput or dict")
153
+
154
+
155
+ def normalize_memory_link_encoder_input(raw_input: object) -> MemoryLinkEncoderInput:
156
+ if isinstance(raw_input, MemoryLinkEncoderInput):
157
+ return raw_input
158
+ if isinstance(raw_input, dict):
159
+ data: dict[str, Any] = raw_input
160
+ return MemoryLinkEncoderInput(
161
+ source_id=str(data["source_id"]),
162
+ target_id=str(data["target_id"]),
163
+ description=str(data["description"]),
164
+ metadata=dict(data.get("metadata") or {}),
165
+ name=str(data.get("name") or "memory_link"),
166
+ artha_id=data.get("artha_id"),
167
+ )
168
+ raise ValueError("memory_link encoder requires MemoryLinkEncoderInput or dict")
169
+
170
+
171
+ def normalize_memory_placement_encoder_input(raw_input: object) -> MemoryPlacementEncoderInput:
172
+ if isinstance(raw_input, MemoryPlacementEncoderInput):
173
+ return raw_input
174
+ if isinstance(raw_input, dict):
175
+ data: dict[str, Any] = raw_input
176
+ return MemoryPlacementEncoderInput(
177
+ parent_id=str(data["parent_id"]),
178
+ child_id=str(data["child_id"]),
179
+ name=str(data["name"]),
180
+ scope=[str(item) for item in data.get("scope") or []],
181
+ metadata=dict(data.get("metadata") or {}),
182
+ inherit_parent_scope=bool(data.get("inherit_parent_scope", True)),
183
+ artha_id=data.get("artha_id"),
184
+ )
185
+ raise ValueError("memory_placement encoder requires MemoryPlacementEncoderInput or dict")
@@ -0,0 +1,8 @@
1
+ """Product-specific lifecycle steps live here.
2
+
3
+ Guardian write planning (create/update/link/consolidate) currently lives in
4
+ recipes.py + guardian.py as an intentional v0 slice. When Memuron adds
5
+ reinforcement, merge, supersession, archival, or reflection, those transitions
6
+ should become registered lifecycles so transformations are explicit, replayable,
7
+ and reusable outside a single recipe.
8
+ """
@@ -0,0 +1,6 @@
1
+ """Memory content limits."""
2
+
3
+ MAX_MEMORY_CONTENT = 50_000
4
+ MAX_ADD_MEMORY_CONTENT = MAX_MEMORY_CONTENT * 10
5
+ MAX_SCOPE_ITEMS = 50
6
+ MAX_SCOPE_TOKEN_LEN = 256
@@ -0,0 +1,56 @@
1
+ """Product-specific Arthaanu representation classes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Literal
6
+
7
+ from pydantic import BaseModel, ConfigDict, Field
8
+
9
+ from artha_engine.representations import Arthaanu
10
+
11
+
12
+ class MemoryValue(BaseModel):
13
+ model_config = ConfigDict(frozen=True)
14
+
15
+ content: str
16
+ node_type: Literal["text", "image", "document", "collection"] = "text"
17
+ payload: dict[str, Any] = Field(default_factory=dict)
18
+ perception: str | None = None
19
+ encoding: str = "memory"
20
+ metadata: dict[str, Any] = Field(default_factory=dict)
21
+ scope: list[str] = Field(default_factory=list)
22
+ embedding: list[float] = Field(default_factory=list)
23
+ retrieval_count: int = 0
24
+
25
+
26
+ class MemoryArthaanu(Arthaanu[MemoryValue]):
27
+ value_type: Literal["memory"] = "memory"
28
+
29
+
30
+ class MemoryLinkValue(BaseModel):
31
+ model_config = ConfigDict(frozen=True)
32
+
33
+ source_id: str
34
+ target_id: str
35
+ description: str
36
+ metadata: dict[str, Any] = Field(default_factory=dict)
37
+ embedding: list[float] = Field(default_factory=list)
38
+
39
+
40
+ class MemoryLinkArthaanu(Arthaanu[MemoryLinkValue]):
41
+ value_type: Literal["memory_link"] = "memory_link"
42
+
43
+
44
+ class MemoryPlacementValue(BaseModel):
45
+ model_config = ConfigDict(frozen=True)
46
+
47
+ parent_id: str
48
+ child_id: str
49
+ name: str
50
+ scope: list[str] = Field(default_factory=list)
51
+ metadata: dict[str, Any] = Field(default_factory=dict)
52
+ inherit_parent_scope: bool = True
53
+
54
+
55
+ class MemoryPlacementArthaanu(Arthaanu[MemoryPlacementValue]):
56
+ value_type: Literal["memory_placement"] = "memory_placement"