unique-user-memory 2026.36.0.dev0__tar.gz → 2026.36.0.dev2__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.
- {unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/PKG-INFO +7 -5
- {unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/README.md +4 -2
- {unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/pyproject.toml +3 -3
- {unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/unique_user_memory/tests/test_user_memory.py +12 -0
- {unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/unique_user_memory/user_memory_prompts.py +43 -2
- {unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/unique_user_memory/__init__.py +0 -0
- {unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/unique_user_memory/config.py +0 -0
- {unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/unique_user_memory/user_memory.py +0 -0
- {unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/unique_user_memory/user_memory_message_log.py +0 -0
- {unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/unique_user_memory/user_memory_postprocessor.py +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-user-memory
|
|
3
|
-
Version: 2026.36.0.
|
|
3
|
+
Version: 2026.36.0.dev2
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Fabian Schläpfer
|
|
6
6
|
Author-email: Fabian Schläpfer <fabian@unique.ch>
|
|
7
7
|
License: Proprietary
|
|
8
8
|
Requires-Dist: jinja2>=3.1.6
|
|
9
9
|
Requires-Dist: pydantic>=2.8.2
|
|
10
|
-
Requires-Dist: unique-sdk>=2026.36.0.
|
|
11
|
-
Requires-Dist: unique-toolkit>=2026.36.0.
|
|
10
|
+
Requires-Dist: unique-sdk>=2026.36.0.dev1,<2026.36.0rc0
|
|
11
|
+
Requires-Dist: unique-toolkit>=2026.36.0.dev6,<2026.36.0rc0
|
|
12
12
|
Requires-Python: >=3.12, <4
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
|
|
@@ -77,15 +77,17 @@ _(empty)_
|
|
|
77
77
|
## Skills & Expertise
|
|
78
78
|
_(empty)_
|
|
79
79
|
|
|
80
|
-
##
|
|
80
|
+
## Follow-ups
|
|
81
81
|
_(empty)_
|
|
82
82
|
|
|
83
|
-
##
|
|
83
|
+
## Recent Topics
|
|
84
84
|
_(empty)_
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
The consolidation prompt preserves the schema, keeps bullets short, and returns `NOOP` when a turn has no durable user facts.
|
|
88
88
|
|
|
89
|
+
Each fact lives in exactly one section. **Recent Topics** is a dated log reserved for discussion topics whose substance is not already captured as a fact elsewhere in the profile. **Follow-ups** only holds tasks the user explicitly committed to or asked to be reminded about — never the assistant's own offers or open questions — and entries are removed once completed or stale.
|
|
90
|
+
|
|
89
91
|
## Configuration
|
|
90
92
|
|
|
91
93
|
Memory is activated by the orchestrator when `space.allow_user_memory` is true. `UserMemoryConfig` only configures how active memory is consolidated and stored.
|
|
@@ -63,15 +63,17 @@ _(empty)_
|
|
|
63
63
|
## Skills & Expertise
|
|
64
64
|
_(empty)_
|
|
65
65
|
|
|
66
|
-
##
|
|
66
|
+
## Follow-ups
|
|
67
67
|
_(empty)_
|
|
68
68
|
|
|
69
|
-
##
|
|
69
|
+
## Recent Topics
|
|
70
70
|
_(empty)_
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
The consolidation prompt preserves the schema, keeps bullets short, and returns `NOOP` when a turn has no durable user facts.
|
|
74
74
|
|
|
75
|
+
Each fact lives in exactly one section. **Recent Topics** is a dated log reserved for discussion topics whose substance is not already captured as a fact elsewhere in the profile. **Follow-ups** only holds tasks the user explicitly committed to or asked to be reminded about — never the assistant's own offers or open questions — and entries are removed once completed or stale.
|
|
76
|
+
|
|
75
77
|
## Configuration
|
|
76
78
|
|
|
77
79
|
Memory is activated by the orchestrator when `space.allow_user_memory` is true. `UserMemoryConfig` only configures how active memory is consolidated and stored.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "unique_user_memory"
|
|
3
|
-
version = "2026.36.0.
|
|
3
|
+
version = "2026.36.0.dev2"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Fabian Schläpfer", email = "fabian@unique.ch" },
|
|
@@ -11,8 +11,8 @@ requires-python = ">=3.12,<4"
|
|
|
11
11
|
dependencies = [
|
|
12
12
|
"jinja2>=3.1.6",
|
|
13
13
|
"pydantic>=2.8.2",
|
|
14
|
-
"unique-sdk>=2026.36.0.
|
|
15
|
-
"unique-toolkit>=2026.36.0.
|
|
14
|
+
"unique-sdk>=2026.36.0.dev1,<2026.36.0rc0",
|
|
15
|
+
"unique-toolkit>=2026.36.0.dev6,<2026.36.0rc0",
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
[dependency-groups]
|
|
@@ -97,6 +97,18 @@ def test_memory_profile_keeps_follow_up_tasks_but_excludes_open_questions() -> N
|
|
|
97
97
|
assert "## Follow-ups" in profile
|
|
98
98
|
assert "concrete tasks the user intends to complete" in consolidation_prompt
|
|
99
99
|
assert "Concrete future tasks the user intends to complete" in gate_prompt
|
|
100
|
+
assert "NEVER record the assistant's offers" in consolidation_prompt
|
|
101
|
+
assert 'Never write "awaiting user input"' in consolidation_prompt
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def test_recent_topics_is_last_section_and_deduplicated() -> None:
|
|
105
|
+
profile = empty_profile("user_1")
|
|
106
|
+
consolidation_prompt = consolidation_system_prompt(2000)
|
|
107
|
+
|
|
108
|
+
assert profile.index("## Follow-ups") < profile.index("## Recent Topics")
|
|
109
|
+
assert profile.rstrip().endswith("## Recent Topics\n_(empty)_")
|
|
110
|
+
assert "one home per fact" in consolidation_prompt
|
|
111
|
+
assert "do NOT also log that same information" in consolidation_prompt
|
|
100
112
|
|
|
101
113
|
|
|
102
114
|
def test_profile_body_strips_frontmatter() -> None:
|
|
@@ -7,8 +7,8 @@ SECTION_HEADINGS: tuple[str, ...] = (
|
|
|
7
7
|
"Communication Preferences",
|
|
8
8
|
"Work Context",
|
|
9
9
|
"Skills & Expertise",
|
|
10
|
-
"Recent Topics",
|
|
11
10
|
"Follow-ups",
|
|
11
|
+
"Recent Topics",
|
|
12
12
|
)
|
|
13
13
|
|
|
14
14
|
_EMPTY_PROFILE_TEMPLATE = """\
|
|
@@ -68,6 +68,37 @@ when a section is empty (use the literal string `_(empty)_` as a placeholder):
|
|
|
68
68
|
|
|
69
69
|
{{ section_list }}
|
|
70
70
|
|
|
71
|
+
# Section purposes - one home per fact
|
|
72
|
+
|
|
73
|
+
Every piece of information lives in EXACTLY ONE section. Never record
|
|
74
|
+
the same fact, in any wording, in two sections:
|
|
75
|
+
|
|
76
|
+
- Identity - stable personal attributes: name, location, role, employer,
|
|
77
|
+
team, timezone, language.
|
|
78
|
+
- Communication Preferences - how the user wants responses shaped:
|
|
79
|
+
style, formatting, depth, tone, language, expertise level.
|
|
80
|
+
- Work Context - current focus areas, active projects, durable goals and
|
|
81
|
+
deadlines stated by the user.
|
|
82
|
+
- Skills & Expertise - what the user knows and can do.
|
|
83
|
+
- Follow-ups - concrete tasks the USER explicitly said they will do, or
|
|
84
|
+
explicitly asked to be reminded about. Nothing else belongs here.
|
|
85
|
+
- Recent Topics - a short, dated log of what was discussed. ONLY for
|
|
86
|
+
topics whose substance is NOT already captured as a fact in another
|
|
87
|
+
section. When you ADD or UPDATE a fact in another section for this
|
|
88
|
+
turn, do NOT also log that same information as a Recent Topics entry;
|
|
89
|
+
a Recent Topics entry is only justified when the turn discussed
|
|
90
|
+
something worth remembering that fits no other section.
|
|
91
|
+
|
|
92
|
+
# Follow-ups - user-stated tasks only
|
|
93
|
+
|
|
94
|
+
- Record ONLY tasks the user explicitly committed to or explicitly asked
|
|
95
|
+
to be reminded about.
|
|
96
|
+
- NEVER record the assistant's offers, suggestions, or open questions
|
|
97
|
+
(e.g. "user was offered X", "user was asked whether to do Y"). The
|
|
98
|
+
user answers those within the ongoing conversation, so they carry no
|
|
99
|
+
value in long-term memory. Never write "awaiting user input".
|
|
100
|
+
- DELETE a follow-up as soon as it is completed, declined, or stale.
|
|
101
|
+
|
|
71
102
|
# Operations
|
|
72
103
|
|
|
73
104
|
For each candidate fact in `<new_turn>`, decide one of:
|
|
@@ -109,6 +140,11 @@ similar (same meaning, different wording) into a single clear bullet.
|
|
|
109
140
|
A section must never accumulate redundant or near-duplicate statements.
|
|
110
141
|
Consolidate on every turn, not only when approaching the word budget.
|
|
111
142
|
|
|
143
|
+
Also deduplicate ACROSS sections: delete any Recent Topics entry whose
|
|
144
|
+
substance is already captured as a fact in another section, and any
|
|
145
|
+
Follow-ups entry that records an assistant offer or question rather
|
|
146
|
+
than a user-stated task.
|
|
147
|
+
|
|
112
148
|
# What to extract
|
|
113
149
|
|
|
114
150
|
ADD/UPDATE for facts that are:
|
|
@@ -120,7 +156,8 @@ ADD/UPDATE for facts that are:
|
|
|
120
156
|
- Contextual but durable - current focus areas, active projects,
|
|
121
157
|
multi-week goals, deadlines mentioned by the user.
|
|
122
158
|
- Follow-ups - concrete tasks the user intends to complete in the future,
|
|
123
|
-
or tasks they explicitly ask to be reminded about
|
|
159
|
+
or tasks they explicitly ask to be reminded about - never the
|
|
160
|
+
assistant's own offers or questions.
|
|
124
161
|
|
|
125
162
|
NEVER extract:
|
|
126
163
|
|
|
@@ -192,6 +229,10 @@ fact about the user. This is lossy compression, not deletion of meaning.
|
|
|
192
229
|
2. Delete outdated, stale, resolved, or superseded entries: old
|
|
193
230
|
"Recent Topics", completed or cancelled "Follow-ups", and facts a later
|
|
194
231
|
bullet already contradicts or refines.
|
|
232
|
+
- Also delete "Recent Topics" entries whose substance is already
|
|
233
|
+
captured as a fact in another section, and "Follow-ups" entries that
|
|
234
|
+
record an assistant offer or question ("awaiting user input") rather
|
|
235
|
+
than a task the user explicitly stated.
|
|
195
236
|
3. Tighten verbose, flowery, or repetitive prose into short factual
|
|
196
237
|
bullets. Remove hedging and filler.
|
|
197
238
|
4. Fold low-signal "Work Context" and "Skills & Expertise" bullets into
|
|
File without changes
|
{unique_user_memory-2026.36.0.dev0 → unique_user_memory-2026.36.0.dev2}/unique_user_memory/config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|