-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdemo_correction.py
More file actions
211 lines (174 loc) · 7.46 KB
/
Copy pathdemo_correction.py
File metadata and controls
211 lines (174 loc) · 7.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#!/usr/bin/env python3
"""Memory Correction Demo - Version History and Audit.
Pre-read References:
- Section 4.1: "APIs for read/search/write/update/delete with versioning"
- Section 4.4: "timely correction pathways, provenance metadata"
This demo shows:
1. Initial memory state (model_inferred)
2. Learner correction (changes to user_declared)
3. Version history showing the change
4. Audit trail for corrections
"""
import os
import sys
# Ensure we can import from the package
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from dotenv import load_dotenv
load_dotenv()
from memory.schema import MemoryItem, MemoryCategory
from memory.service import PortableMemoryService
from memory.scopes import create_math_tutor_scope
from memory.grants import create_grant
def print_header(title: str):
"""Print a formatted section header."""
print("\n" + "=" * 60)
print(f" {title}")
print("=" * 60)
def print_version_history(versions: list):
"""Print version history in a readable format."""
print("\n Version History:")
if not versions:
print(" (no history)")
return
for v in versions:
change_marker = {"created": "+", "updated": "~", "corrected": "!!", "restored": "<-"}
marker = change_marker.get(v.change_type, "?")
print(f" v{v.version_number} [{marker}] {v.content[:40]}...")
print(f" by: {v.created_by}, reason: {v.change_reason or 'initial'}")
def run_correction_demo():
"""Run the memory correction demo."""
print_header("MEMORY CORRECTION DEMO - Version History")
print("""
This demo shows the Pre-read 4.1/4.4 correction flow:
- Model infers a memory about the learner
- Learner corrects it (changes source_type to user_declared)
- Full version history is preserved
- Audit trail tracks the correction
""")
# Create service
service = PortableMemoryService()
learner_id = "alice"
# Create grant
math_scope = create_math_tutor_scope()
math_grant = create_grant(
learner_id=learner_id,
agent_id="math_tutor",
scope=math_scope,
)
service.grant_store.store(math_grant)
# ==========================================================================
# PHASE 1: Initial State
# ==========================================================================
print_header("PHASE 1: Initial State")
print("Math Tutor infers that Alice struggles with word problems...")
# Add initial memory (model_inferred)
initial_memory = MemoryItem(
category=MemoryCategory.MASTERY,
content="Struggles with word problems",
source="conversation",
confidence=0.48,
source_type="model_inferred",
subject_area="math",
)
memory_id = service.add_memory(initial_memory, learner_id, math_grant)
# Show initial state
memory = service.get_memory(memory_id, math_grant)
print(f"\n Memory: {memory.content}")
print(f" Source type: {memory.source_type}")
print(f" Confidence: {memory.confidence:.2f}")
print(f" Version: {memory.version}")
# Show version history
versions = service.get_version_history(memory_id)
print_version_history(versions)
# ==========================================================================
# PHASE 2: Learner Correction
# ==========================================================================
print_header("PHASE 2: Learner Correction")
print('Alice: "Actually, I\'ve been practicing and I\'m better at word problems now."')
# Correct the memory
corrected = service.correct_memory(
memory_id=memory_id,
new_content="Improving on word problems after recent practice",
reason="Learner self-reported improvement after practice",
grant=math_grant,
new_source_type="user_declared",
new_confidence=0.65,
)
print(f"\n Memory: {corrected.content}")
print(f" Source type: {corrected.source_type} (changed from model_inferred)")
print(f" Confidence: {corrected.confidence:.2f} (was 0.48)")
print(f" Version: {corrected.version}")
print(f" Correction reason: {corrected.correction_reason}")
# ==========================================================================
# PHASE 3: Version History
# ==========================================================================
print_header("PHASE 3: Version History")
print("The full history is preserved for audit and potential restore...")
versions = service.get_version_history(memory_id)
print_version_history(versions)
print("\n Key points:")
print(" - Original inference preserved (v1)")
print(" - Correction creates new version (v2)")
print(" - Source type changed to user_declared")
print(" - Reason recorded for audit")
# ==========================================================================
# PHASE 4: Further Update
# ==========================================================================
print_header("PHASE 4: Further Update")
print("Later, Alice takes an assessment and scores well...")
# Update with assessment result
updated = service.update_memory(
memory_id=memory_id,
updates={
"content": "Competent at word problems (assessment: 0.78)",
"confidence": 0.78,
},
reason="Assessment result confirms improvement",
grant=math_grant,
)
print(f"\n Memory: {updated.content}")
print(f" Confidence: {updated.confidence:.2f}")
print(f" Version: {updated.version}")
# Final version history
versions = service.get_version_history(memory_id)
print_version_history(versions)
# ==========================================================================
# PHASE 5: Audit Trail
# ==========================================================================
print_header("PHASE 5: Audit Trail")
print("All operations are logged with full details...")
entries = service.audit_log.query(learner_id)
print(f"\n Total entries: {len(entries)}")
# Filter to show just this memory's corrections
corrections = [e for e in entries if e.operation in ("correct", "update")]
print(f" Corrections/updates: {len(corrections)}")
for entry in corrections:
ts = entry.timestamp.strftime("%H:%M:%S")
print(f"\n {ts} | {entry.operation}")
if entry.previous_values:
old_content = entry.previous_values.get("content", "?")[:30]
print(f" Before: {old_content}...")
if entry.new_values:
new_content = entry.new_values.get("content", "?")
if new_content:
print(f" After: {new_content[:30]}...")
if entry.reason:
print(f" Reason: {entry.reason[:50]}...")
# ==========================================================================
# Summary
# ==========================================================================
print_header("DEMO COMPLETE")
print("""
Key points demonstrated:
1. Initial model inference with lower confidence
2. Learner correction changes source_type to user_declared
3. Full version history preserved (v1 -> v2 -> v3)
4. Assessment updates further refine the memory
5. Audit trail captures all changes with reasons
Pre-read 4.4: "timely correction pathways, provenance metadata"
- Corrections are first-class operations
- Source type distinction prevents identity hardening
- Version history enables audit and restore
""")
if __name__ == "__main__":
run_correction_demo()