feat(alaya): lay the groundwork for standalone short-term memory planner/query#1216
feat(alaya): lay the groundwork for standalone short-term memory planner/query#1216freezinlove wants to merge 4 commits intomoeru-ai:mainfrom
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request lays the foundational architecture for the Alaya memory system, introducing a new, decoupled package that orchestrates short-term memory planning and querying. It integrates LLM-first extraction and embedding generation for conversation turns, enabling intelligent recall, and provides comprehensive developer tools for observability and configuration. Highlights
Changelog
Ignored Files
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces the Alaya memory system as a standalone package, featuring a well-thought-out architecture and a comprehensive UI for developer inspection and settings management. While the foundation is solid, the integration of LLM-generated memory into the prompt flow introduces standard LLM safety risks, such as indirect prompt injection. Additionally, the current local storage implementation has a potential performance bottleneck when listing keys, and a few medium-severity issues related to correctness, maintainability, and efficiency have been identified that should be addressed.
| if ( | ||
| existingMemory.contentHash === record.contentHash | ||
| && existingMemory.summary === record.summary | ||
| ) { |
There was a problem hiding this comment.
The contentHash is generated from the lowercased summary in run-planner-batch.ts, making it case-insensitive. However, this check includes a case-sensitive comparison of the summary field. This means memories differing only in case will not be skipped, which may be unintended. If the goal is case-insensitive deduplication, relying solely on contentHash would be clearer and more consistent. If case sensitivity is desired, the hash should be generated from the original summary.
There was a problem hiding this comment.
Keeping this as-is for now.
contentHash is intentionally case-insensitive as a coarse content identity signal, while the direct summary comparison is retained as a stricter equality check before skipping writes. In the current flow this branch is already gated by the idempotency key path, so I’d prefer not to broaden dedup semantics in this PR without revisiting the full merge/update behavior.
| const idempotencyKeys = await listKeysByPrefix(storage, `${idempotencyKeyPrefix(workspaceId)}/`) | ||
| for (const key of idempotencyKeys) { | ||
| const mappedMemoryId = await storage.getItemRaw<string>(key) | ||
| if (mappedMemoryId === memoryId) { | ||
| await storage.removeItem(key) | ||
| } | ||
| } |
There was a problem hiding this comment.
This loop appears to be redundant and inefficient. The idempotency key is already removed on line 236 using targetRecord.idempotencyKey. This second loop iterates over all idempotency keys for the workspace, which could be slow if there are many memories. If targetRecord.idempotencyKey is reliable and unique per memory, this loop is unnecessary and can be removed to improve performance.
There was a problem hiding this comment.
Keeping this fallback cleanup for now.
The direct idempotency mapping removal is still the primary path. This extra scan is a defensive cleanup step for stale or duplicated mappings in the current IndexedDB-backed MVP, so it is intentionally conservative. I agree it is not ideal at larger scale, but I’d prefer to optimize this together with a broader storage/index cleanup pass rather than changing the deletion semantics in this PR.
⏳ Approval required for deploying to Cloudflare Workers (Preview) for stage-web.
Hey, @nekomeowww, @sumimakito, @luoling8192, @LemonNekoGH, kindly take some time to review and approve this deployment when you are available. Thank you! 🙏 |
|
I think the latest workflow runs are currently waiting for maintainer approval on the fork PR. When convenient, could a maintainer please approve the pending workflows for the latest head commit? Thank you. |
Refs #879
Context
This PR is a first implementation step toward the Alaya direction discussed for AIRI's memory system.
My intention here was not to model Alaya as a thin
search/save/update/forgetwrapper around vectors, but to start shaping it as a decoupled memory layer with room for:So this PR is intentionally a groundwork PR: it implements a usable first slice, while trying to stay aligned with the broader architecture discussed around Alaya.
What this PR includes
1. Standalone
packages/memory-alayaThis PR adds
packages/memory-alayaas a standalone package instead of baking memory logic directly into the app layer.The package is organized around contracts, ports, engines, and use-cases so that memory orchestration is separated from:
The current shape is closer to a memory orchestration layer than a simple search driver.
2. First short-term memory pipeline
This PR implements the first MVP pipeline for short-term memory (STM):
At this stage, the implemented memory scope is short-term memory only.
3. Planner-first extraction flow
The planner is designed in a planner/filter style rather than a raw storage API.
Current behavior:
This is intended as a first step toward the more job-oriented / filter-oriented memory pipeline discussed in the design thread.
4. Query engine MVP
This PR also adds the first query-side recall path for STM.
Current query engine responsibilities:
This is still a lightweight MVP query engine, but it establishes the boundary for future expansion toward:
5. Local-first storage for current MVP
For the current MVP, STM records and embeddings are stored locally in IndexedDB.
This choice is mainly for the current local/self-hosted usage pattern, but I tried to avoid coupling Alaya to IndexedDB as a permanent assumption.
The goal is that later storage implementations can be added as separate backends/drivers, for example:
So in this PR, IndexedDB is the current runtime storage, not the intended final storage story.
6. Dedicated settings and developer tooling
This PR adds Alaya-related settings and a developer page so the memory pipeline is observable during iteration.
Included UI/devtools work:
This follows the idea of exposing memory experimentation through the developer tooling surface while the design is still evolving.
Current scope of this PR
This PR currently implements:
What is intentionally not implemented yet
This PR does not try to claim the full Alaya vision is complete.
Still not implemented yet:
memory-storage-pgvectorWhy I structured it this way
From the design discussion, my understanding is that Alaya should move toward:
This PR does not solve those bigger problems yet, but it tries to avoid blocking them.
Concretely, I tried to keep:
So this is meant as a practical first slice that is already usable, while still leaving room for the broader Alaya architecture to grow.
Validation
Ran during implementation:
pnpm -F @proj-airi/memory-alaya test pnpm -F @proj-airi/memory-alaya build pnpm -F @proj-airi/stage-ui typecheck pnpm typecheckNotes
A few implementation choices in this PR are MVP-oriented:
I would treat this PR as the first usable foundation for Alaya, not the final memory architecture.