Files
OmniRoute/docs/i18n/am/docs/frameworks/MEMORY.md
Diego Rodrigues de Sa e Souza 8feea123bb feat(docs): mirror every docs/ page in all 65 locales (#14106)
* feat(docs): mirror every docs/ page in all 65 locales

Extends the documentation mirrors from the 22-page core set (#13940) to
every Markdown page under docs/: 152 sources x 65 locales = 9,880 mirrors
(6,208 new), language bars rewritten for the full locale list, state
adopted so the blocking drift gate now covers all 152 pages.

run-translation.mjs: an oversized block made only of table rows or list
items (PROVIDER_REFERENCE.md 244-row table, FREE_TIERS.md 71-item list) is
cut at item boundaries and rejoined without a blank line — the single
16-40 KB request outlived the backend socket for verbose scripts. 48
older mirrors whose tables had lost rows were retranslated with --force.

* docs(i18n): refresh mirrors for the sources the base changed since the branch cut

Section-level retranslation of the 29 docs (and README.md) whose source
or mirrors moved on release/v3.8.51 during the run, then state adoption;
the drift gate is green again on the merged tree.
2026-09-18 13:16:46 -03:00

85 KiB
Raw Blame History

Memory System (አማርኛ)

🌐 Languages: 🇺🇸 English · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW


የእውነት ምንጭ፦ src/lib/memory/ እና src/app/api/memory/ ለመጨረሻ ጊዜ የዘመነው፦ 2026-06-28 — v3.8.40 (በነባሪ የተሰናከለ + የ int8 quantization ማሟያ)

OmniRoute በAPI ቁልፍ (እና እንደ አማራጭ በክፍለ-ጊዜ መታወቂያ) የሚለይ ቋሚ የውይይት ማህደረ ትውስታ ያቀርባል። ትውስታዎች ቀላል የregex ስርዓተ-ጥለት ማዛመድን በመጠቀም ከLLM ምላሾች በራስ-ሰር ይወጣሉ፣ ከዚያም የመጀመሪያ የስርዓት መልዕክት ሆነው ወደ ቀጣይ ጥያቄዎች ይካተታሉ (ወይም የስርዓት ሚናን ለማይቀበሉ አቅራቢዎች እንደ መጀመሪያው የተጠቃሚ መልዕክት ይካተታሉ)።

ማህደረ ትውስታ በነባሪ ተሰናክሏል (v3.8.30+)። DEFAULT_MEMORY_SETTINGS.enabled አሁን false ነው (src/lib/memory/settings.ts)። ማህደረ ትውስታን ማንቃት እስከ maxTokens (~2k) የተመለሰ ዐውድ በእያንዳንዱ የውይይት ጥያቄ ውስጥ ያካትታል፣ ለዚህም ክፍያ ይከፈላል — ይህ ለአዲስ ጭነቶች እና የራሳቸውን ዐውድ ለሚያስተዳድሩ ደንበኞች ያልተጠበቀ ወጪ ነው። በSettings → Memory ስር በግልጽ ያንቁት (MemorySkillsTab ማህደረ ትውስታ ሲነቃ የቶከን ወጪ ማስጠንቀቂያ ጥሪ ያሳያል)። አንድ ደንበኛ የx-omniroute-no-memory የጥያቄ ራስጌን (true/1/yes) በመጠቀም አንድን ጥያቄ ከዚህ ማስወጣት ይችላል — በAPI_REFERENCE.md ውስጥ ያለውን የጥያቄ-ራስጌ ሰንጠረዥ ይመልከቱ። ማህደረ ትውስታ የሌለው ጥያቄ memoryOwnerId = null ያዘጋጃል፣ ይህም ለዚያ ጥያቄ ሁለቱንም የማህደረ ትውስታ እና የክህሎት ማካተትን ያሰናክላል (open-sse/handlers/chatCore/headers.ts::isNoMemoryRequested)።

ማህደረ ትውስታው በእያንዳንዱ API ቁልፍ የተወሰነ እንጂ በተጠቃሚ የተወሰነ አይደለም — በተመሳሳይ API ቁልፍ የተረጋገጠ እያንዳንዱ ጥያቄ ተመሳሳይ የማህደረ ትውስታ ስብስብን ይጋራል፣ እንደ አማራጭም በsessionId የበለጠ ሊወሰን ይችላል።

አርክቴክቸር

ደንበኛ → /v1/chat/completions (apiKeyInfo በቅድሚያ ተፈቷል)
  → handleChatCore() [open-sse/handlers/chatCore.ts]
    → resolveMemoryOwnerId(apiKeyInfo)        # መታወቂያውን ያወጣል
    → getMemorySettings()                     # የተሸጎጡ ቅንብሮች
    → shouldInjectMemory(body, {enabled})     # መቆጣጠሪያ
    → retrieveMemories(apiKeyId, config)      # SQL + FTS5 + እንደ አማራጭ vector
    → injectMemory(body, memories, provider)  # የስርዓት ወይም የተጠቃሚ መልዕክት
  → ወደ ውጫዊ አቅራቢ ጥሪ
  → በምላሹ ጊዜ፦ extractFacts(text, apiKeyId, sessionId)  # የማያግድ
    → setImmediate → createMemory(fact) ለእያንዳንዱ ማዛመድ
                   → embed(content) + upsertVector(id, vec)

የማካተት እና የማውጣት ጥሪ ቦታዎች በ open-sse/handlers/chatCore.ts ውስጥ ተገናኝተዋል (retrieveMemoriesinjectMemory እና extractFactsን ይፈልጉ)።

የሞተር አርክቴክቸር (ባለ3-ደረጃ መፍትሔ)

የማህደረ ትውስታ ሞተሩ በሚገኙ መሠረተ ልማቶች እና ቅንብሮች መሠረት በስራ ላይ ባለበት ጊዜ የሰርስሮ ማውጣት መንገዱን ይወስናል። በቅድሚያ ቅደም ተከተል የሚተገበሩ ሦስት ደረጃዎች አሉ፦

  ┌─────────────────────────────────────────────────────────────┐
  │  ደረጃ 0 — ቁልፍ ቃል (FTS5)                                 │
  │  በፍተሻ የሚወሰን ተገኝነት፦ የSQLite ግንባታው               │
  │  ሲደግፈው FTS5 (better-sqlite3 / node:sqlite / bun:sqlite)፤│
  │  FTS5 በሌላቸው ግንባታዎች (ለምሳሌ sql.js/WASM —             │
  │  "no such module: fts5") ላይ አይገኝም። strategy = "exact"   │
  │  ሲሆን ወይም እንደ አማራጭ መመለሻ ይጠቀማል፤ የengine-status  │
  │  keyword ፍተሻውን ያንጸባርቃል።                            │
  └──────────────────────────────────┬──────────────────────────┘
                                     │ strategy = semantic|hybrid?
                                     ▼
  ┌─────────────────────────────────────────────────────────────┐
  │  ደረጃ 1 — የተካተተ Vector (sqlite-vec)                       │
  │  sqlite-vec v0.1.9 በdb.loadExtension() ይጫናል።             │
  │  በFloat32 vectors ላይ KNN brute-force። ንቁ የሚሆነው፦       │
  │   • sqlite-vec loadExtension ሲሳካ                            │
  │   • Float32Array ማምረት የሚችል የembedding ምንጭ              │
  │     (remote | static | transformers) ሲገኝ                   │
  │   • vec_memories ሰንጠረዥ ሲኖር (በመጀመሪያው ready() ይፈጠራል)│
  └──────────────────────────────────┬──────────────────────────┘
                                     │ qdrant.enabled?
                                     ▼
  ┌─────────────────────────────────────────────────────────────┐
  │  ደረጃ 2 — Qdrant (በምርጫ የሚነቃ ውጫዊ vector database)      │
  │  ሲነቃ ለsemantic/hybrid sqlite-vecን ይተካል።                 │
  │  እየሰራ ያለ Qdrant instance + የተዋቀረ host/port ይፈልጋል።  │
  └─────────────────────────────────────────────────────────────┘

ወደ ዝቅተኛ ደረጃ መመለስ ራስ-ሰር እና ግልጽ ነው፦

  • sqlite-vec መጫን ካልቻለ፣ ደረጃ 1 አይገኝም → ወደ ደረጃ 0 ይመለሳል።
  • የembedding ምንጩ ስህተት ከመለሰ፣ ደረጃ 1 ወደ ደረጃ 0 ይመለሳል።
  • Qdrant ጤናማ ካልሆነ፣ ደረጃ 2 ወደ ደረጃ 1 ይመለሳል (ወይም ደረጃ 1ም የማይገኝ ከሆነ ወደ ደረጃ 0 ይመለሳል)።

የEmbedding ምንጮች

የembedding ንብርብሩ (src/lib/memory/embedding/) በMemorySettingsExtended.embeddingSource ላይ ተመስርቶ የትኛውን ምንጭ መጠቀም እንዳለበት ይወስናል፦

ምንጭ መግለጫ ቁልፍ ያስፈልጋል የመጀመሪያ ማስነሻ
remote የተዋቀረ አቅራቢ embedding APIን ይጠቀማል (OpenAI፣ Cohere፣ ወዘተ) አዎ የለም
static potion-base-8M በኩል የሚከናወን አካባቢያዊ የፍለጋ-ሰንጠረዥ embedding (WordPiece + አማካይ pooling) አይ ~200ms
transformers @huggingface/transformers v4፣ all-MiniLM-L6-v2 በኩል የሚከናወን አካባቢያዊ ONNX inference አይ ~3s + ~400MB RAM
auto በruntime ጊዜ መወሰን፦ remote (ቁልፍ ካለ) → static → transformers → null እንደሁኔታው እንደሁኔታው

auto መወሰኛ ቅደም ተከተል፦

  1. listEmbeddingProviders() ውስጥ hasKey === true የሆነውን የመጀመሪያ አቅራቢ ያግኙ → remote
  2. settings.staticEnabled === true ከሆነ → static
  3. settings.transformersEnabled === true ከሆነ → transformers
  4. ካልሆነ → null (ወደ FTS5 ቁልፍ-ቃል ፍለጋ ዝቅ ይላል)።

የembedding cache (src/lib/memory/embedding/cache.ts) በ${source}:${model}:${dim}:${sha256(text)} ቁልፍ የሚሰጠውን በማህደረ ትውስታ ውስጥ ያለ LRU map ይጠቀማል፤ በMEMORY_EMBEDDING_CACHE_MAX ግቤቶች (ነባሪው 1000) የተገደበ ሲሆን TTL ደግሞ MEMORY_EMBEDDING_CACHE_TTL_MS (ነባሪው 5 ደቂቃ) ነው። በአንድ process lifecycle ውስጥ በሁሉም ጠሪዎች መካከል ይጋራል።

ድብልቅ RRF (k=60)

strategy = "hybrid" ሲሆን እና vector store ሲገኝ፣ retrieval የFTS5 እና vector ውጤቶችን ለማዋሃድ Reciprocal Rank Fusionን ይጠቀማል፦

RRF(d) = Σ  1 / (k + rank_i(d))      k = 60 ሲሆን (በMEMORY_RRF_K ሊዋቀር ይችላል)
          i

በተግባር፦

  1. የFTS5 ፍለጋን ያስኪዱ → ደረጃ የተሰጠው ዝርዝር R_fts (ቦታ 1..N)።
  2. የKNN vector ፍለጋን ያስኪዱ → ደረጃ የተሰጠው ዝርዝር R_vec (ቦታ 1..M)።
  3. ለእያንዳንዱ ልዩ memoryId
    rrf_score = 1/(60 + fts_rank) + 1/(60 + vec_rank) (በዝርዝሩ ውስጥ ከሌለ 0)።
  4. rrf_score DESC ደርድሩ፣ የtoken budget ቅኝቱን ይተግብሩ።

RRF በልዩ ልዩ retrieval systems መካከል የውጤት መደበኛነት ሳያስፈልገው ውጤታማ እንደሆነ በሰፊው ይታወቃል። ነባሪው k=60 ከመጀመሪያው የCormack et al. ጥናታዊ ጽሑፍ የተወሰደ ሲሆን ለአነስተኛ corpora (<10k ትውስታዎች) ጥሩ ይሰራል።

Backfill (lazy + reindex)

የembedding model ሲቀየር (በembedding_signature በኩል ይገኛል)፣ vector store እንደገና ይገነባል እና ሁሉም ነባር ትውስታዎች በmemories ሰንጠረዥ ውስጥ needs_reindex = 1 ተብለው ምልክት ይደረግባቸዋል።

Lazy backfill፦ በሚቀጥለው retrieval ጊዜ፣ vector ግቤት የሌለው ማንኛውም ትውስታ ፍለጋው ከመከናወኑ በፊት embed ተደርጎ ወደ vec_memories ይገባል። ይህ ማስነሻውን ሳያግድ የbackfill ወጪውን በእውነተኛ ጥያቄዎች ላይ ያከፋፍላል።

ግልጽ reindex፦ በ/dashboard/memory ውስጥ ያለው Engine tab POST /api/memory/reindexን የሚጠራ "አሁን Reindex አድርግ" የሚል አዝራር ያቀርባል። handlerው src/lib/memory/reindex.ts ውስጥ ያለውን runReindexBatch() ይጠራል፤ ይህም በእያንዳንዱ ጥያቄ እስከ limit የሚደርሱ በመጠባበቅ ላይ ያሉ ግቤቶችን ያስኬዳል። ሂደቱ በGET /api/memory/engine-status (vectorStore.needsReindex) በኩል በተደጋጋሚ ሊፈተሽ ይችላል።

memory_vec_meta ሰንጠረዥ (migration 083_memory_vec.sql) የሚከተሉትን ያከማቻል፦

  • active_dim — የአሁኑ vector dimension (null = ገና አልተስተካከለም)።
  • embedding_signature — ለውጦችን ለማግኘት የሚያገለግል ${source}:${model}:${dim}
  • last_reset_at — የመጨረሻው ሙሉ reset timestamp።
  • vec_loaded — sqlite-vec በተሳካ ሁኔታ መጫኑን የሚያሳይ 0/1 flag።

የቅንብሮች ቅጥያ

ዘጠኝ የembedding እና vector መስኮች በMemorySettingsExtended ውስጥ፣ በsrc/shared/schemas/memory.ts ይገኛሉ፤ በsrc/lib/db/settings.ts በኩል ዘላቂ ሆነው ይቀመጣሉ፦

መስክ ዓይነት ነባሪ መግለጫ
embeddingSource "remote" | "static" | "transformers" | "auto" "auto" የትኛውን የembedding ምንጭ መጠቀም እንዳለበት
embeddingProviderModel string | null null አቅራቢ/ሞዴል በprovider/model ቅርጸት
customBaseUrl string | null null ለማህደረ ትውስታ ብቻ የሚያገለግል OpenAI-ተኳኋኝ endpoint መሠረታዊ URL
customModelId string | null null ወደብጁ endpoint የሚላክ የሞዴል ID
transformersEnabled boolean false ለTransformers.js በፈቃደኝነት ማንቃት (MiniLM፣ ~400MB)
staticEnabled boolean false ለአካባቢያዊው ቋሚ potion-base-8M ሞዴል በፈቃደኝነት ማንቃት
rerankEnabled boolean false እንደገና የደረጃ አሰጣጥ ደረጃን ማንቃት (+200-500ms/req ይጨምራል)
rerankProviderModel string | null null የእንደገና ደረጃ አሰጣጥ አቅራቢ/ሞዴል በprovider/model ቅርጸት
vectorStore "sqlite-vec" | "qdrant" | "auto" "auto" የትኛውን የvector backend መጠቀም እንዳለበት

እነዚህ በGET /PUT /api/settings/memory (schema MemorySettingsExtendedSchema) በኩል ተደራሽ ተደርገዋል።

remote ምንጭ፣ Memory አማራጭ የሆኑትን customBaseUrl እና customModelId ቅንብሮችም ይቀበላል። እነዚህ በአንድነት ዓለም አቀፉን የembedding registry ሳይቀይሩ OpenAI-ተኳኋኝ የ/embeddings endpoint እና ሞዴል ይመርጣሉ። endpoint ጥቅም ላይ ከመዋሉ በፊት መደበኛ ቅርጽ ይሰጠዋል፣ እና በአቅራቢው የወጪ URL ፖሊሲ ይፈተሻል፦ HTTP(S) ያስፈልጋል፣ የተካተቱ የመግቢያ ማረጋገጫዎች እና query strings ውድቅ ይደረጋሉ፣ እንዲሁም የcloud-metadata አድራሻዎች እንደታገዱ ይቆያሉ። ባዶ እሴቶች የተመረጠውን የregistry አቅራቢ እንዳለ ያቆዩታል። ወደ dashboard የሚመለሱ ስህተቶች ሚስጥራዊ መረጃ እንዳያካትቱ ይጣራሉ፣ እና የendpoint የመግቢያ ማረጋገጫዎች ፈጽሞ አይመዘገቡም።

TODO (D20):global scope (በሁሉም API keys መካከል ማህደረ ትውስታዎችን መጋራት) በዚህ ልቀት ውስጥ አልተተገበረም። የschema ለውጦችን እና ዓለም አቀፍ የretrieval መንገድን ይፈልጋል። ለብቻው ይከታተሉት።

የማከማቻ ንብርብሮች

ዋና፦ SQLite (memories table)

በmigration 015_create_memories.sql የተፈጠረ፦

ዓምድ ዓይነት ማስታወሻዎች
id TEXT PRIMARY KEY crypto.randomUUID() የሚፈጠር UUID
api_key_id TEXT NOT NULL ባለቤት የሆነው API key
session_id TEXT አማራጭ የውይይት-ተኮር scope
type TEXT NOT NULL factualepisodicproceduralsemantic አንዱ
key TEXT የተረጋጋ upsert key፣ ለምሳሌ preference:i_prefer_python
content TEXT NOT NULL ትክክለኛው የእውነታ ጽሑፍ
metadata TEXT JSON blob (category, extractedAt, source, ...)
created_at / updated_at TEXT ISO 8601 strings
expires_at TEXT አማራጭ የማብቂያ ጊዜ፤ NULL ቋሚ ማለት ነው
memory_id INTEGER UNIQUE UUIDs ↔ FTS5 rowids ለማገናኘት በ023_fix_memory_fts_uuid.sql የታከለ

Indexes፦ api_key_idsession_idtypeexpires_at፣ እንዲሁም ልዩ የmemory_id index።

የUpsert ባህሪcreateMemory() ተመሳሳይ (api_key_id, key) ያለውን ነባር row ይፈልጋል፣ ሲያገኘውም በቦታው ላይ ያዘምነዋል (metadataን በshallow spread በማዋሃድ)። ይህ ተደጋጋሚ የምርጫ መግለጫዎች ሲኖሩ table ያለገደብ እንዳያድግ ያደርጋል።

የሙሉ ጽሑፍ ፍለጋ (memory_fts virtual table)

022_add_memory_fts5.sqlcontent እና key ላይ FTS5 virtual table ይፈጥራል። 023_fix_memory_fts_uuid.sql የUUID primary key ከFTS5 integer rowid ጋር የማይገናኝበትን በተግባር የታየ ስህተት ያስተካክላል — migration የmemory_id ዓምድን ይጨምራል፣ የFTS tableን እንደገና ይፈጥራል፣ እና INSERT፣ DELETE እና UPDATE ሲደረጉ FTSን የተመሳሰለ እንዲያቆዩ የሚያደርጉ triggers (memory_fts_ai, memory_fts_ad, memory_fts_au) ያገናኛል።

retrieval.ts ውስጥ ለsemantic እና hybrid strategies ጥቅም ላይ ይውላል (ከታች ይመልከቱ)። የretrieval code በhasTable("memory_fts") ማረጋገጫ ያደርጋል፣ እና የFTS table ከሌለ ወይም የFTS query ስህተት ካስነሳ ወደ ቅደም ተከተላዊ የጊዜ አደራደር ይመለሳል።

አማራጭ፦ Qdrant (vector store tier 2)

src/lib/memory/qdrant.ts እንደ tier 2 vector store አማራጭ የQdrant ውህደትን ይተገብራል። Retrieval ወደ Qdrant የሚመራው የengine selector memoryVectorStore === "qdrant" ሲሆን ብቻ ነው — ነባሪው "auto" (እና "sqlite-vec") Qdrantን ፈጽሞ አይመርጥም። የEngine-tab toggle ሁለቱንም qdrantEnabled እና memoryVectorStore በአንድነት ያቀናብራል፦ ማንቃት Qdrantን ዋና store ያደርገዋል፣ ማሰናከል ደግሞ ወደ "auto" ይመልሰዋል (#5597 — ከዚያ ማስተካከያ በፊት ምንም ነገር የengine selectorን ስለማይጽፍ ማንቃቱ ውጤት አልነበረውም)። Qdrant የማይደረስ ከሆነ ወይም ምንም ውጤት ካልመለሰ፣ retrieval ወደ sqlite-vec → FTS5 ይመለሳል።

  • upsertSemanticMemoryPoint() — በተዋቀረው embedding model key + content-ን embed ያደርጋል፣ collection-ው መኖሩን ያረጋግጣል (በመጀመሪያ አጠቃቀም cosine-distance vectors ይፈጥራል)፣ እና payload {memoryId, apiKeyId, sessionId, key, content, metadata, createdAtUnix, expiresAtUnix} ያለውን point upsert ያደርጋል።
  • searchSemanticMemory(query, topK, scope) — query-ውን embed ያደርጋል፣ በkind = "omniroute_memory" እና እንደ አማራጭ በapiKeyId / sessionId የተጣራውን collection ይፈልጋል። topK-ን በ[1, 20] ውስጥ ይገድባል።
  • deleteSemanticMemoryPoint(id) — አንድ point ይሰርዛል። የSQLite row ከተወገደ በኋላ በdeleteMemory() ይጠራል (D15)።
  • cleanupSemanticMemoryPoints({retentionDays})expiresAtUnix ጊዜው ያለፈ ወይም createdAtUnix ከretention cutoff በላይ ያረጀባቸውን points በጅምላ ይሰርዛል። dashboard-ው ትክክለኛዎቹን ቁጥሮች ማሳየት እንዲችል መጀመሪያ ይቆጥራል።
  • checkQdrantHealth() — latencyን ያካተተ GET /readyz የጤንነት ምርመራ።

የsettings UI የQdrant config፣ የጤንነት ምርመራ፣ የsemantic search ሙከራ እና cleanupን በ/dashboard/memory Engine tab ውስጥ ያቀርባል። በsrc/app/api/settings/qdrant/ ስር ያሉት ተጓዳኝ routes ከv3.8.6 ጀምሮ ሁሉም ተገናኝተዋል፦

Route ዘዴ መግለጫ
/api/settings/qdrant GET / PUT የQdrant settingsን ማንበብ / ማዘመን
/api/settings/qdrant/health GET የLiveness ምርመራ + latency
/api/settings/qdrant/search POST የSemantic search ሙከራ
/api/settings/qdrant/cleanup POST ጊዜያቸው ያለፈ / ያረጁ pointsን ማስወገድ
/api/settings/qdrant/embedding-models GET ያሉትን embedding models መዘርዘር

የባህሪ ማስታወሻዎች (ምን እንደሚጠበቅ)፦

  • Engine selection — በEngine tab ውስጥ Qdrantን ማንቃት ዋናው store ያደርገዋል (memoryVectorStore="qdrant" ያዘጋጃል)፤ ማሰናከል ወደ "auto" ይመልሰዋል (#5597)።
  • No back-fill — Qdrant ከነቃ በኋላ የተፈጠሩ/የተዘመኑ memories ብቻ ወደ እሱ ይጻፋሉ (fire-and-forget dual-write)። ቀድሞ የነበሩ SQLite memories አይዛወሩም፤ "Reindex Now" የsqlite-vec indexን ብቻ ነው እንደገና የሚገነባው፣ Qdrantን አይደለም።
  • Vector dimension በራስ-ሰር ይለያል፤ ይህም በመጀመሪያ አጠቃቀም ከትክክለኛው embedding ይወሰዳል — የሚሞላ dimension field የለም። collection ከተፈጠረ በኋላ embedding modelን መቀየር በራስ-ሰር አይስተናገድም፦ ያለው collection ሳይነካ ይቀራል፣ dimension የማይዛመድባቸው writes/searches ይሳናሉ እና ወደ sqlite-vec fallback ያደርጋሉ። embeddersን ለመቀየር collection-ውን እንደገና ይፍጠሩ (አዲስ ስም ይጠቀሙ ወይም በQdrant ውስጥ ይሰርዙት)።
  • Distance metric — ሁልጊዜ Cosine ነው (collection ሲፈጠር hardcoded ነው፤ ሊዋቀር አይችልም)።
  • Auth — API key ብቻ (እንደ api-key header ይላካል፤ authentication ለማይጠቀም local Docker አማራጭ ነው)። JWT/RBAC ጥቅም ላይ አይውሉም።
  • Config fields — UI-ው hostportcollectionembeddingModelapiKeyን ያቀርባል። vectorSize / hnswEfConstruct በenv/DB ብቻ ይገኛሉ፣ እና vectorSize collectionን ለመፍጠር ጥቅም ላይ አይውልም (dimension-ው ከembedding ይመጣል)።

Vector quantization (int8 — በምርጫ የሚነቃ፣ ለሁለቱም backends)

ሁለቱም vector backends የተከማቹ vectors የmemory footprintን ለመቀነስ (~ከFloat32 4× ያነሰ) በትንሽ የrecall ኪሳራ በምርጫ የሚነቃ int8 quantization ይደግፋሉ። በሁለቱም ላይ default-ው off ነው — በግልጽ ካልነቃ vectors ሙሉ precision ይዘው ይቆያሉ።

Backend Setting ዓይነት Default የሚነበብበት ቦታ
Qdrant qdrantQuantization (DB key) "none" | "int8" | "binary" "none" src/lib/memory/qdrant.ts::normalizeQdrantConfig()
sqlite-vec MEMORY_VEC_QUANTIZATION (env) "none" | "int8" "none" src/lib/memory/vectorStore.ts::requestedVecQuantization()
  • QdrantqdrantQuantization setting key በኩል ለእያንዳንዱ instance ይዋቀራል (በPUT /api/settings/qdrant ላይ እንደ quantization field ይቀርባል)። "int8" ሲሆን፣ buildQuantizationConfig() scalar quantization (always_ram፣ quantile 0.99) ይጠይቃል፣ እና ሙሉ-precision vectors የint8 candidate setን እንዲያጣሩ searches rescore: trueን ያነቃሉ።
  • sqlite-vec quantization በenvironment ብቻ ነው (የDB setting አይደለም)፦ local vectorsን በvec_quantize_int8(?, 'unit') በኩል እንደ int8[dim] column ለማከማቸት MEMORY_VEC_QUANTIZATION=int8ን ያዘጋጁ። የተመረጠው mode በembedding_signature ውስጥ (:int8 suffix) ይካተታል፤ ስለዚህ modesን መቀየር የvec_memories table ሙሉ reindexን ያስነሳል — embedding model ሲቀየር ጥቅም ላይ ከሚውለው lazy-backfill path ጋር ተመሳሳይ ነው።

የማህደረ ትውስታ ዓይነቶች

MemoryType (src/lib/memory/types.ts):

ዓይነት ጥቅም ላይ የሚውለው
factual ምርጫዎች፣ የማይለዋወጡ የተጠቃሚ መረጃዎች፣ የባህሪ ቅጦች
episodic ከተወሰነ ጊዜ ጋር የተያያዙ ውሳኔዎች ("I chose Postgres")
procedural የሥራ ሂደት / እንዴት-እንደሚደረግ ማህደረ ትውስታ (የተያዘ፤ በአሁኑ ጊዜ ራስ-ሰር አውጪ የለም)
semantic ለ vector-store ግቤቶች የተያዘ

MemoryConfig ማምጫ ስልት ከexactsemantic፣ ወይም hybrid አንዱ ሲሆን፣ ወሰኑም ከsessionapiKey፣ ወይም global አንዱ ነው። ከ getMemorySettings() የሚመጣው ነባሪ ወሰን apiKey ነው።

የእውነታ ማውጣት (extraction.ts)

ማውጣቱ በregex ላይ የተመሠረተ እንጂ በLLM ላይ የተመሠረተ አይደለም — በሂደቱ ውስጥ በsetImmediate() ይሠራል፣ ስለዚህ የምላሽ ዥረቱን ፈጽሞ አያግድም፦

  • የምርጫ ቅጦችMemoryType.FACTUAL (ለምሳሌ I prefer …I really like …my favorite is …I hate …)
  • የውሳኔ ቅጦችMemoryType.EPISODIC (ለምሳሌ I'll use …I chose …I went with …I'm going to adopt …)
  • የልማድ ቅጦችMemoryType.FACTUAL (ለምሳሌ I usually …I always …I tend to …)

እያንዳንዱ ተዛማጅ ይጸዳል (trim፣ የነጭ ቦታ ማጣበቅ፣ እስከ 500 ቁምፊዎች መገደብ)፣ በቋሚ factKey(category, content) አማካኝነት በቡድኑ ውስጥ የተደጋገሙት ይወገዳሉ፣ እና በcreateMemory() በኩል ከ {category, extractedAt, source: "llm_response"} ሜታዳታ ጋር ይከማቻሉ። የግቤት ጽሑፉ በ64 KiB (MAX_EXTRACTION_TEXT_LENGTH) ይገደባል — ከዚህ በላይ ሲሆን፣ በቅርብ ጊዜ የተፈጠረው የረዳት ይዘት ሁልጊዜ እንዲካተት የጽሑፉ መጨረሻ ጥቅም ላይ ይውላል።

extractFactsFromText(text) ለሙከራዎች ወደ ውጭ ይላካል፣ እና ሳያከማቻቸው የተዋቀሩትን እውነታዎች ይመልሳል።

ማምጣት (retrieval.ts)

retrieveMemories(apiKeyId, config) ዋናው የመግቢያ ነጥብ ነው። ይህ፦

  1. ውቅሩን በMemoryConfigSchema በኩል መደበኛ ያደርገዋል እና ያረጋግጠዋል።
  2. enabled false ሲሆን ወይም maxTokens <= 0 ሲሆን ወዲያውኑ [] ይመልሳል።
  3. maxTokensን በ[1, 8000] ክልል ውስጥ ይገድባል።
  4. የቆዩ የውሂብ ጎታዎች እንደቀድሞው መሥራታቸውን እንዲቀጥሉ፣ ዘመናዊው memories ሰንጠረዥ መኖሩን (ከቀድሞው memory ሰንጠረዥ ጋር በማነጻጸር) ይለያል።
  5. የማብቂያ ጊዜ ጥበቃ (expires_at IS NULL OR datetime(expires_at) > datetime('now'))፣ አማራጭ የክፍለ-ጊዜ ወሰን፣ እና አማራጭ የretentionDays መቁረጫ ያለውን መሠረታዊ ጥያቄ ይገነባል።
  6. በስልቱ መሠረት ቅርንጫፍ ይመርጣል፦
    • exact (ነባሪ)፦ በጊዜ ቅደም ተከተል ORDER BY created_at DESC LIMIT 100
    • semanticconfig.query ካለ እና memory_fts ካለ፣ memory_fts MATCH ?ን JOIN አድርጎ በFTS ደረጃ ያዛል፤ FTS 0 ረድፎችን ሲመልስ ወደ ጊዜ ቅደም ተከተል ይመለሳል።
    • hybrid፦ የFTS ውጤቶችን (ከፍተኛ ተዛማጅነት ያላቸውን) እና በጊዜ ቅደም ተከተል የተዘጋጀውን ስብስብ ያዋህዳል፣ በid የተደጋገሙትንም ያስወግዳል።
  7. ጥያቄ ሲቀርብ በcontentkey፣ እና metadata JSON ላይ የቁልፍ ቃል ተዛማጅነት ውጤት (getRelevanceScore) ያሰላል። ውጤታቸው ዜሮ የሆኑ ረድፎች ይጣራሉ።
  8. በውጤት ከከፍተኛ ወደ ዝቅተኛ፣ ከዚያም በcreatedAt ከአዲስ ወደ አሮጌ ይደረድራል።
  9. በደረጃ የተደረደረውን ዝርዝር በተከታታይ በማለፍ፣ እየተደመረ የሚሄደው estimateTokens(content) (≈ length / 4) ከበጀቱ በታች እስከቆየ ድረስ ግቤቶችን ይቀበላል። ማንኛውም ተዛማጅ ሲኖር ሁልጊዜ ቢያንስ አንድ ግቤት ይመልሳል።

estimateTokens ወደ ውጭ ይላካል፣ እና በማምጣት፣ በማጠቃለል፣ እና በMCP omniroute_memory_search መሣሪያ ጥቅም ላይ ይውላል።

ማስገባት (injection.ts)

injectMemory(request, memories, provider):

  1. ሁሉንም የማህደረ ትውስታ ይዘቶች ወደ አንድ Memory context: … ሕብረቁምፊ ያጣምራል።
  2. በአቅራቢው ስም መሠረት ስልት ይመርጣል፦
    • የስርዓት መልዕክት (ለOpenAI፣ Anthropic፣ Gemini፣ … ነባሪ) — የተጠቃሚው የስርዓት መጠየቂያዎች አሁንም ቅድሚያ እንዲኖራቸው፣ {role: "system", content: memoryText}ን ከማናቸውም ነባር የስርዓት መልዕክቶች በፊት ያስገባል።
    • የተጠቃሚ መልዕክት (የመጠባበቂያ አማራጭ) — በ PROVIDERS_WITHOUT_SYSTEM_MESSAGE ውስጥ ላሉ አቅራቢዎች፦ o1o1-minio1-previewglmglmtglm-cnzaiqianfan። እነዚህ የስርዓት ሚናውን ውድቅ ያደርጋሉ፤ አለበለዚያ 400 ስህተት ይመልሳሉ (ለGLM/Zhipu issue #1701ን ይመልከቱ)።
  3. ብዛቱን፣ ስልቱን እና ሞዴሉን በmemory.injection.injected ስር ይመዘግባል።

providerSupportsSystemMessage(provider) የራሳቸውን የማዘዋወር ውሳኔዎች ማድረግ ለሚያስፈልጋቸው ጠሪዎች ወደ ውጭ ይላካል። ያልታወቁ አቅራቢዎች ለደህንነት ሲባል በነባሪ true (የስርዓት ሚና የተፈቀደ) ይጠቀማሉ።

ቅንብሮች (settings.ts)

የማህደረ ትውስታ ውቅር በenv vars ውስጥ ሳይሆን በDB ቅንብሮች ሰንጠረዥ ውስጥ ይከማቻልgetMemorySettings()getSettings() ያነባል እና ውጤቱን በሂደቱ ውስጥ በመሸጎጫ ያስቀምጣል፤ ከመጻፍ በኋላ በቅንብሮች PUT መስመር invalidateMemorySettingsCache() ይጠራል።

የቆዩ መስኮች (ሁሉም ስሪቶች)

DB ቁልፍ ዓይነት ነባሪ የUI መቆጣጠሪያ
memoryEnabled boolean false (ከv3.8.30 ጀምሮ በነባሪ ጠፍቷል) ማህደረ ትውስታ ማብራት/ማጥፋት
memoryMaxTokens integer 2000 (ክልል 016000) ለማስገባት የቶከን በጀት
memoryRetentionDays integer 30 (ክልል 1365) የማቆያ ጊዜ መስኮት
memoryStrategy enum "hybrid" (ከrecentsemantichybrid አንዱ) የሰርስሮ ማውጣት ስልት
skillsEnabled boolean false በቁልፍ የሚደረግ የክህሎት ማስገባትን ያበራል/ያጠፋል (SKILLS.mdን ይመልከቱ)

ማስታወሻ፦ የUI ስልት "recent"toMemoryRetrievalConfig() በኩል ወደ ውስጣዊው "exact" የሰርስሮ ማውጣት ስልት ይዛመዳል (በጊዜ ቅደም ተከተል)።

አዲስ መስኮች (v3.8.6፣ plan 21 D9)

ለመስኮች መግለጫዎች ከላይ ያለውን "የቅንብሮች ቅጥያ" ክፍልም ይመልከቱ።

DB ቁልፍ የAPI መስክ ነባሪ
memoryEmbeddingSource embeddingSource "auto"
memoryEmbeddingModel embeddingProviderModel null
memoryTransformersEnabled transformersEnabled false
memoryStaticEnabled staticEnabled false
memoryRerankEnabled rerankEnabled false
memoryRerankModel rerankProviderModel null
memoryVectorStore vectorStore "auto"

ከQdrant ጋር የተያያዙ DB ቁልፎች (qdrantEnabledqdrantHostqdrantPortqdrantApiKeyqdrantCollection ነባሪ "omniroute_memory"qdrantEmbeddingModel ነባሪ "openai/text-embedding-3-small") በ qdrant.ts ውስጥ ባለው normalizeQdrantConfig() ይነበባሉ።

የአካባቢ ተለዋዋጮች (v3.8.6)

ስድስት አማራጭ env vars የኤንጂኑን የአሂድ ጊዜ ባህሪ ያስተካክላሉ (በ.env.example ውስጥ ተመዝግበዋል)፦

ተለዋዋጭ ነባሪ መግለጫ
MEMORY_EMBEDDING_CACHE_TTL_MS 300000 የembedding መሸጎጫ TTL (5 ደቂቃ)
MEMORY_EMBEDDING_CACHE_MAX 1000 በembedding LRU መሸጎጫ ውስጥ ከፍተኛው የግቤቶች ብዛት
MEMORY_TRANSFORMERS_MODEL Xenova/all-MiniLM-L6-v2 ለTransformers.js ሞዴል የHF ማከማቻ
MEMORY_STATIC_MODEL minishlab/potion-base-8M ለስታቲክ potion ሞዴል የHF ማከማቻ
MEMORY_STATIC_CACHE_DIR <DATA_DIR>/embeddings የወረዱ ሞዴሎች የሚከማቹበት
MEMORY_VEC_TOP_K 20 ለvector ፍለጋ ነባሪ top-K
MEMORY_RRF_K 60 ለhybrid ፍለጋ የRRF k ቋሚ
MEMORY_VEC_QUANTIZATION none የአካባቢያዊ sqlite-vec vectorsን በquantized መልክ ለማከማቸት ወደ int8 ያቀናብሩ (~4× ያነሰ፤ በምርጫ የሚነቃ)። ሁነታውን መቀየር ዳግም መጠቆምን ያስገድዳል።

ማጠቃለያ (summarization.ts)

summarizeMemories(apiKeyId, sessionId?, maxTokens = 4000) በአንድ ቁልፍ ትውስታዎች ውስጥ ያለው አጠቃላይ የቶከን ብዛት ከተመደበው ገደብ ሲያልፍ የቆየውን ይዘት ያመቃል። ረድፎቹን በcreated_at መሠረት DESC ቅደም ተከተል ይዞ ይደጋገማል፣ ከገደቡ ጋር የሚጣጣሙትን ረድፎች ያቆያል፣ ለቀሩት ደግሞ contentን በቦታው በዋናው ይዘት የመጀመሪያ ሦስት ዓረፍተ ነገሮች ይተካል። tokensSaved በድሮው እና በአዲሱ ይዘት መካከል ያለው የestimateTokens ልዩነት ነው።

ይህ ሂደት ይገኛል፣ ነገር ግን አሁን ባለው የውይይት ፓይፕላይን ውስጥ በራስ-ሰር አይጠራም — ቀጣይነት ያለው ማመቅ ካስፈለገዎት ከcron፣ ከአስተዳዳሪ ድርጊት ወይም ከMemoryConfig.autoSummarize ማገናኛ ይጥሩት። የውሂብ መጥፋቱ የአንድ አቅጣጫ ነው፤ ዋናው ጽሑፍ ተደርቦ ይጻፋል።

REST API

ሁሉም መዳረሻዎች የአስተዳደር ማረጋገጫ (requireManagementAuth) ይፈልጋሉ።

ዋና የትውስታ መዳረሻዎች (ነባር + የተዘመኑ)

ዘዴ ዱካ መግለጫ
GET /api/memory ገጽ የተከፋፈለ ዝርዝር ከማጣሪያዎች ጋር፦ apiKeyIdtypesessionIdqlimitpageoffset። ምላሹ stats.totalstats.tokensUsedstats.hitRatecacheStatsን ያካትታል
POST /api/memory ግቤት ይፍጠሩ (በZod የተረጋገጠ፦ contentkey፣ አማራጭ typesessionIdapiKeyIdmetadataexpiresAt)። በ(apiKeyId, key) ላይ upsert የሚያደርገውን createMemory() ይጠራል
GET /api/memory/[id] በUUID አንድ ግቤት ያምጡ
PUT /api/memory/[id] የግቤቱን መስኮች (typekeycontentmetadata) ያዘምኑ። አካል፦ MemoryUpdatePutSchema። የembedding ምንጭ ካለ ቬክተሩንም ያመሳስላል።
DELETE /api/memory/[id] ግቤትን ይሰርዙ፤ ከvec_memories (D15) እና ከQdrantም በሚቻለው መጠን ይሰርዛል። ካልተገኘ 404 ይመልሳል።
GET /api/memory/health verifyExtractionPipeline("health-check")ን ያስኬዳል — ሙሉ ዑደት ፍጠር→ዘርዝር→ሰርዝ። {working, latencyMs, error?}ን ይመልሳል

አዲስ የትውስታ ሞተር መዳረሻዎች (ዕቅድ 21)

ዘዴ ዱካ መግለጫ
POST /api/memory/retrieve-preview retrieveMemories የሙከራ ሂደት — በውጤት ነጥብ፣ ደረጃ እና ቶከኖች የተሰናዱ ውጤቶችን ይመልሳል። አካል፦ RetrievePreviewSchema። ትውስታዎችን አያስገባም ወይም አያሻሽልም።
GET /api/memory/embedding-providers የትኞቹ የተዋቀረ API ቁልፍ እንዳላቸው በማመልከት፣ አቅራቢዎችን ከembedding ሞዴሎች ጋር ይዘረዝራል።
GET /api/memory/engine-status ሙሉ የሞተሩን ሁኔታ ይመልሳል፦ የቁልፍ ቃል ደረጃ፣ የembedding ውሳኔ፣ የቬክተር ማከማቻ ስታቲስቲክስ፣ የQdrant ጤና፣ የrerank ውቅር። ቅርጽ፦ MemoryEngineStatusSchema
POST /api/memory/summarize የትውስታ ማመቅን በእጅ ያስጀምሩ። አካል፦ MemorySummarizeSchema (olderThanDaysapiKeyId?dryRun)። {candidates, tokensSaved}ን ይመልሳል።
POST /api/memory/reindex needs_reindex=1 ላላቸው ትውስታዎች የቬክተር ዳግም መረጃ ጠቋሚ ማዘጋጀትን ያስጀምሩ። አካል፦ MemoryReindexSchema (force)። {started, pending}ን ይመልሳል።

የቅንብሮች መዳረሻዎች

ዘዴ ዱካ መግለጫ
GET /api/settings/memory የአሁኑ ደረጃውን የጠበቀ MemorySettingsExtended (7 አዲስ መስኮች + የቆየ)
PUT /api/settings/memory MemorySettingsExtendedSchema ውስጥ ማንኛውንም መስክ ያዘምኑ (በድምሩ 12 መስኮች)
GET /api/settings/qdrant የአሁኑ የQdrant ቅንብሮች (QdrantSettingsSchema)
PUT /api/settings/qdrant የQdrant ቅንብሮችን ያዘምኑ። አካል፦ QdrantSettingsUpdateSchemaapiKey = ባዶ ሕብረቁምፊ ቁልፉን ያስወግዳል።
GET /api/settings/qdrant/health በተዋቀረው የQdrant አብነት ላይ የህያውነት ምርመራ ያካሂዳል። QdrantHealthResultSchemaን ይመልሳል።
POST /api/settings/qdrant/search በQdrant ላይ የትርጉም ፍለጋ ሙከራ ያካሂዳል። አካል፦ QdrantSearchSchema (querytopK)።
POST /api/settings/qdrant/cleanup ጊዜያቸው ላለፈ / ለቆዩ ትውስታዎች የQdrant ነጥቦችን ያስወግዱ።
GET /api/settings/qdrant/embedding-models ለQdrant የሚገኙትን embedding ሞዴሎች ይዘርዝሩ።

/api/memory ዝርዝር መጠይቅ በpage ላይ የተመሠረተ ገጽ ክፍፍልን (parsePaginationParams) ወይም ጥሬ offsetን ይደግፋል — offset ካለ ቅድሚያ ይወስዳል፣ እና ለምላሹ ቅርጽ የተሰላ page ይፈጠራል።

MCP መሣሪያዎች (open-sse/mcp-server/tools/memoryTools.ts)

MCP አገልጋዩ ሲነቃ፣ ሦስት የማህደረ ትውስታ መሣሪያዎች ይመዘገባሉ፦

  • omniroute_memory_search{apiKeyId, query?, type?, maxTokens?, limit?}retrieveMemories()ን ይጠቀልላል። ከv3.8.6 (D16) ጀምሮ፣ strategy በቋሚነት ወደ "exact" ከመቀመጥ ይልቅ ከgetMemorySettings() ይነበባል። query ከቀረበ እና strategy semantic ወይም hybrid ከሆነ፣ ቬክተር ማከማቻው ሲኖር ጥቅም ላይ ይውላል።
  • omniroute_memory_add{apiKeyId, sessionId?, type, key, content, metadata?}createMemory()ን ይጠቀልላል። 4ቱን መደበኛ ዓይነቶች ብቻ ይቀበላል፦ factualepisodicproceduralsemantic (D17)።
  • omniroute_memory_clear{apiKeyId, type?, olderThan?} → የሚዛመዱ ግቤቶችን ይዘረዝራል፣ እንደ አማራጭ ከተወሰነ ጊዜ በፊት በተፈጠሩበት የጊዜ ማህተም ያጣራል፣ ከዚያም እያንዳንዱን በdeleteMemory() ይሰርዛል (ይህም ቬክተሮችን ከsqlite-vec + Qdrant ያስወግዳል)።

ስለ ማጓጓዣ እና ወሰን ዝርዝሮች MCP-SERVER.mdን ይመልከቱ።

ዳሽቦርድ (የማህደረ ትውስታ ስቱዲዮ)

src/app/(dashboard)/dashboard/memory/page.tsx አሁን ባለ3-ትር ስቱዲዮ ነው፦

ትር፦ ማህደረ ትውስታዎች

  • የፅንሰ-ሐሳብ ካርድ (ሊታጠፍ የሚችል «እንዴት እንደሚሠራ» ማብራሪያ)።
  • ቅጽበታዊ ዝርዝር፣ ፍለጋ እና ገጽ ክፍፍል (በ300 ms የዘገየ)።
  • የዓይነት ማጣሪያ (factual / episodic / procedural / semantic / ሁሉም)።
  • የማህደረ ትውስታ ማከያ ሞዳል (ቁልፍ፣ ይዘት፣ ዓይነት)።
  • በቦታው ላይ ማርትዕ (የእርሳስ አዝራር → PUT /api/memory/[id])።
  • በየረድፉ መሰረዝ (ከማረጋገጫ መገናኛ ሳጥን ጋር)።
  • የአሁኑን ገጽ ወደ JSON መላክ፤ በፋይል መራጭ በኩል JSON ማስገባት።
  • የስታቲስቲክስ ካርዶች፦ totalEntriestokensUsedhitRate
  • «የቆዩትን አጠቃልል» አዝራር → POST /api/memory/summarize (በመጀመሪያ dry-run የዕጩዎችን ብዛት ያሳያል፣ ከዚያም ማረጋገጫ ይጠይቃል)።
  • GET /api/memory/health የሚመራ አረንጓዴ/ቀይ የጤና ነጥብ።

ትር፦ የሙከራ መድረክ

  • የመጠይቅ ግቤት + የስልት መራጭ (ትክክለኛ / ትርጉማዊ / ድብልቅ) + የቶከን በጀት።
  • «አስመስል» → POST /api/memory/retrieve-preview — በደረጃ የተደረደሩ ውጤቶችን ከscoretiertokensvecScoreftsScore ጋር ያሳያል።
  • የትኛው የመክተቻ ምንጭ / ቬክተር ማከማቻ ጥቅም ላይ እንደዋለ እና የአማራጭ መመለሻ መከሰቱን የሚያሳይ የመፍትሔ ፓነል።

ትር፦ ሞተር

  • የሞተር ሁኔታ ፓነል (የቁልፍ ቃል FTS5 ቺፕ፣ የመክተቻ ቺፕ፣ የቬክተር ማከማቻ ቺፕ፣ የQdrant ጤና ቺፕ፣ የድጋሚ ደረጃ አሰጣጥ ቺፕ)።
  • «አሁን ዳግም አውጫ» አዝራር → POST /api/memory/reindex
  • የመክተቻ ምንጭ መራጭ (ራስ-ሰር / ሩቅ / የማይለወጥ / transformers + መቀያየሪያዎች)።
  • የQdrant ውቅር ካርድ (የማንቃት መቀያየሪያ፣ አስተናጋጅ/ወደብ/ስብስብ/ቁልፍ፣ ግንኙነትን መሞከር፣ የትርጉማዊ ፍለጋ ሙከራ፣ ማጽዳት)።
  • የድጋሚ ደረጃ አሰጣጥ ውቅር ካርድ (የማንቃት መቀያየሪያ፣ የአቅራቢ/ሞዴል መራጭ)።

የማህደረ ትውስታ እና Qdrant ቅንብሮች ለቀድሞው/ዓለም አቀፍ የቅንብሮች በይነገጽ በ/dashboard/settings → Memory & Skills (MemorySkillsTab.tsx) ሥርም ይገኛሉ።

መሸጎጫ

src/lib/memory/store.tsgetMemory(id) ንባቦች በሂደት ውስጥ ያለ LRU-መሰል መሸጎጫ (MEMORY_CACHE_TTL = 1 minMEMORY_MAX_CACHE_SIZE = 500፣ 20 % ከቆዩት መጀመሪያ በማስወጣት) ይይዛል፤ በተጨማሪም የራሳቸውን ወሰን ያለው መሸጎጫ መጠቀም በሚፈልጉ ጠሪዎች የሚጠቀሙበት get/set/invalidate ሜተዶች ያሉት አጠቃላይ የቁልፍ/እሴት memoryCache ንብርብር (src/lib/memory/cache.ts) አለው (1 000-ግቤት LRU፣ ነባሪ TTL 5 min)።

ግላዊነት እና የሕይወት ዑደት

  • የማህደረ ትውስታ ባለቤትነት የAPI ቁልፍ መለያ ነው (resolveMemoryOwnerIdchatCore.ts ውስጥ)። apiKeyInfo.id ከሌለ ሰርስሮ ማውጣትም፣ ማስገባትም ሆነ ማውጣጣት አይከናወንም።
  • ወደፊት የሚያልቅ expires_at ያላቸው ግቤቶች ከሰርስሮ ማውጣት ይጣራሉ፤ ከretentionDays በላይ ያረጁ ግቤቶች በretrieveMemories ውስጥ ባለው created_at >= cutoff አንቀጽ አይካተቱም።
  • ለቋሚ ስረዛ፣ DELETE /api/memory/[id] ወይም omniroute_memory_clear ይጠቀሙ።
  • ማውጣጣት በsetImmediate በኩል ውጤቱን ሳይጠብቅ ይከናወናል፤ አለመሳካቶች በmemory.extraction.background.failed ስር ይመዘገባሉ እና ለጠሪው ፈጽሞ አይታዩም።
  • የማረጋገጫ ዙር-ጉዞዎች (verifyExtractionPipeline) የራሳቸውን የሙከራ ግቤቶች በfinally ብሎክ ውስጥ ያጸዳሉ።

በተጨማሪ ይመልከቱ

  • SKILLS.md — የskillsEnabled ቅንብር ከማህደረ ትውስታ ጎን ለጎን የመሣሪያ ትርጓሜዎችን ያስገባል።
  • MCP-SERVER.md — የMCP ማጓጓዣ / ወሰኖች።
  • API_REFERENCE.md — የበለጠ ሰፊ የAPI ወሰን።
  • የምንጭ ሞጁሎች፦
    • src/lib/memory/types.ts, schemas.ts
    • src/lib/memory/store.ts, retrieval.ts, injection.ts, reindex.ts
    • src/lib/memory/extraction.ts, summarization.ts, verify.ts
    • src/lib/memory/settings.ts, qdrant.ts, cache.ts
    • src/lib/memory/vectorStore.ts — sqlite-vec + ዲቃላ RRF
    • src/lib/memory/embedding/index.ts — ባለብዙ-ምንጭ የኢምቤዲንግ ንብርብር
    • src/lib/memory/embedding/types.ts, remote.ts, staticPotion.ts, transformersLocal.ts, cache.ts
    • src/shared/schemas/memory.ts — ለሁሉም የማህደረ ትውስታ API አካሎች የZod ንድፎች
    • src/shared/schemas/qdrant.ts — ለQdrant ቅንብሮች/ክዋኔዎች የZod ንድፎች
    • src/lib/db/memoryVec.ts — ለmemory_vec_meta CRUD
    • src/lib/db/migrations/015_create_memories.sql, 022_add_memory_fts5.sql, 023_fix_memory_fts_uuid.sql, 083_memory_vec.sql
    • src/app/api/memory/route.ts, [id]/route.ts, health/route.ts
    • src/app/api/memory/retrieve-preview/route.ts
    • src/app/api/memory/engine-status/route.ts
    • src/app/api/memory/embedding-providers/route.ts
    • src/app/api/memory/summarize/route.ts
    • src/app/api/memory/reindex/route.ts
    • src/app/api/settings/memory/route.ts
    • src/app/api/settings/qdrant/route.ts + ንዑስ-መስመሮች
    • src/app/(dashboard)/dashboard/memory/ — የStudio UI (ገጽ + ክፍሎች + ትሮች + hooks)
    • open-sse/handlers/chatCore.ts (የማስገባት / የማውጣጣት ሽቦ አያያዝ)
    • open-sse/mcp-server/tools/memoryTools.ts

የኢምቤዲንግ አቅራቢን መምረጥ (v3.8.16+)

የOmniRoute ማህደረ ትውስታ ሞተር አራት የኢምቤዲንግ ምንጮችን (src/lib/memory/embedding/) ይደግፋል። እያንዳንዳቸው በመዘግየት፣ ወጪ፣ የሞዴል ጥራት እና የማዋቀር ውስብስብነት ረገድ የተለያዩ ሚዛናዊ ምርጫዎች አሏቸው።

የኢምቤዲንግ ምንጮች

አቅራቢ ምንጭ መዘግየት ወጪ ጥራት ማዋቀር
transformers አካባቢያዊ ONNX ሞዴል (Xenova/all-MiniLM-L6-v2) ~50-150ms (CPU) ነጻ ጥሩ npm install ብቻ
static አስቀድሞ የተሰሉ ቬክተሮች (የተሸጎጡ) <1ms ነጻ አይመለከተውም (በመሸጎጫ መገኘት ይወሰናል) ምንም
remote OpenAI / Cohere / Voyage API ~100-300ms $0.02-0.10/1M ቶከኖች እጅግ በጣም ጥሩ API ቁልፍ
auto በአሂድ ጊዜ የሚገኘውን ምርጥ ምንጭ ይመርጣል ከተመረጠው ምንጭ ጋር ተመሳሳይ ነጻ ከተመረጠው ምንጭ ጋር ተመሳሳይ ምንም
(cache) በማንኛውም ምንጭ ላይ ያለ የማህደረ ትውስታ ውስጥ LRU ንብርብር <1ms (ሲገኝ)፣ ሙሉ መዘግየት (ሳይገኝ) ነጻ ከመሠረታዊው ጋር ተመሳሳይ ሁልጊዜ ክፍት (ሊመረጥ የሚችል ምንጭ አይደለም)

የውሳኔ ዛፍ

                  የማሰማሪያ አውድዎ ምንድን ነው?
                  │
      ┌───────────┼───────────┬──────────────┐
      │           │           │              │
  ልማት/ሙከራ    አነስተኛ ፕሮድ   ትልቅ ፕሮድ    ጠርዝ / ከመስመር ውጭ
      │           │           │              │
      ▼           ▼           ▼              ▼
  transformers transformers remote (Qdrant) transformers
  (ነጻ፣ API የለም)            (ምርጥ ጥራት)   (በይነመረብ የለም)
      │           │           │              │
      └────────┬──┴───────────┴──────────────┘
               │
               ▼
            ሁልጊዜ `cache` ንብርብርን ከላይ ያክሉ
            (LruCache ማንኛውንም አቅራቢ ይጠቀልላል)

የውሂብ ጎታ እና API ውቅር

የማህደረ ትውስታ ኢምቤዲንግ አማራጮች የሚዋቀሩት በSettings API/UI በኩል እንጂ በአካባቢ ተለዋዋጮች አይደለም። በSettings ስር ያሉት አግባብነት ያላቸው የቅንብር ውሂብ ጎታ ቁልፎች (normalizeMemorySettingssrc/lib/memory/settings.ts ውስጥ) እነዚህ ናቸው፦

  • memoryEmbeddingSource: "transformers" (አካባቢያዊ)፣ "remote" (በAPI ላይ የተመሠረተ፣ ለምሳሌ OpenAI)፣ "static" (ውጫዊ ማከማቻ)፣ ወይም "auto"
  • memoryEmbeddingProviderModel: ለremote/static ምንጮች የሞዴል መለያ (ለምሳሌ፣ "text-embedding-3-small")
  • memoryTransformersEnabled: true | false
  • memoryStaticEnabled: true | false
  • memoryVectorStore: "sqlite-vec", "qdrant", ወይም "auto"

አካባቢያዊ ሞዴል (transformers)

አካባቢያዊ ሞዴሎችን ለማስኬድ transformers.jsን በውስጥ ይጠቀማል፦

# በኮዱ ውስጥ የሚነበቡ የአካባቢ ተለዋዋጮች (src/lib/memory/embedding/index.ts):
MEMORY_TRANSFORMERS_MODEL=Xenova/all-MiniLM-L6-v2  # የHF ሞዴል ማከማቻ
MEMORY_STATIC_MODEL=minishlab/potion-base-8M       # የHF static potion ሞዴል
MEMORY_STATIC_CACHE_DIR=<DATA_DIR>/embeddings      # የመሸጎጫ ማውጫ

የLRU ኢምቤዲንግ መሸጎጫ

መሸጎጫው በነባሪነት ሁልጊዜ ክፍት ሲሆን በአካባቢ ተለዋዋጮች በኩል ይዋቀራል፦

MEMORY_EMBEDDING_CACHE_MAX=1000                    # ከፍተኛው የተሸጎጡ ንጥሎች ብዛት
MEMORY_EMBEDDING_CACHE_TTL_MS=300000               # TTL (5 ደቂቃ)

የአፈጻጸም ቁጥሮች

በተለመደ ባለ 4-ኮር x86 ሰርቨር ላይ የተደረገ የአፈጻጸም መለኪያ (እያንዳንዱ ጽሑፍ ~100 ቶከኖች)፦

አቅራቢ p50 p95 p99 የ1M embeddings ወጪ
transformers (CPU) 80ms 180ms 350ms ነጻ
remote (OpenAI) 120ms 220ms 400ms ~$0.02 (ada-002) / $0.13 (3-large)
static (Qdrant) 15ms 30ms 60ms በQdrant ማስተናገጃ ላይ ይወሰናል
cache (የተገኘ) <1ms <1ms 2ms ነጻ

የእውነታ ማውጣት ንድፎች (v3.8.16+)

extraction.ts ሞጁል (src/lib/memory/extraction.ts) ከውይይት መልዕክቶች የተዋቀሩ እውነታዎችን ለማውጣት የregex ንድፍ ማዛመድን ይጠቀማል። እነዚህን ንድፎች መረዳት ለአጠቃቀም ሁኔታዎ የማውጣት ጥራትን እንዲያስተካክሉ ይረዳዎታል።

ነባሪ የንድፍ ምድቦች

ምድብ የንድፍ ምሳሌ የሚይዘው
PREFERENCE_PATTERNS "I prefer <X>", "I like <X>", "I hate <X>" የተጠቃሚ ምርጫዎች
DECISION_PATTERNS "I'll use <X>", "I decided to <X>", "I went with <X>" የተጠቃሚ ውሳኔዎች (ክስተታዊ)
PATTERN_PATTERNS "I usually <X>", "I always <X>", "I never <X>" ቀጣይነት ያላቸው የባህሪ ንድፎች

የንድፍ ምሳሌዎች (ቀለል የተደረጉ)

// ከ src/lib/memory/extraction.ts
const PREFERENCE_PATTERNS = [
  /\bI\s+(?:really\s+)?prefer\s+([^.,\n]+)/gi,
  /\bI\s+(?:really\s+)?like\s+([^.,\n]+)/gi,
  /\bI\s+(?:hate|dislike|avoid)\s+([^.,\n]+)/gi,
];
const DECISION_PATTERNS = [
  /\bI'?(?:ll|will)\s+use\s+([^.,\n]+)/gi,
  /\bI\s+(?:have\s+)?decided\s+(?:to\s+)?([^.,\n]+)/gi,
];
const PATTERN_PATTERNS = [/\bI\s+usually\s+([^.,\n]+)/gi, /\bI\s+always\s+([^.,\n]+)/gi];

ምን ይወጣል

አንድ ተጠቃሚ እንዲህ ሲል፦

"TypeScriptን እመርጣለሁ። ለዚህ ፕሮጀክት Postgresን እጠቀማለሁ። ከመግፋቴ በፊት ሁልጊዜ commit አደርጋለሁ። Pythonን አልወድም።" ማውጣቱ 4 ትውስታዎችን ያመነጫል፦

ቁልፍ ምድብ ዓይነት ይዘት
preference:typescript ምርጫ እውነታዊ "TypeScript"
decision:postgres_for_this_project ውሳኔ ክስተታዊ "Postgres ለዚህ ፕሮጀክት"
pattern:commit_before_pushing ንድፍ እውነታዊ "ከመግፋት በፊት commit ማድረግ"
preference:python ምርጫ እውነታዊ "Python"

የማውጣት ገደቦች

ከቁጥጥር ውጪ የሆነ ማውጣትን ለመከላከል፣ የሚከተሉት ገደቦች ተፈጻሚ ይሆናሉ፦

| ዝቅተኛው የይዘት ርዝመት | 3 ቁምፊዎች | | ከፍተኛው የይዘት ርዝመት | 500 ቁምፊዎች |

ማውጣትን መቼ ማሰናከል እንዳለብዎት

ትውስታ በነቃ ቁጥር ማውጣቱ በራስ-ሰር ይሠራል፤ የተለየ ማውጣት-ብቻ መቀያየሪያ የለም። ለማጥፋት፣ ትውስታን ሙሉ በሙሉ ያሰናክሉ (enabled: falsePUT /api/settings/memory በኩል)። በሚከተሉት ሁኔታዎች ይህን ማድረግ ያስቡበት፦

  • ከፍተኛ የመልዕክት መጠን ሲኖርዎት እና የማውጣቱ ወጪ ቀላል የማይባል ሲሆን
  • ውይይቶችዎ አብዛኛውን ጊዜ ጊዜያዊ (ውይይት፣ ማረም) እና የረጅም ጊዜ ዋጋ የሌላቸው ሲሆኑ
  • አውድን አስቀድመው በብጁ ተሰኪዎች እየመዘገቡ ከሆነ

የድብልቅ RRF ማስተካከያ (v3.8.16+)

Reciprocal Rank Fusion (RRF) ስልተ ቀመር የFTS5 (ቁልፍ ቃል) እና የvector (ትርጉማዊ) ውጤቶችን ያጣምራል። የk መለኪያ ዝቅተኛ ደረጃ ላላቸው ውጤቶች ምን ያህል ክብደት እንደሚሰጥ ይቆጣጠራል።

ቀመሩ

ለእያንዳንዱ እጩ ትውስታ፣ የRRF ነጥብ፦

RRF(d) = Σ  1 / (k + rank_i(d))

ይህም፦

  • k ቋሚው ነው (ነባሪ 60)
  • rank_i(d) በiኛው የመልሶ ማግኛ ሥርዓት (FTS፣ vector) ውስጥ የሰነድ d ደረጃ ነው
  • ድምሩ በሁሉም የመልሶ ማግኛ ሥርዓቶች ላይ ይከናወናል

k ውጤቶችን እንዴት እንደሚነካ

k ዋጋ ተጽዕኖ ተስማሚ የሆነው
k=0 ንጹሕ የደረጃ ውህደት (ማለስለስ የለም) የንድፈ ሐሳብ መነሻ
k=10-30 ከፍተኛ ውጤቶችን በከፍተኛ ሁኔታ ይመዝናል፣ ዝቅተኛ ደረጃ ያለው የሚያበረክተው በጣም ትንሽ ነው ከፍተኛዎቹ 3 ውጤቶች ብዙውን ጊዜ ትክክል ሲሆኑ
k=60 (ነባሪ) ሚዛናዊ — ከፍተኛዎቹ 10 ውጤቶች ሁሉ ትርጉም ባለው ሁኔታ ያበረክታሉ ለአጠቃላይ ዓላማ መልሶ ማግኘት
k=100+ ይበልጥ ጠፍጣፋ — ዝቅተኛ ደረጃ ያላቸው ውጤቶች እንኳ በብዙ ሥርዓቶች ውስጥ ከታዩ የበላይ ሊሆኑ ይችላሉ recall > precision ወሳኝ በሚሆንበት ጊዜ

kን በተግባር ማስተካከል

# ነባሪ
MEMORY_RRF_K=60

# ከፍተኛ precision (አነስተኛ ትውስታ፣ ጥቂት ሰነዶች)
MEMORY_RRF_K=20

# ከፍተኛው recall (ትልቅ ትውስታ፣ የተለያዩ ጥያቄዎች)
MEMORY_RRF_K=120

k=20 ያለው ምሳሌ፦

  • FTS ደረጃ 1 → አስተዋጽኦ 1/21 = 0.048
  • FTS ደረጃ 10 → አስተዋጽኦ 1/30 = 0.033
  • Vector ደረጃ 1 → አስተዋጽኦ 0.048
  • ከፍተኛው ጥምር፦ 0.096

k=60 ያለው ምሳሌ፦

  • FTS ደረጃ 1 → አስተዋጽኦ 1/61 = 0.016
  • FTS ደረጃ 10 → አስተዋጽኦ 1/70 = 0.014
  • Vector ደረጃ 1 → አስተዋጽኦ 0.016
  • ከፍተኛው ጥምር፦ 0.033

ከፍ ያለ k ሲኖር፣ በከፍተኛ-1 እና በደረጃ-10 መካከል ያለው አንጻራዊ ልዩነት አነስተኛ ይሆናል፤ ስለዚህ ስልተ ቀመሩ ከከፍተኛ ደረጃ እምነት ይልቅ በመልሶ ማግኛ ሥርዓቶች መካከል ባለ ስምምነት ላይ የበለጠ ይመረኮዛል።

kን መቼ መቀየር እንዳለብዎት

ምልክት ይህን ይሞክሩ
ከፍተኛው ውጤት ሁልጊዜ ያሸንፋል፣ ግን የተሳሳተ ነው kን ዝቅ ያድርጉ (ለምሳሌ፣ 20) — የከፍተኛ ደረጃ እምነት የበለጠ አስፈላጊ ነው
ትክክለኛው መልስ ከከፍተኛዎቹ 5 ውስጥ ነው፣ ግን ከፍተኛ-1 አይደለም kን ከፍ ያድርጉ (ለምሳሌ፣ 100) — ጠፍጣፋ የነጥብ አሰጣጥ ስምምነትን ይሸልማል
Recall ከፍተኛ ነው፣ ግን precision ዝቅተኛ ነው kን ዝቅ ያድርጉ — ደረጃ አሰጣጡን ያጥሩ
Recall ዝቅተኛ ነው (ተዛማጅ ሰነዶች ጠፍተዋል) kን ከፍ ያድርጉ — ዝቅተኛ ደረጃ ላላቸው ሰነዶች ዕድል ይስጡ

የRRF ክብደት አሰጣጥ

Reciprocal rank fusion ለትርጉማዊ vector ደረጃ እና ለሙሉ-ጽሑፍ ፍለጋ ደረጃ እኩል ክብደቶችን ይጠቀማል፦

RRF(d) = 1/(k + rank_vector) + 1/(k + rank_fts)

የእያንዳንዱን ክብደት ለማስተካከል የሚያስችሉ የአካባቢ ተለዋዋጮች የሉም (MEMORY_RRF_VECTOR_WEIGHT/MEMORY_RRF_FTS_WEIGHT አይኖሩም)።


የማጠቃለያ ስልት (v3.8.16+)

summarization.ts ሞጁል (src/lib/memory/summarization.ts) የንቁ ስብስቡን መጠን አነስተኛ ለማድረግ፣ የማስታወስ ችሎታን እንደጠበቀ የቆዩ ትውስታዎችን ይጨምቃል።

ማጠቃለያ የሚጀመርበት ጊዜ

አስጀማሪ ገደብ (ነባሪ)
በAPI በኩል በእጅ ማስጀመር አይመለከተውም

ምን ይጠቃለላል

summarization.ts ሁለት መግቢያ ነጥቦች ይላካሉ፦

  • summarizeMemories(apiKeyId, sessionId?, maxTokens = 4000) — የአንድን ክፍለ ጊዜ ትውስታዎች በቶከን በጀት የተገደበ አንድ የማጠቃለያ ጽሑፍ አድርጎ ያጠቃልላል።
  • summarizeMemoriesOlderThan(apiKeyId, days, dryRun) — በAPI የሚጠቀምበት በዕድሜ ላይ የተመሠረተ ማጨቅ፦ ከdays በላይ የቆየን እያንዳንዱን ትውስታ ይመርጣል፣ ከእነሱ አንድ የታመቀ የማጠቃለያ ትውስታ ይፈጥራል፣ እና (dryRun false ሲሆን) የመጀመሪያዎቹን ይሰርዛል። ምንም ነገር ሳይለወጥ የዕጩዎችን ስብስብና አጠቃላይ የቶከን ብዛት ለማየት dryRun: true ያስተላልፉ።

የመለያ/ቁልፍ ማሰባሰቢያ ዙር ወይም ለእያንዳንዱ ትውስታ "ዋና ከማጠቃለል ከሚችል" የሚል የውጤት አሰጣጥ የለም — ምርጫው ሙሉ በሙሉ በዕድሜ ገደቡ ላይ የተመሠረተ ሲሆን፣ የማጠቃለያው ጽሑፍም ለእያንዳንዱ ዕጩ ዓይነት-ቅድመ ቅጥያ ያለው የታመቀ መስመር ነው።

ማጠቃለያን ማስጀመር

ማጠቃለያ በእጅ / በምርጫ የሚነቃ ነው — የautoSummarize ቅንብር በነባሪ false ነው፣ ስለዚህ ምንም ነገር በራስ-ሰር አይጨመቅም። በAPI በኩል ያስጀምሩት፦

curl -X POST http://localhost:20128/api/memory/summarize \
  -H "Authorization: Bearer $OMNIROUTE_KEY"

እንዳይነቃ ለማድረግ፣ autoSummarizeን በነባሪ እሴቱ (false) ላይ ብቻ ያቆዩት።

የማጠቃለያ ጥራት ምክሮች

  • መጀመሪያ በdryRun ቅድመ ዕይታ ያድርጉsummarizeMemoriesOlderThan(..., true) የመጀመሪያዎቹን ከመሰረዝዎ በፊት ምን እንደሚዋሃድ ማረጋገጥ እንዲችሉ የዕጩዎችን ዝርዝርና አጠቃላይ የቶከን ብዛት ይመልሳል።
  • ብዙ የትውስታ ስብስብ ካለዎት ማጠቃለያውን ትራፊክ በሚቀንስባቸው ሰዓታት ያስኪዱ — የLLM ጥሪው ዘገምተኛው ክፍል ነው
# የCron አይነት፦ በየቀኑ ከጠዋቱ 3 ሰዓት ላይ አጠቃልል
0 3 * * * curl -X POST http://localhost:20128/api/memory/summarize \
  -H "Authorization: Bearer $OMNIROUTE_KEY"

የMemoryBackend አቅራቢ ንድፍ

ትክክለኛው የመረጃ ምንጭ፦ src/lib/memory/backend.ts, src/lib/memory/genericBackend.ts, src/lib/memory/manager.ts ሙከራዎች፦ src/lib/memory/__tests__/generic-backend.test.ts

የMemoryBackend አቅራቢ ንድፍ በነባሩ የትውስታ ሞተር ላይ ሊሰካ የሚችል የጀርባ-ክፍል ረቂቅ ንብርብር ያስተዋውቃል። ከአንድ የማከማቻ ትግበራ ጋር ብቻ ከመታሰር ይልቅ፣ የትውስታ ሥርዓቱ አሁን ሊዋቀር የሚችል ዋና/ተተኪ ማዞሪያ ያላቸውን በርካታ የጀርባ ክፍሎች (SQLite፣ Obsidian፣ Notion፣ ብጁ HTTP የጀርባ ክፍሎች) ይደግፋል።

አርክቴክቸር

┌──────────────────────────────────────────────────────────┐
│                    የAPI መንገዶች                          │
│            (src/app/api/memory/route.ts)                  │
└──────────────────────┬───────────────────────────────────┘
                       │
┌──────────────────────▼───────────────────────────────────┐
│                   MemoryManager                           │
│           ነጠላ አስተባባሪ (manager.ts)                     │
│                                                          │
│  ዋና ──────► የጀርባ ክፍል A  (ለምሳሌ SQLite)              │
│  ተተኪ ─────► የጀርባ ክፍል B  (ለምሳሌ Obsidian)            │
│             የጀርባ ክፍል C  (ለምሳሌ Notion በGenericBackend)│
└──────────────────────┬───────────────────────────────────┘
                       │
        ┌──────────────┼──────────────┐
        ▼              ▼              ▼
┌────────────┐ ┌────────────┐ ┌──────────────────┐
│ SQLite     │ │ Obsidian   │ │ GenericMemory    │
│ የጀርባ ክፍል │ │ የጀርባ ክፍል │ │ የጀርባ ክፍል (HTTP) │
└────────────┘ └────────────┘ └──────────────────┘

ዋና በይነገጽ (backend.ts)

እያንዳንዱ የጀርባ ክፍል የMemoryBackend በይነገጽን መተግበር አለበት፦

interface MemoryBackend {
  readonly id: string;
  readonly displayName: string;

  // CRUD
  create(input: CreateMemoryInput): Promise<Memory>;
  get(id: string): Promise<Memory | null>;
  update(id: string, updates: Partial<...>): Promise<boolean>;
  delete(id: string): Promise<boolean>;
  list(filter: MemoryFilter): Promise<{ data: Memory[]; total: number; byType: Record<string, number> }>;

  // ፍለጋ
  search(config: SearchConfig): Promise<Memory[]>;

  // ጤንነት
  health(): Promise<HealthCheckResult>;

  // የሕይወት ዑደት (አማራጭ)
  initialize?(): Promise<void>;
  shutdown?(): Promise<void>;
}

MemoryManager (manager.ts)

የሚከተሉትን የሚያከናውን ነጠላ አስተባባሪ፦

  • የጀርባ ክፍሎችን በregister(backend) ይመዘግባል — ሲነሳ ከindex.ts ይጠራል
  • ዋናውን + ተተኪዎችን በconfigure(primary, fallbacks) ያዋቅራል
  • CRUD/ፍለጋን ወደ ዋናው ያዞራል፣ ሲከሽፍም የተተኪ ሰንሰለትን ይጠቀማል
  • ሁሉንም የጀርባ ክፍሎች በየጊዜው የጤንነት ፍተሻ ያደርግባቸዋል

የተተኪ ባህሪ፦

ክወና ዋና ተተኪዎች
create ዋናው ብቻ
get መጀመሪያ ዋናውን ይሞክራል null ከሆነ ተተኪን ይጠቀማል
update ዋናው ብቻ ጀምሮ-ሳይጠብቅ ማመሳሰል
delete ዋናው ብቻ ጀምሮ-ሳይጠብቅ ማመሳሰል
list ዋናው ብቻ
search መጀመሪያ ዋናው ስህተት ሲኖር ተተኪን ይጠቀማል

GenericMemoryBackend (genericBackend.ts)

ማንኛውንም REST API ወደ MemoryBackend የሚያስማማ አጠቃላይ HTTP አገናኝ። ለሚከተሉት ጠቃሚ ነው፦

  • Notion — በNotion API በኩል ያገናኙ
  • Obsidian — በObsidian Local REST API በኩል ያገናኙ
  • ብጁ የጀርባ ክፍሎች — RESTful የትውስታ API የሚያቀርብ ማንኛውም አገልግሎት

ውቅር፦

interface GenericBackendConfig {
  baseUrl: string;           // የጀርባ API መሠረታዊ URL
  apiKey?: string;           // ለማረጋገጫ የBearer ቶከን
  headers?: Record<string, string>;  // ብጁ HTTP ራስጌዎች
  timeout?: number;          // የጥያቄ ጊዜ ገደብ (ነባሪ፦ 30000ms)
  backendType?: string;      // ለምዝግብ ማስቀመጥ

  // የመዳረሻ ነጥብ ሽረቶች (ነባሪዎች የREST ልማዶችን ይጠቀማሉ)
  endpoints?: {
    search?: string;   // ነባሪ፦ "/memories/search"
    create?: string;   // ነባሪ፦ "/memories"
    list?: string;     // ነባሪ፦ "/memories"
    get?: string;      // ነባሪ፦ "/memories/{id}"
    update?: string;   // ነባሪ፦ "/memories/{id}"
    delete?: string;   // ነባሪ፦ "/memories/{id}"
    health?: string;   // ነባሪ፦ "/health"
  };

  // የጥያቄ መለኪያ ስም ማዛመጃዎች
  queryParams?: {
    query?/apiKeyId?/limit?/offset?/strategy?/maxTokens?/type?/sessionId?/orderBy?/orderDir?/options?
  };

  // የዱካ መለኪያ ስም ማዛመጃዎች
  pathParams?: {
    id?/memoryId?
  };
}

የታወቁ ጀርባዎችKNOWN_BACKENDS ውስጥ አስቀድመው ተዋቅረዋል፦

createKnownBackend("obsidian"); // → ወደ localhost:27123 የሚያመለክት GenericMemoryBackend
createKnownBackend("notion"); // → ወደ api.notion.com/v1 የሚያመለክት GenericMemoryBackend

አብሮገነብ ጀርባዎች

SQLiteBackend (sqliteBackend.ts)

ነባሪው ዋና ጀርባ። src/lib/memory/store.tsን በመጠቀም ነባሩን SQLite-ተኮር የማህደረ ትውስታ ማከማቻ ይጠቀልላል። ሲነሳ በራስ-ሰር ይመዘገባል።

import { sqliteBackend } from "./sqliteBackend";
memoryManager.register(sqliteBackend);
ObsidianBackend (obsidianBackend.ts)

ነባሩን የObsidian ውህደት (src/lib/memory/obsidianBackend.ts) ይጠቀልላል። በObsidian Local REST API በኩል ከObsidian ማከማቻ ጋር ይገናኛል።

ቅንብሮች

የማህደረ ትውስታ ጀርባ ቅንብሮች በመተግበሪያው የቅንብሮች ሰንጠረዥ ውስጥ ይከማቻሉ፣ እንዲሁም በsrc/lib/memory/settings.ts በኩል ይተዳደራሉ፦

ቅንብር የአካባቢ/ውቅር ቁልፍ ነባሪ መግለጫ
ዋና ጀርባ memoryPrimaryBackend "sqlite" የዋናው ጀርባ ID
ተጠባባቂ ጀርባዎች memoryFallbackBackends [] በቅደም ተከተል የተደረደሩ ተጠባባቂ ጀርባ IDዎች
የጀርባ ውቅሮች memoryBackendConfigs {} ለእያንዳንዱ ጀርባ የሚደረጉ የውቅር ሽረቶች

ቅንብሮች በnormalizeMemorySettings() በኩል መደበኛ ቅርጽ ይይዛሉ፣ እና በgetMemorySettings() ላይ ይሸጎጣሉ።

የማስጀመር ፍሰት

የመተግበሪያ ማስነሻ
  → index.ts ማስመጣቶች (እንደ ጎንዮሽ ውጤት)፦ SQLiteBackendን ይመዘግባሉ
  → initMemoryBackends() ከመተግበሪያው የሕይወት ዑደት ይጠራል፦
      1. ቅንብሮችን ጫን (getMemorySettings)
      2. ዋናውን + ተጠባባቂዎቹን አዋቅር
      3. ሁሉንም ጀርባዎች አስጀምር (የጤና ምርመራ)
      4. ለጥያቄዎች ዝግጁ

አዲስ ጀርባ ማከል

  1. src/lib/memory/<name>Backend.ts ውስጥ የ**MemoryBackendን በይነገጽ ይተግብሩ**
  2. src/lib/memory/index.ts ወደ ውጭ ይላኩ
  3. ሲነሳ በmemoryManager.register(yourBackend) ይመዝግቡ
  4. በቅንብሮች በኩል ያዋቅሩmemoryPrimaryBackendን ወደ ጀርባዎ ID ያቀናብሩ
  5. src/lib/memory/__tests__/generic-backend.test.tsን እንደ ማጣቀሻ በመጠቀም ይፈትሹ

ምሳሌ፦ Brain ጀርባ

import { createGenericMemoryBackend } from "./genericBackend";

const brainBackend = createGenericMemoryBackend("brain", "BK-Brain", {
  baseUrl: process.env.BRAIN_API_URL || "http://localhost:9099",
  apiKey: process.env.BRAIN_API_KEY,
  endpoints: {
    search: "/api/memory/search",
    create: "/api/memory",
    health: "/api/health",
  },
});

memoryManager.register(brainBackend);

ማረጋገጫ

የክፍል ፈተናዎች

npx vitest run src/lib/memory/__tests__/generic-backend.test.ts --reporter=verbose

የሚጠበቀው ውጤት፦ 35 ፈተናዎች፣ ሁሉም ያለፉ፣ የሚከተሉትን ይሸፍናሉ፦

  • ገንቢ (2)
  • የጤና ምርመራ (4) — ስኬት፣ ውድቀት 500፣ የአውታረ መረብ ስህተት፣ መዘግየት
  • ማስጀመር (2) — ስኬት፣ ውድቀት
  • መፍጠር (2) — ነባሪ መዳረሻ ነጥብ፣ ብጁ መዳረሻ ነጥብ
  • ማግኘት (4) — ስኬት፣ 404 → null፣ 404 ያልሆነ ስህተት መጣል፣ ብጁ የዱካ መለኪያዎች
  • ማዘመን (2) — ስኬት፣ 404 → false
  • መሰረዝ (2) — ስኬት፣ 404 → false
  • መዘርዘር (2) — የጥያቄ መለኪያዎች፣ ብጁ የመለኪያ ስሞች
  • መፈለግ (3) — የጥያቄ መለኪያዎች፣ ብጁ መዳረሻ ነጥብ፣ የአማራጮች ተከታታይ ማድረግ
  • የማረጋገጫ ራስጌዎች (2) — Bearer ቶከን፣ ብጁ ራስጌዎች
  • ፋብሪካ (1)

የዓይነት ምርመራ

npm run typecheck:core

የሚጠበቀው፦ 0 ስህተቶች