sozograph 0.1.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.
- sozograph-0.1.0/.gitignore +54 -0
- sozograph-0.1.0/LICENSE +21 -0
- sozograph-0.1.0/PKG-INFO +308 -0
- sozograph-0.1.0/README.md +280 -0
- sozograph-0.1.0/pyproject.toml +64 -0
- sozograph-0.1.0/src/sozograph/__init__.py +6 -0
- sozograph-0.1.0/src/sozograph/adapters/__init__.py +12 -0
- sozograph-0.1.0/src/sozograph/adapters/firestore.py +104 -0
- sozograph-0.1.0/src/sozograph/adapters/rtdb.py +91 -0
- sozograph-0.1.0/src/sozograph/adapters/supabase.py +103 -0
- sozograph-0.1.0/src/sozograph/core.py +143 -0
- sozograph-0.1.0/src/sozograph/extractor.py +120 -0
- sozograph-0.1.0/src/sozograph/ingest.py +437 -0
- sozograph-0.1.0/src/sozograph/interaction.py +70 -0
- sozograph-0.1.0/src/sozograph/prompts.py +96 -0
- sozograph-0.1.0/src/sozograph/render.py +217 -0
- sozograph-0.1.0/src/sozograph/resolver.py +268 -0
- sozograph-0.1.0/src/sozograph/schema.py +241 -0
- sozograph-0.1.0/src/sozograph/utils.py +149 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# -----------------------------
|
|
2
|
+
# Python
|
|
3
|
+
# -----------------------------
|
|
4
|
+
__pycache__/
|
|
5
|
+
*.py[cod]
|
|
6
|
+
*$py.class
|
|
7
|
+
|
|
8
|
+
# Virtual environments
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
ENV/
|
|
12
|
+
env/
|
|
13
|
+
|
|
14
|
+
# Build artifacts
|
|
15
|
+
build/
|
|
16
|
+
dist/
|
|
17
|
+
*.egg-info/
|
|
18
|
+
.eggs/
|
|
19
|
+
|
|
20
|
+
# Packaging
|
|
21
|
+
pip-wheel-metadata/
|
|
22
|
+
|
|
23
|
+
# -----------------------------
|
|
24
|
+
# Environment / secrets
|
|
25
|
+
# -----------------------------
|
|
26
|
+
.env
|
|
27
|
+
.env.*
|
|
28
|
+
!.env.example
|
|
29
|
+
|
|
30
|
+
# -----------------------------
|
|
31
|
+
# Editors / IDEs
|
|
32
|
+
# -----------------------------
|
|
33
|
+
.vscode/
|
|
34
|
+
.idea/
|
|
35
|
+
*.swp
|
|
36
|
+
*.swo
|
|
37
|
+
.DS_Store
|
|
38
|
+
|
|
39
|
+
# -----------------------------
|
|
40
|
+
# Testing / coverage
|
|
41
|
+
# -----------------------------
|
|
42
|
+
.pytest_cache/
|
|
43
|
+
.coverage
|
|
44
|
+
htmlcov/
|
|
45
|
+
|
|
46
|
+
# -----------------------------
|
|
47
|
+
# Logs
|
|
48
|
+
# -----------------------------
|
|
49
|
+
*.log
|
|
50
|
+
|
|
51
|
+
# -----------------------------
|
|
52
|
+
# OS
|
|
53
|
+
# -----------------------------
|
|
54
|
+
Thumbs.db
|
sozograph-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sozo Analytics Lab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
sozograph-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sozograph
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: SozoGraph v1: transcript/db object -> portable cognitive passport JSON
|
|
5
|
+
Project-URL: Homepage, https://github.com/quantilytix/sozograph
|
|
6
|
+
Project-URL: Repository, https://github.com/quantilytix/sozograph
|
|
7
|
+
Project-URL: Issues, https://github.com/quantilytix/sozograph/issues
|
|
8
|
+
Author: Rairo Mukamuri
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agents,context,gemini,knowledge,memory,passport
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Requires-Dist: google-genai>=0.6.0
|
|
22
|
+
Requires-Dist: pydantic>=2.7.0
|
|
23
|
+
Requires-Dist: python-dotenv>=1.0.1
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: ruff>=0.6.0; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# SozoGraph (v1) — The Cognitive Passport
|
|
31
|
+
|
|
32
|
+
**SozoGraph** turns interaction history (transcripts + DB objects) into a **portable cognitive snapshot** you can pass into any AI agent context on the fly.
|
|
33
|
+
|
|
34
|
+
It answers one question cleanly:
|
|
35
|
+
|
|
36
|
+
> "Given everything that has happened so far, what should an agent **currently believe** about this user?"
|
|
37
|
+
|
|
38
|
+
Not:
|
|
39
|
+
- what was said
|
|
40
|
+
- what is similar
|
|
41
|
+
- what might be relevant
|
|
42
|
+
|
|
43
|
+
But:
|
|
44
|
+
- what is true now
|
|
45
|
+
- what is stable
|
|
46
|
+
- what is unresolved
|
|
47
|
+
- what is contradictory (resolved by time)
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Why this exists (the problem)
|
|
52
|
+
|
|
53
|
+
Most "memory" systems are either:
|
|
54
|
+
- **prompt stuffing** (expensive, degrades reasoning, no forgetting)
|
|
55
|
+
- **vector RAG** (good recall, weak truth/temporal consistency)
|
|
56
|
+
- **app-specific notes** (non-portable, brittle schemas)
|
|
57
|
+
|
|
58
|
+
So agents keep acting like "goldfish" even when data exists.
|
|
59
|
+
|
|
60
|
+
SozoGraph v1 is a **truth-layer memory object**:
|
|
61
|
+
- typed (facts vs preferences vs entities vs open loops)
|
|
62
|
+
- temporal (new updates override old; contradictions are explicit)
|
|
63
|
+
- portable (a lightweight JSON passport + a compact context string)
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install sozograph
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
-----
|
|
74
|
+
|
|
75
|
+
## Configure
|
|
76
|
+
|
|
77
|
+
Create a `.env` file (see `.env.example`):
|
|
78
|
+
|
|
79
|
+
```env
|
|
80
|
+
GEMINI_API_KEY=your_key_here
|
|
81
|
+
SOZOGRAPH_EXTRACTOR_MODEL=gemini-3-flash
|
|
82
|
+
SOZOGRAPH_ENABLE_FALLBACK_SUMMARIZER=true
|
|
83
|
+
SOZOGRAPH_MAX_INTERACTION_CHARS=4000
|
|
84
|
+
SOZOGRAPH_DEFAULT_CONTEXT_BUDGET=3000
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
-----
|
|
88
|
+
|
|
89
|
+
## Quickstart
|
|
90
|
+
|
|
91
|
+
### 1) Single transcript → Passport
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from sozograph import SozoGraph
|
|
95
|
+
|
|
96
|
+
sg = SozoGraph()
|
|
97
|
+
|
|
98
|
+
passport, stats = sg.ingest(
|
|
99
|
+
"I'm Quantilytix. I build software and want direct answers. I'm working on SozoGraph v1.",
|
|
100
|
+
meta={"user_key": "u_123", "source": "transcript:demo-1"}
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
print(passport.to_compact_dict())
|
|
104
|
+
print(stats) # per-interaction merge stats
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
-----
|
|
108
|
+
|
|
109
|
+
### 2) List of transcripts / message history (supported ✅)
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
history = [
|
|
113
|
+
{"createdAt": "2026-02-01T10:00:00Z", "project_title": "SozoFix", "transcript": "I'm renovating my kitchen."},
|
|
114
|
+
{"createdAt": "2026-02-02T09:30:00Z", "project_title": "SozoFix", "transcript": "I prefer rustic style and hate glossy paint."},
|
|
115
|
+
{"createdAt": "2026-02-03T12:10:00Z", "project_title": "SozoGraph", "transcript": "We need portable memory JSON. No infra. Truth-layer."},
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
# You can ingest a list directly. SozoGraph will coerce items internally.
|
|
119
|
+
passport, _ = sg.ingest(history, hint="firestore") # hint optional; see below
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Tip:** If your list items aren’t “docs”, you can pass them as plain dicts and let fallback summarization help when needed. If your dicts contain a `transcript` field, extraction will still succeed (it will stringify deterministically).
|
|
123
|
+
|
|
124
|
+
-----
|
|
125
|
+
|
|
126
|
+
### 3) Firestore object ingestion (objects-only)
|
|
127
|
+
|
|
128
|
+
You fetch your Firestore data in your app, then pass the dict here:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
firestore_doc = {
|
|
132
|
+
"id": "abc123",
|
|
133
|
+
"createdAt": "2026-02-03T10:00:00Z",
|
|
134
|
+
"title": "User Profile Update",
|
|
135
|
+
"notes": "User says they prefer direct answers.",
|
|
136
|
+
"companyCode": "QX",
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
passport, _ = sg.ingest(
|
|
140
|
+
firestore_doc,
|
|
141
|
+
hint="firestore",
|
|
142
|
+
meta={"source": "firestore:/users/abc123", "user_key": "u_abc123"}
|
|
143
|
+
)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
-----
|
|
147
|
+
|
|
148
|
+
### 4) Firebase Realtime DB ingestion (path + value)
|
|
149
|
+
|
|
150
|
+
RTDB is tree-based, so pass an envelope:
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
rtdb_snapshot = {
|
|
154
|
+
"path": "/users/u1/profile",
|
|
155
|
+
"value": {
|
|
156
|
+
"updatedAt": 1738560000000,
|
|
157
|
+
"displayName": "Quantilytix",
|
|
158
|
+
"preferences": {"tone": "direct"}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
passport, _ = sg.ingest(rtdb_snapshot, hint="rtdb", meta={"user_key": "u1"})
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
-----
|
|
166
|
+
|
|
167
|
+
### 5) Supabase ingestion (table + row)
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
supabase_row = {
|
|
171
|
+
"table": "events",
|
|
172
|
+
"row": {
|
|
173
|
+
"id": 77,
|
|
174
|
+
"created_at": "2026-02-03T11:22:00Z",
|
|
175
|
+
"event": "user_preference_update",
|
|
176
|
+
"notes": "User wants strategy alignment before code."
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
passport, _ = sg.ingest(supabase_row, hint="supabase", meta={"user_key": "u1"})
|
|
181
|
+
```
|
|
182
|
+
# SozoGraph Test Fixtures
|
|
183
|
+
|
|
184
|
+
These fixtures are **intentionally small and human-readable**.
|
|
185
|
+
|
|
186
|
+
They are designed to test:
|
|
187
|
+
- transcript ingestion
|
|
188
|
+
- Firestore document ingestion
|
|
189
|
+
- Firebase Realtime Database snapshots
|
|
190
|
+
- Supabase row ingestion
|
|
191
|
+
|
|
192
|
+
They are NOT meant to simulate production-scale data.
|
|
193
|
+
If a fixture grows beyond what a human would comfortably read,
|
|
194
|
+
it is probably violating SozoGraph v1 philosophy.
|
|
195
|
+
-----
|
|
196
|
+
|
|
197
|
+
## Export a compact agent “briefing” (context injection)
|
|
198
|
+
|
|
199
|
+
You can inject this into any agent prompt:
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
briefing = sg.export_context(passport, budget_chars=2500)
|
|
203
|
+
print(briefing)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Example output format:**
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
SOZOGRAPH PASSPORT v1
|
|
210
|
+
User: u1
|
|
211
|
+
Updated: 2026-02-03T12:34:56+00:00
|
|
212
|
+
|
|
213
|
+
Facts (current beliefs):
|
|
214
|
+
- role: software development
|
|
215
|
+
- current_project: sozograph v1
|
|
216
|
+
...
|
|
217
|
+
|
|
218
|
+
Preferences:
|
|
219
|
+
- tone: direct
|
|
220
|
+
...
|
|
221
|
+
|
|
222
|
+
Open loops:
|
|
223
|
+
- finalize v1 repo + publish pip package
|
|
224
|
+
...
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
-----
|
|
228
|
+
|
|
229
|
+
## How SozoGraph v1 works
|
|
230
|
+
|
|
231
|
+
### Ingestion pipeline (v1)
|
|
232
|
+
|
|
233
|
+
1. Coerce input into canonical `Interaction` objects (deterministic)
|
|
234
|
+
1. If the derived text is weak/noisy, call Gemini fallback summarizer (optional)
|
|
235
|
+
1. Use Gemini extractor (strict JSON) to propose memory updates
|
|
236
|
+
1. Use deterministic resolver to merge:
|
|
237
|
+
|
|
238
|
+
- temporal priority (latest wins)
|
|
239
|
+
- explicit contradictions record changes
|
|
240
|
+
- de-dupe entities + aliases
|
|
241
|
+
- keep open loops short and recent
|
|
242
|
+
|
|
243
|
+
### What SozoGraph v1 is NOT
|
|
244
|
+
|
|
245
|
+
- Not a graph database
|
|
246
|
+
- Not RAG
|
|
247
|
+
- Not embeddings
|
|
248
|
+
- Not a long transcript store
|
|
249
|
+
- Not a tool that fetches from DB (objects-only by design)
|
|
250
|
+
|
|
251
|
+
-----
|
|
252
|
+
|
|
253
|
+
## Roadmap (upcoming features)
|
|
254
|
+
|
|
255
|
+
### v1.x (near-term)
|
|
256
|
+
|
|
257
|
+
- Better input detection for common “transcript list” shapes (e.g. `{transcript, createdAt}`)
|
|
258
|
+
- CLI:
|
|
259
|
+
- `sozograph ingest transcript.txt --out passport.json`
|
|
260
|
+
- `sozograph render passport.json --budget 3000`
|
|
261
|
+
- Stronger JSON recovery if a model response is slightly malformed
|
|
262
|
+
- More deterministic evidence linking (source-id mapping improvements)
|
|
263
|
+
|
|
264
|
+
### v1.5 (planned, optional)
|
|
265
|
+
|
|
266
|
+
- Graph engine support (Neo4j Aura / Memgraph) via Bolt
|
|
267
|
+
- Cypher-style relational queries over memory
|
|
268
|
+
- Temporal deprecation on edges
|
|
269
|
+
- Export “active truth subgraph” to context
|
|
270
|
+
|
|
271
|
+
### v2 (optional)
|
|
272
|
+
|
|
273
|
+
- Foundational model adapters (non-Gemini backends)
|
|
274
|
+
- MCP tool server integration
|
|
275
|
+
- Hybrid patterns (graph + vector) only where needed
|
|
276
|
+
|
|
277
|
+
-----
|
|
278
|
+
|
|
279
|
+
## Contributing
|
|
280
|
+
|
|
281
|
+
We want contributions, but keep v1 disciplined.
|
|
282
|
+
|
|
283
|
+
### Good contributions
|
|
284
|
+
|
|
285
|
+
- Adapters for additional object shapes (still objects-only)
|
|
286
|
+
- Resolver improvements (deterministic)
|
|
287
|
+
- Tests for merge/contradiction edge-cases
|
|
288
|
+
- Prompt tuning for more stable key extraction
|
|
289
|
+
|
|
290
|
+
### What won’t be accepted in v1
|
|
291
|
+
|
|
292
|
+
- Adding DB client dependencies (firebase-admin, supabase clients, etc.)
|
|
293
|
+
- Building RAG/embeddings into core
|
|
294
|
+
- Turning v1 into a graph project
|
|
295
|
+
|
|
296
|
+
### How to contribute
|
|
297
|
+
|
|
298
|
+
1. Fork the repo
|
|
299
|
+
1. Create a branch: `feat/<short-name>`
|
|
300
|
+
1. Add tests where relevant
|
|
301
|
+
1. Open a PR with a short explanation and sample input/output
|
|
302
|
+
|
|
303
|
+
-----
|
|
304
|
+
|
|
305
|
+
## License
|
|
306
|
+
|
|
307
|
+
MIT — Sozo Analytics Lab
|
|
308
|
+
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
|
|
2
|
+
# SozoGraph (v1) — The Cognitive Passport
|
|
3
|
+
|
|
4
|
+
**SozoGraph** turns interaction history (transcripts + DB objects) into a **portable cognitive snapshot** you can pass into any AI agent context on the fly.
|
|
5
|
+
|
|
6
|
+
It answers one question cleanly:
|
|
7
|
+
|
|
8
|
+
> "Given everything that has happened so far, what should an agent **currently believe** about this user?"
|
|
9
|
+
|
|
10
|
+
Not:
|
|
11
|
+
- what was said
|
|
12
|
+
- what is similar
|
|
13
|
+
- what might be relevant
|
|
14
|
+
|
|
15
|
+
But:
|
|
16
|
+
- what is true now
|
|
17
|
+
- what is stable
|
|
18
|
+
- what is unresolved
|
|
19
|
+
- what is contradictory (resolved by time)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Why this exists (the problem)
|
|
24
|
+
|
|
25
|
+
Most "memory" systems are either:
|
|
26
|
+
- **prompt stuffing** (expensive, degrades reasoning, no forgetting)
|
|
27
|
+
- **vector RAG** (good recall, weak truth/temporal consistency)
|
|
28
|
+
- **app-specific notes** (non-portable, brittle schemas)
|
|
29
|
+
|
|
30
|
+
So agents keep acting like "goldfish" even when data exists.
|
|
31
|
+
|
|
32
|
+
SozoGraph v1 is a **truth-layer memory object**:
|
|
33
|
+
- typed (facts vs preferences vs entities vs open loops)
|
|
34
|
+
- temporal (new updates override old; contradictions are explicit)
|
|
35
|
+
- portable (a lightweight JSON passport + a compact context string)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install sozograph
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
-----
|
|
46
|
+
|
|
47
|
+
## Configure
|
|
48
|
+
|
|
49
|
+
Create a `.env` file (see `.env.example`):
|
|
50
|
+
|
|
51
|
+
```env
|
|
52
|
+
GEMINI_API_KEY=your_key_here
|
|
53
|
+
SOZOGRAPH_EXTRACTOR_MODEL=gemini-3-flash
|
|
54
|
+
SOZOGRAPH_ENABLE_FALLBACK_SUMMARIZER=true
|
|
55
|
+
SOZOGRAPH_MAX_INTERACTION_CHARS=4000
|
|
56
|
+
SOZOGRAPH_DEFAULT_CONTEXT_BUDGET=3000
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
-----
|
|
60
|
+
|
|
61
|
+
## Quickstart
|
|
62
|
+
|
|
63
|
+
### 1) Single transcript → Passport
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from sozograph import SozoGraph
|
|
67
|
+
|
|
68
|
+
sg = SozoGraph()
|
|
69
|
+
|
|
70
|
+
passport, stats = sg.ingest(
|
|
71
|
+
"I'm Quantilytix. I build software and want direct answers. I'm working on SozoGraph v1.",
|
|
72
|
+
meta={"user_key": "u_123", "source": "transcript:demo-1"}
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
print(passport.to_compact_dict())
|
|
76
|
+
print(stats) # per-interaction merge stats
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
-----
|
|
80
|
+
|
|
81
|
+
### 2) List of transcripts / message history (supported ✅)
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
history = [
|
|
85
|
+
{"createdAt": "2026-02-01T10:00:00Z", "project_title": "SozoFix", "transcript": "I'm renovating my kitchen."},
|
|
86
|
+
{"createdAt": "2026-02-02T09:30:00Z", "project_title": "SozoFix", "transcript": "I prefer rustic style and hate glossy paint."},
|
|
87
|
+
{"createdAt": "2026-02-03T12:10:00Z", "project_title": "SozoGraph", "transcript": "We need portable memory JSON. No infra. Truth-layer."},
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
# You can ingest a list directly. SozoGraph will coerce items internally.
|
|
91
|
+
passport, _ = sg.ingest(history, hint="firestore") # hint optional; see below
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Tip:** If your list items aren’t “docs”, you can pass them as plain dicts and let fallback summarization help when needed. If your dicts contain a `transcript` field, extraction will still succeed (it will stringify deterministically).
|
|
95
|
+
|
|
96
|
+
-----
|
|
97
|
+
|
|
98
|
+
### 3) Firestore object ingestion (objects-only)
|
|
99
|
+
|
|
100
|
+
You fetch your Firestore data in your app, then pass the dict here:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
firestore_doc = {
|
|
104
|
+
"id": "abc123",
|
|
105
|
+
"createdAt": "2026-02-03T10:00:00Z",
|
|
106
|
+
"title": "User Profile Update",
|
|
107
|
+
"notes": "User says they prefer direct answers.",
|
|
108
|
+
"companyCode": "QX",
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
passport, _ = sg.ingest(
|
|
112
|
+
firestore_doc,
|
|
113
|
+
hint="firestore",
|
|
114
|
+
meta={"source": "firestore:/users/abc123", "user_key": "u_abc123"}
|
|
115
|
+
)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
-----
|
|
119
|
+
|
|
120
|
+
### 4) Firebase Realtime DB ingestion (path + value)
|
|
121
|
+
|
|
122
|
+
RTDB is tree-based, so pass an envelope:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
rtdb_snapshot = {
|
|
126
|
+
"path": "/users/u1/profile",
|
|
127
|
+
"value": {
|
|
128
|
+
"updatedAt": 1738560000000,
|
|
129
|
+
"displayName": "Quantilytix",
|
|
130
|
+
"preferences": {"tone": "direct"}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
passport, _ = sg.ingest(rtdb_snapshot, hint="rtdb", meta={"user_key": "u1"})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
-----
|
|
138
|
+
|
|
139
|
+
### 5) Supabase ingestion (table + row)
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
supabase_row = {
|
|
143
|
+
"table": "events",
|
|
144
|
+
"row": {
|
|
145
|
+
"id": 77,
|
|
146
|
+
"created_at": "2026-02-03T11:22:00Z",
|
|
147
|
+
"event": "user_preference_update",
|
|
148
|
+
"notes": "User wants strategy alignment before code."
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
passport, _ = sg.ingest(supabase_row, hint="supabase", meta={"user_key": "u1"})
|
|
153
|
+
```
|
|
154
|
+
# SozoGraph Test Fixtures
|
|
155
|
+
|
|
156
|
+
These fixtures are **intentionally small and human-readable**.
|
|
157
|
+
|
|
158
|
+
They are designed to test:
|
|
159
|
+
- transcript ingestion
|
|
160
|
+
- Firestore document ingestion
|
|
161
|
+
- Firebase Realtime Database snapshots
|
|
162
|
+
- Supabase row ingestion
|
|
163
|
+
|
|
164
|
+
They are NOT meant to simulate production-scale data.
|
|
165
|
+
If a fixture grows beyond what a human would comfortably read,
|
|
166
|
+
it is probably violating SozoGraph v1 philosophy.
|
|
167
|
+
-----
|
|
168
|
+
|
|
169
|
+
## Export a compact agent “briefing” (context injection)
|
|
170
|
+
|
|
171
|
+
You can inject this into any agent prompt:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
briefing = sg.export_context(passport, budget_chars=2500)
|
|
175
|
+
print(briefing)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Example output format:**
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
SOZOGRAPH PASSPORT v1
|
|
182
|
+
User: u1
|
|
183
|
+
Updated: 2026-02-03T12:34:56+00:00
|
|
184
|
+
|
|
185
|
+
Facts (current beliefs):
|
|
186
|
+
- role: software development
|
|
187
|
+
- current_project: sozograph v1
|
|
188
|
+
...
|
|
189
|
+
|
|
190
|
+
Preferences:
|
|
191
|
+
- tone: direct
|
|
192
|
+
...
|
|
193
|
+
|
|
194
|
+
Open loops:
|
|
195
|
+
- finalize v1 repo + publish pip package
|
|
196
|
+
...
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
-----
|
|
200
|
+
|
|
201
|
+
## How SozoGraph v1 works
|
|
202
|
+
|
|
203
|
+
### Ingestion pipeline (v1)
|
|
204
|
+
|
|
205
|
+
1. Coerce input into canonical `Interaction` objects (deterministic)
|
|
206
|
+
1. If the derived text is weak/noisy, call Gemini fallback summarizer (optional)
|
|
207
|
+
1. Use Gemini extractor (strict JSON) to propose memory updates
|
|
208
|
+
1. Use deterministic resolver to merge:
|
|
209
|
+
|
|
210
|
+
- temporal priority (latest wins)
|
|
211
|
+
- explicit contradictions record changes
|
|
212
|
+
- de-dupe entities + aliases
|
|
213
|
+
- keep open loops short and recent
|
|
214
|
+
|
|
215
|
+
### What SozoGraph v1 is NOT
|
|
216
|
+
|
|
217
|
+
- Not a graph database
|
|
218
|
+
- Not RAG
|
|
219
|
+
- Not embeddings
|
|
220
|
+
- Not a long transcript store
|
|
221
|
+
- Not a tool that fetches from DB (objects-only by design)
|
|
222
|
+
|
|
223
|
+
-----
|
|
224
|
+
|
|
225
|
+
## Roadmap (upcoming features)
|
|
226
|
+
|
|
227
|
+
### v1.x (near-term)
|
|
228
|
+
|
|
229
|
+
- Better input detection for common “transcript list” shapes (e.g. `{transcript, createdAt}`)
|
|
230
|
+
- CLI:
|
|
231
|
+
- `sozograph ingest transcript.txt --out passport.json`
|
|
232
|
+
- `sozograph render passport.json --budget 3000`
|
|
233
|
+
- Stronger JSON recovery if a model response is slightly malformed
|
|
234
|
+
- More deterministic evidence linking (source-id mapping improvements)
|
|
235
|
+
|
|
236
|
+
### v1.5 (planned, optional)
|
|
237
|
+
|
|
238
|
+
- Graph engine support (Neo4j Aura / Memgraph) via Bolt
|
|
239
|
+
- Cypher-style relational queries over memory
|
|
240
|
+
- Temporal deprecation on edges
|
|
241
|
+
- Export “active truth subgraph” to context
|
|
242
|
+
|
|
243
|
+
### v2 (optional)
|
|
244
|
+
|
|
245
|
+
- Foundational model adapters (non-Gemini backends)
|
|
246
|
+
- MCP tool server integration
|
|
247
|
+
- Hybrid patterns (graph + vector) only where needed
|
|
248
|
+
|
|
249
|
+
-----
|
|
250
|
+
|
|
251
|
+
## Contributing
|
|
252
|
+
|
|
253
|
+
We want contributions, but keep v1 disciplined.
|
|
254
|
+
|
|
255
|
+
### Good contributions
|
|
256
|
+
|
|
257
|
+
- Adapters for additional object shapes (still objects-only)
|
|
258
|
+
- Resolver improvements (deterministic)
|
|
259
|
+
- Tests for merge/contradiction edge-cases
|
|
260
|
+
- Prompt tuning for more stable key extraction
|
|
261
|
+
|
|
262
|
+
### What won’t be accepted in v1
|
|
263
|
+
|
|
264
|
+
- Adding DB client dependencies (firebase-admin, supabase clients, etc.)
|
|
265
|
+
- Building RAG/embeddings into core
|
|
266
|
+
- Turning v1 into a graph project
|
|
267
|
+
|
|
268
|
+
### How to contribute
|
|
269
|
+
|
|
270
|
+
1. Fork the repo
|
|
271
|
+
1. Create a branch: `feat/<short-name>`
|
|
272
|
+
1. Add tests where relevant
|
|
273
|
+
1. Open a PR with a short explanation and sample input/output
|
|
274
|
+
|
|
275
|
+
-----
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
MIT — Sozo Analytics Lab
|
|
280
|
+
|