feat(profile): extract preferences from sessions - #11
Conversation
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e3cc9c326e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .map((message) => getText(message.parts)), | ||
| ); | ||
| for (const [index, preference] of preferences.entries()) { | ||
| await graphitiClient.addMemory(preference.content, tags.user, { |
There was a problem hiding this comment.
Deduplicate preferences before writing them on idle
With the default autoSaveTurns and autoSavePreferences settings, message.updated already stores an explicit preference through saveFinishedTurnMemories and its remote duplicate check; the following session.idle then writes the same content again through this unconditional addMemory. Every later idle also replays the entire preference list before the digest refresher can decide that the digest is unchanged, creating redundant profile episodes and potentially distorting Graphiti's temporal profile. Route these writes through the existing distinct-memory persistence path or track which session preferences were already saved.
Useful? React with 👍 / 👎.
| const preferences = extractSessionProfileMemories( | ||
| messages | ||
| .filter((message) => message.info?.role === "user") | ||
| .map((message) => getText(message.parts)), |
There was a problem hiding this comment.
Sanitize session text before extracting profile memories
When a non-synthetic user part contains a durable preference followed in the same sentence by a <system-reminder> block, passing raw getText(...) output here causes extractExplicitProfileMemory to include and persist that internal block in the cross-project user profile. The existing turn and digest persistence paths deliberately call sanitizeTextForStorage to remove these blocks; apply that sanitation before session profile extraction as well.
Useful? React with 👍 / 👎.
Extract direct, explicit preferences across an entire session at digest time while retaining conservative profile safety gates. Release v0.6.3.