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.
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-user-memory
3
- Version: 2026.36.0.dev0
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.dev0,<2026.36.0rc0
11
- Requires-Dist: unique-toolkit>=2026.36.0.dev0,<2026.36.0rc0
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
- ## Recent Topics
80
+ ## Follow-ups
81
81
  _(empty)_
82
82
 
83
- ## Follow-ups
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
- ## Recent Topics
66
+ ## Follow-ups
67
67
  _(empty)_
68
68
 
69
- ## Follow-ups
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.dev0"
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.dev0,<2026.36.0rc0",
15
- "unique-toolkit>=2026.36.0.dev0,<2026.36.0rc0",
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