From a95c772a5c846839f816a1789d939c89b78ec290 Mon Sep 17 00:00:00 2001 From: Zhafron Date: Wed, 4 Nov 2026 09:27:07 +0700 Subject: [PATCH 1/4] docs(readme): refresh features, options and site links Audited against main 1055d37: provider list, dreaming status, memory modes, web UI views, encryption ciphers and dev commands were stale or missing. Adds website/docs badges and links, a common-options table with defaults from src/config.ts, and brings the five translations back in line with README.md. --- .github/i18n/README.ar.md | 145 +++++++++++++++++++++++++++++++------- .github/i18n/README.de.md | 137 +++++++++++++++++++++++++++++------ .github/i18n/README.nl.md | 141 +++++++++++++++++++++++++++++------- .github/i18n/README.tr.md | 121 +++++++++++++++++++++++++++---- .github/i18n/README.zh.md | 81 +++++++++++++++++---- README.md | 53 ++++++++++---- 6 files changed, 566 insertions(+), 112 deletions(-) diff --git a/.github/i18n/README.ar.md b/.github/i18n/README.ar.md index 32b082b4..f7e8ab94 100644 --- a/.github/i18n/README.ar.md +++ b/.github/i18n/README.ar.md @@ -4,6 +4,8 @@ [![npm downloads](https://img.shields.io/npm/dm/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![license](https://img.shields.io/npm/l/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![GitHub stars](https://img.shields.io/github/stars/tickernelz/opencode-mem.svg)](https://github.com/tickernelz/opencode-mem) +[![Website](https://img.shields.io/badge/website-opencode--mem.zhafron.my.id-blue)](https://opencode-mem.zhafron.my.id) +[![Docs](https://img.shields.io/badge/docs-opencode--mem.zhafron.my.id%2Fdocs-blue)](https://opencode-mem.zhafron.my.id/docs/) ![OpenCode Memory Banner](../pics/banner.png) @@ -13,7 +15,16 @@ ## الميزات الأساسية -قاعدة بيانات Turso/libSQL محلية مع بحث متجهات أصلي، ذكريات مشروع دائمة، تعلّم تلقائي لملف المستخدم، خط زمني موحّد للذاكرة والمطالبات، واجهة ويب كاملة الميزات، استخراج ذكي للذاكرة مستند إلى المطالبات، دعم مزودي ذكاء اصطناعي متعددين (OpenAI، Anthropic)، أكثر من 12 نموذج تضمين محلي، إزالة تكرار ذكية، وحماية خصوصية مدمجة. +- **قاعدة بيانات محلية:** قاعدة بيانات Turso/libSQL مدمجة مع بحث متجهات أصلي، مخزّنة ضمن `storagePath`. لا حاجة إلى قاعدة بيانات متجهات منفصلة. +- **استخراج ذكي للذاكرة مستند إلى المطالبات (auto-capture):** عندما تصبح الجلسة خاملة، يحوّل طلب ذكاء اصطناعي في الخلفية العمل التقني إلى ذكريات مشروع دائمة. +- **استرجاع تلقائي:** تُحقن الذكريات ذات الصلة وملف المستخدم في سياق النموذج (`chatMessage`). +- **تعلّم ملف المستخدم:** ملخص عابر للمشاريع لتفضيلاتك وأنماطك وسير عملك. +- **نظافة الذاكرة:** إزالة تكرار ذكية، وupdate-on-capture اختياري، ودمج dreaming اختياري مع سلة محذوفات قابلة للاسترداد. +- **دعم مزودي ذكاء اصطناعي متعددين:** أي مزود مُعدّ في OpenCode (`opencodeProvider` / `opencodeModel`)، أو واجهة API يدوية: OpenAI Chat Completions، OpenAI Responses، Anthropic، MiniMax، OrcaRouter، Atlas Cloud، Cheaper Inference، API Route، Runcrate، CloudGPU. +- **التضمينات:** أكثر من 12 نموذج تضمين محلي يعمل على المعالج المركزي (CPU) دون الحاجة إلى GPU، أو أي واجهة API للتضمينات متوافقة مع OpenAI. +- **واجهة ويب كاملة الميزات:** memory–prompt timeline موحّد، وUser profile، وSkill library، وMarkdown vault، وإحصاءات الحالة، مع HTTP Basic Auth اختياري. +- **الخصوصية:** وسوم ``، وحجب بيانات الاعتماد قبل الالتقاط، وتشفير اختياري للبيانات المخزّنة. +- **قابلية النقل:** واجهة خلفية Markdown vault اختيارية، وأوامر `export` / `import` / `migrate` في أداة `memory` للمشاريع المنقولة أو المنسوخة. ## المتطلبات الأساسية @@ -138,11 +149,11 @@ opencode-mem **لا** يتطلب وحدة معالجة رسومات (GPU). تع } ``` -عند أول تشغيل ينشئ المكون الإضافي `~/.config/opencode/opencode-mem-db.key` (مفتاح hex بطول 32 بايت، `chmod 600`) ويرحّل الأجزاء النصية الحالية. تجاوز بـ `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` أو `"file://~/path/to.key"` إذا كنت تدير المفتاح بنفسك. فقدان المفتاح يعني أن قواعد البيانات المشفّرة لا يمكن فتحها. +عند أول تشغيل ينشئ المكون الإضافي `~/.config/opencode/opencode-mem-db.key` (مفتاح hex بطول 32 بايت، `chmod 600`) ويرحّل الأجزاء النصية الحالية. تجاوز بـ `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` أو `"file://~/path/to.key"` إذا كنت تدير المفتاح بنفسك. فقدان المفتاح يعني أن قواعد البيانات المشفّرة لا يمكن فتحها. يحدد `databaseEncryptionCipher` خوارزمية التشفير: `aes256gcm` (الافتراضي)، أو `aes128gcm`، أو `aegis256`، أو `aegis256x2`، أو `aegis128l`، أو `aegis128x2` أو `aegis128x4`. **Windows:** استخدم `%USERPROFILE%\.config\opencode\opencode.json` (مثلًا `C:\Users\\.config\opencode\opencode.json`). هذا المكون الإضافي **لا** يقرأ `%APPDATA%` أو `%LOCALAPPDATA%` لمدخل مكون OpenCode الإضافي — ضع الملف تحت `.config\opencode` في ملف تعريف المستخدم، ثم أعد تشغيل OpenCode. إذا لم يظهر المكون الإضافي، أكّد ذلك المسار وأعد التشغيل مجددًا. -يُنزَّل المكون الإضافي تلقائيًا عند التشغيل التالي. +يُنزَّل المكون الإضافي تلقائيًا عند التشغيل التالي. ## كيفية الاستخدام اليومي @@ -158,10 +169,10 @@ opencode-mem **لا** يتطلب وحدة معالجة رسومات (GPU). تع ### الذاكرة التلقائية مقابل اليدوية -| النهج | متى يعمل | ما تفعله | -| ------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------ | -| **الالتقاط التلقائي** (`autoCaptureEnabled: true`، الافتراضي) | بعد دورات المحادثة عندما تصبح الجلسة خاملة | لا شيء — الاستخراج تلقائي | -| أداة / أوامر `memory` **اليدوية** | عند الطلب | `add`، `search`، `list`، `profile`، `forget`، `list-shards`، `migrate`، `export`، `import` | +| النهج | متى يعمل | ما تفعله | +| ------------------------------------------------------------- | ------------------------------------------ | -------------------------------------------------------------------------------------------------- | +| **الالتقاط التلقائي** (`autoCaptureEnabled: true`، الافتراضي) | بعد دورات المحادثة عندما تصبح الجلسة خاملة | لا شيء — الاستخراج تلقائي | +| أداة / أوامر `memory` **اليدوية** | عند الطلب | `add`، `search`، `list`، `profile`، `forget`، `list-shards`، `migrate`، `export`، `import`، `help` | ما زال البحث/الإضافة/القائمة اليدوية تعمل حتى لو لم يكن للالتقاط التلقائي مزود مُعَد. يحتاج الالتقاط التلقائي وتعلّم ملف المستخدم مزودًا يمكنه إرجاع مخرجات منظمة/استدعاء أدوات. @@ -205,7 +216,7 @@ opencode-mem **لا** يتطلب وحدة معالجة رسومات (GPU). تع ### واجهة الويب -افتح `http://127.0.0.1:4747` لتصفح الخط الزمني للذاكرة–المطالبات، وفحص الالتقاطات، وإدارة ملف المستخدم. إذا ربطت الخادم خارج الحلقة المحلية، انظر [مصادقة HTTP Basic لواجهة الويب](#مصادقة-http-basic-لواجهة-الويب). +افتح `http://127.0.0.1:4747` لتصفح memory–prompt timeline، وفحص الالتقاطات، وإدارة ملف المستخدم. تحتوي الواجهة على خمسة عروض: **Project memories** (`/project-memories`)، و**User profile** (`/user-profile`)، و**Skill library** (`/skill-library`)، و**Markdown vault** (`/markdown-vault`)، و**Stats** (`/stats`). غيّر المنفذ باستخدام `webServerPort`، أو اضبط `webServerEnabled: false` للتشغيل دون واجهة الويب. إذا ربطت الخادم خارج الحلقة المحلية، انظر [HTTP Basic Auth لواجهة الويب](#مصادقة-http-basic-لواجهة-الويب). ## أمثلة الاستخدام @@ -233,7 +244,21 @@ memory({ mode: "import", inputPath: "./memories.json" }); **Windows:** `%USERPROFILE%\.config\opencode\opencode-mem.jsonc` (نفس مجلد `.config\opencode` أعلاه — وليس AppData). التخزين الافتراضي يُحل إلى `%USERPROFILE%\.opencode-mem\data` (صيغة `~` تتوسع إلى منزل المستخدم على Windows أيضًا). -ينشئ المكون الإضافي قالبًا كاملًا معلَّقًا في هذا المسار عند أول تشغيل. لكل إعداد وتعليق، انظر [`opencode-mem.example.jsonc`](../../opencode-mem.example.jsonc). +ينشئ المكون الإضافي قالبًا كاملًا معلَّقًا في هذا المسار عند أول تشغيل. لكل إعداد وتعليق، انظر [`opencode-mem.example.jsonc`](../../opencode-mem.example.jsonc). + +الخيارات العليا الأكثر تعديلًا: + +| الخيار | القيمة الافتراضية | الوظيفة | +| --------------------------------------------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| `storagePath` | `"~/.opencode-mem/data"` | مكان حفظ قواعد بيانات الذاكرة. | +| `webServerEnabled` / `webServerPort` / `webServerHost` | `true` / `4747` / `"127.0.0.1"` | مفتاح تشغيل خادم واجهة الويب، والمنفذ، وعنوان الربط. | +| `autoCaptureEnabled` | `true` | تلخيص الجلسات الخاملة إلى ذكريات (يتطلب مزوّدًا، انظر [Auto-Capture AI Provider](#مزود-الذكاء-الاصطناعي-للالتقاط-التلقائي)). | +| `similarityThreshold` / `maxMemories` | `0.6` / `10` | الحد الأدنى لدرجة التشابه والحد الأقصى لعدد النتائج في البحث عن الذكريات. | +| `injectProfile` | `true` | حقن ملف المستخدم (التفضيلات، الأنماط، سير العمل) في سياق الذكاء الاصطناعي. | +| `deduplicationEnabled` / `deduplicationSimilarityThreshold` | `true` / `0.9` | اكتشاف الذكريات المكررة وإزالتها. | +| `autoCleanupEnabled` / `autoCleanupRetentionDays` | `true` / `30` | مرة واحدة يوميًا على الأكثر، حذف الذكريات التي لم تُحدَّث خلال فترة الاحتفاظ. الذكريات المثبّتة تُحفظ. | +| `showAutoCaptureToasts` / `showUserProfileToasts` / `showErrorToasts` | `true` | إشعارات منبثقة لـ auto-capture وتحديثات الملف الشخصي والأخطاء. | +| `autoUpdate` | `true` | مسح التثبيت المخزّن مؤقتًا لـ OpenCode عند توفر إصدار npm أحدث. | ### خلفية Markdown vault (`memoryBackend`) @@ -265,17 +290,35 @@ memory({ mode: "import", inputPath: "./memories.json" }); | الخيار | الافتراضي | ماذا يفعل | | ------------------------------------------------------ | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `enabled` | `true` | التقاط مطالبات المستخدم المؤلفة وحقن سياق الذاكرة. | -| `injectOn` | `"first"` | حقن سياق الذاكرة عند أول رسالة مستخدم في الجلسة، أو على `"always"` عند كل دورة مؤلفة. | +| `injectOn` | `"first"` | مع `recall: "recent"`، يتم الحقن عند أول رسالة مستخدم، أو على `"always"` عند كل دورة مؤلفة. مع `recall: "relevant"` / `"both"`، يتجدد السياق دائمًا عند كل دورة مؤلفة (issue #460). | +| `recall` | `"relevant"` | كيفية اختيار الذكريات المحقونة: `"relevant"` يُضمِّن رسالة المستخدم ويجري بحثًا متجهيًا في كل دورة؛ `"recent"` يُبقي على القائمة القديمة لأحدث N ذكرى؛ `"both"` يفضّل الذكريات ذات الصلة ثم يملأ الأماكن المتبقية بالأحدث. | +| `recallScope` | `"default"` | نطاق الاستدعاء التلقائي: `"default"` يتبع `memory.defaultScope`، أو يمكن فرض `"project"` / `"all-projects"`. عند البحث في جميع المشاريع، تحصل النتائج من المشروع الحالي على تعزيز صغير في التشابه. | +| `similarityThreshold` | (المستوى الأعلى) | حد أدنى اختياري لكل عملية حقن؛ وإلا يُستخدم `similarityThreshold` في المستوى الأعلى. | | `maxMemories` / `excludeCurrentSession` / `maxAgeDays` | `3` / `true` / — | كم ذكرى يحمل السياق المحقون، وما إذا كانت الذكريات الملتقطة في الجلسة الحالية مستبعدة، وحد عمري اختياري بالأيام. | -| `filterInjectedPrompts` | `true` | تخطي نص المطالبات المحقون من المضيف أو من مكونات OpenCode الإضافية الأخرى (تذكيرات النظام، توجيهات التنسيق، إشعارات المهام الخلفية) حتى لا يُخزَّن أبدًا كما لو كتبه المستخدم. | +| `filterInjectedPrompts` | `true` | تخطي نص المطالبات المحقون من المضيف أو من مكونات OpenCode الإضافية الأخرى (تذكيرات النظام، توجيهات التنسيق، إشعارات المهام الخلفية) حتى لا يُخزَّن أبدًا كما لو كتبه المستخدم. | | `injectionMarkers` | مدمجة | علامات إضافية لتحديد الكتل المحقونة؛ تُضاف إلى القائمة المدمجة، ولا تستبدلها أبدًا. | -| `captureChildSessions` | `false` | التقاط المطالبات من جلسات الأبناء للمنسّق (جلسات ذات `parentID`، مثل أبناء مهام/وكلاء OpenCode الفرعيين). رسائل «المستخدم» فيها يكتبها الوكيل الأب، وليس أنت، لذا افتراضيًا لا تُخزَّن ولا تُلتقط تلقائيًا ولا تُستخدم لتعلّم الملف ولا تُعطى سياق ذاكرة محقون. | +| `captureChildSessions` | `false` | التقاط المطالبات من جلسات الأبناء للمنسّق (جلسات ذات `parentID`، مثل أبناء مهام/وكلاء OpenCode الفرعيين). رسائل «المستخدم» فيها يكتبها الوكيل الأب، وليس أنت، لذا افتراضيًا لا تُخزَّن ولا تُلتقط تلقائيًا ولا تُستخدم لتعلّم الملف ولا تُعطى سياق ذاكرة محقون. | -تُطبَّق استثناءات الجلسة والعمر قبل الحد الأقصى لعدد الذكريات المحقونة، لذا لا تشغل +تُطبَّق استثناءات الجلسة والعمر قبل الحد الأقصى لعدد الذكريات المحقونة، لذا لا تشغل الذكريات المستبعدة أماكن يمكن أن تستوعب ذكريات مؤهلة. يؤدي ضبط `chatMessage.maxMemories` على `0` إلى تعطيل حقن ذكريات المشروع، مع استمرار إمكانية حقن ملف المستخدم عند تفعيله. +تُعرِّف وسوم الذكريات المحقونة `selection="recent"` أو `selection="semantic"`. +لا تحمل الاختيارات الحديثة (بما في ذلك الرجوع الاحتياطي والملء بالأحدث في `both`) +أي درجة رقمية. تحمل الاختيارات الدلالية قيمة `retrieval_score` محدودة عند توفرها؛ +وهي إشارة ترتيب قد تتضمن تعزيز المشروع الحالي، وليست احتمالًا للصلة أو للصحة +الواقعية. تُحذف الدرجات المفقودة أو غير الصالحة. يحل هذا محل سمة المطالبة السابقة +`relevance="...%"` دون تغيير اختيار الذكريات أو ترتيبها أو محتواها أو مصدرها. يحتفظ +الضغط (Compaction) بتنسيقه الحالي. + +عند فشل الاستدعاء الدلالي (مثلًا عندما يكون التضمين غير متاح)، يرجع `relevant` و +`both` إلى القائمة الحديثة الحالية بنفس قيود النطاق والعدد والجلسة والعمر. يبقى البحث +الناجح الذي لا يعثر على تطابقات مؤهلة فارغًا في `relevant`؛ بينما يستمر `both` في الملء +من الأحدث كالمعتاد. لا تؤدي تحذيرات الأجزاء الجزئية (partial-shard) إلى تفعيل الرجوع +الاحتياطي عند الفشل. إذا فشل الرجوع إلى الأحدث أيضًا، يبقى الاستدعاء فارغًا دون أن يكون +خطأً قاتلًا. يبقى سلوك الرجوع الاحتياطي عند غياب الاستعلام والتحديث في كل دورة دون تغيير. + ### Update-on-capture (اختياري) مسار اختياري لإبقاء الذكريات حديثة عند تغيّر الحقائق. عند @@ -312,7 +355,7 @@ memory({ mode: "import", inputPath: "./memories.json" }); تشغّل التضمينات البحث بالتشابه للذكريات وملف المستخدم. أعدها في نفس الملف (`~/.config/opencode/opencode-mem.jsonc`). **لا توجد خلفية MLX** — التضمينات المحلية تستخدم `@huggingface/transformers` مع ONNX، وليس Apple MLX. -**محلي (الافتراضي):** عيّن فقط `embeddingModel`. عند أول استخدام يُنزَّل النموذج من Hugging Face ويُخزَّن مؤقتًا تحت `{storagePath}/.cache` (الافتراضي `~/.opencode-mem/data/.cache`). +**محلي (الافتراضي):** عيّن فقط `embeddingModel`. عند أول استخدام يُنزَّل النموذج من Hugging Face ويُخزَّن مؤقتًا تحت `{storagePath}/.cache` (الافتراضي `~/.opencode-mem/data/.cache`). تبقى الأوزان محمّلة في الذاكرة طوال عمر العملية المضيفة؛ عيّن `embeddingIdleTimeoutMs` لتحريرها بعد ذلك العدد من أجزاء الثانية من الخمول، وستعيد عملية الذاكرة التالية تحميلها من ذاكرة التخزين المؤقت المحلية (حوالي ثانية، وليس إعادة تنزيل). **بعيد (متوافق مع OpenAI):** عيّن كلًا من `embeddingApiUrl` و`embeddingApiKey`. يستدعي المكون الإضافي حينها `{embeddingApiUrl}/embeddings` برمز Bearer. يقبل `embeddingApiKey` نفس صيغ الأسرار التي يقبلها `memoryApiKey` (`literal`، `env://…`، `file://…`). @@ -320,11 +363,12 @@ memory({ mode: "import", inputPath: "./memories.json" }); | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `embeddingModel` | معرّف Hugging Face (محلي) أو اسم نموذج API (بعيد). الافتراضي: `Xenova/nomic-embed-text-v1` | | `embeddingDimensions` | تجاوز اختياري؛ عادة احذفه — تُستمد الأبعاد من خريطة مدمجة | -| `embeddingPooling` | تجميع محلي: `"mean"` (الافتراضي)، `"cls"`، أو `"last_token"`. غير معيَّن → إعداد مسبق لنموذج معروف صغير أو `"mean"` | -| `embeddingQueryPrefix` | بادئة لتضمينات مهمة الاستعلام. غير معيَّن → إعداد مسبق للنموذج أو Nomic عندما يكون `embeddingUseTaskPrefixes` صحيحًا. `""` صريح يعطّل | +| `embeddingPooling` | تجميع محلي: `"mean"` (الافتراضي)، `"cls"`، أو `"last_token"`. غير معيَّن → إعداد مسبق لنموذج معروف صغير أو `"mean"` | +| `embeddingQueryPrefix` | بادئة لتضمينات مهمة الاستعلام. غير معيَّن → إعداد مسبق للنموذج أو Nomic عندما يكون `embeddingUseTaskPrefixes` صحيحًا. `""` صريح يعطّل | | `embeddingDocumentPrefix` | بادئة لتضمينات مهمة المستند (نفس قواعد الحل مثل `embeddingQueryPrefix`) | -| `embeddingUseTaskPrefixes` | الاشتراك الاختياري في بادئات Nomic `search_query:` / `search_document:` عندما تكون البادئات المخصصة/المسبقة غير معيَّنة. الافتراضي `false` | -| `embeddingDtype` | تجاوز اختياري لنوع بيانات ONNX المحلي (مثل `"q8"`، `"fp32"`). عند التعيين، يُمرَّر إلى transformers.js `pipeline({ dtype })` | +| `embeddingUseTaskPrefixes` | الاشتراك الاختياري في بادئات Nomic `search_query:` / `search_document:` عندما تكون البادئات المخصصة/المسبقة غير معيَّنة. الافتراضي `false` | +| `embeddingDtype` | تجاوز اختياري لنوع بيانات ONNX المحلي (مثل `"q8"`، `"fp32"`). عند التعيين، يُمرَّر إلى transformers.js `pipeline({ dtype })` | +| `embeddingIdleTimeoutMs` | تحرير النموذج المحلي بعد هذا العدد من أجزاء الثانية من الخمول (مثل `600000` لـ 10 دقائق). `0` (الافتراضي) يبقيه محمّلًا طوال عمر العملية | | `embeddingApiUrl` | عنوان URL الأساسي لـ API تضمينات متوافق مع OpenAI (بدون مسار لاحق بعد `/v1`) | | `embeddingApiKey` | مفتاح API لتلك النقطة (مطلوب مع `embeddingApiUrl`) | @@ -513,15 +557,19 @@ memory({ mode: "import", inputPath: "./memories.json" }); يصدر المكون الإضافي طلبات مخرجات منظمة إلى API جلسة opencode بدل استدعاء نقاط نهاية المزود مباشرة، لذا يملك opencode المصادقة وتحديث الرموز وتوجيه المزود. يجب أن يطابق اسم المزود إدخالًا من `opencode providers list`، ويجب أن يدعم النموذج المحدد مخرجات JSON منظمة عبر opencode. -اختياريًا ثبّت متغير استدلال للنموذج بـ `"opencodeVariant": "xhigh"` (مثلًا لـ grok-4.7). يُطبَّق على استدعاءات LLM الداخلية للمكون الإضافي (ملخصات الالتقاط التلقائي، تعلّم الملف، تنظيف الملف)، بما في ذلك عندما يكون `opencodeModel` هو `"inherit"`، حتى يمكن للعمل الخلفي استخدام مستوى استدلال مختلف عن الجلسة التفاعلية. +اختياريًا ثبّت متغير استدلال للنموذج بـ `"opencodeVariant": "xhigh"` (مثلًا لـ grok-4.7). يُطبَّق على استدعاءات LLM الداخلية للمكون الإضافي (ملخصات الالتقاط التلقائي، تعلّم الملف، تنظيف الملف)، بما في ذلك عندما يكون `opencodeModel` هو `"inherit"`، حتى يمكن للعمل الخلفي استخدام مستوى استدلال مختلف عن الجلسة التفاعلية. + +نماذج الاستدلال البطيئة (أو مطالبات الملف الكبيرة جدًا) يمكن أن تتجاوز ميزانية المخرجات المنظمة الافتراضية البالغة 90 ثانية. عيّن `"opencodeTimeoutMs"` (بالمللي ثانية) لتمديدها لاستدعاءات المخرجات المنظمة الداخلية (ملخصات الالتقاط التلقائي، تعلّم الملف) — مثلًا `"opencodeTimeoutMs": 180000` لمدة 3 دقائق. تُقيَّد القيم إلى 10000..600000؛ يبقى الافتراضي 90000. تُحوَّل السلاسل الرقمية. يستخدم تنظيف الملف مهلة منفصلة أطول. -نماذج الاستدلال البطيئة (أو مطالبات الملف الكبيرة جدًا) يمكن أن تتجاوز ميزانية المخرجات المنظمة الافتراضية البالغة 90 ثانية. عيّن `"opencodeTimeoutMs"` (بالمللي ثانية) لتمديدها لاستدعاءات المخرجات المنظمة الداخلية (ملخصات الالتقاط التلقائي، تعلّم الملف) — مثلًا `"opencodeTimeoutMs": 180000` لمدة 3 دقائق. تُقيَّد القيم إلى 10000..600000؛ يبقى الافتراضي 90000. تُحوَّل السلاسل الرقمية. يستخدم تنظيف الملف مهلة منفصلة أطول. +المزودون المدعومون: أي مزود يدرجه `opencode providers list` (مثل `anthropic`، `openai`، `github-copilot`، `openrouter`، ...). -المزودون المدعومون: أي مزود يدرجه `opencode providers list` (مثل `anthropic`، `openai`، `github-copilot`، ...). +**نماذج Free / Zen المدمجة** تحت معرّف المزود `opencode` (مثل `big-pickle`) غالبًا لا تستطيع تشغيل جلسات المخرجات المنظمة الداخلية للمكون الإضافي — قد يرفضها OpenCode خارج الدردشة التفاعلية. فضّل مزودًا مصادقًا من `opencode providers list`، أو استخدم `"opencodeModel": "inherit"` حتى يتبع الالتقاط النموذج الذي تستخدمه بالفعل في الجلسة. -إذا عُيِّن `opencodeProvider` و`opencodeModel`، يتقدمان على إعدادات `memoryProvider` اليدوية أدناه. +إذا كان `autoCaptureEnabled` هو `true` (الافتراضي) ولم يُعَد لا `opencodeProvider`/`opencodeModel` ولا رجوع يدوي كامل، يسجّل المكون الإضافي تحذيرًا ويعرض إشعارًا عند البدء (عندما يكون `showErrorToasts` مفعّلًا) حتى يكون الإعداد الناقص مرئيًا دون البحث في السجلات. -**اتبع نموذج الجلسة:** عيّن `"opencodeModel": "inherit"` لاستخدام نموذج OpenCode ملموس وقت الاستدعاء بدل معرّف مثبت. لـ **الالتقاط التلقائي**، تُسجَّل كل مطالبة عبر خطاف `chat.params` ويعيد طلب الالتقاط استخدام مزود/نموذج تلك المطالبة. لـ **تعلّم الملف** ومسارات المخرجات المنظمة الأخرى (غير المرتبطة برسالة مستخدم واحدة)، يعيد `inherit` أولاً استخدام آخر نموذج أبلغ به المضيف عبر `chat.params` / خطاف سياق V2، ثم يرجع إلى قائمة `model.json` الحديثة في OpenCode إن وُجدت (مفضّلًا `opencodeProvider` المُعَد). OpenCode v2 لم يعد يكتب `model.json`، لذا نموذج الجلسة داخل العملية هو الاحتياطي الأساسي هناك. إرسال معرّف النموذج الحرفي `inherit` غير صالح أبدًا وتسبب سابقًا في `ProviderModelNotFoundError: Model not found: /inherit` على تلك المسارات. ما زال `opencodeProvider` مطلوبًا كبوابة الإعداد العادية. +إذا عُيِّن `opencodeProvider` و`opencodeModel`، يتقدمان افتراضيًا على إعدادات `memoryProvider` اليدوية أدناه (`"autoCaptureProviderOrder": "opencode-first"`). عيّن `"autoCaptureProviderOrder": "external-first"` لتفضيل API اليدوي عند إعداد كليهما (مفيد عندما يكون API جلسة المضيف مشغولًا/بطيئًا)؛ وتُستخدم القناة الأخرى كرجوع. اخفض `"opencodeTimeoutMs"` للتحول عن قناة opencode أسرع. + +**اتبع نموذج الجلسة:** عيّن `"opencodeModel": "inherit"` لاستخدام نموذج OpenCode ملموس وقت الاستدعاء بدل معرّف مثبت. لـ **الالتقاط التلقائي**، تُسجَّل كل مطالبة عبر خطاف `chat.params` ويعيد طلب الالتقاط استخدام مزود/نموذج تلك المطالبة. لـ **تعلّم الملف** ومسارات المخرجات المنظمة الأخرى (غير المرتبطة برسالة مستخدم واحدة)، يعيد `inherit` أولاً استخدام آخر نموذج أبلغ به المضيف عبر `chat.params` / خطاف سياق V2، ثم يرجع إلى قائمة `model.json` الحديثة في OpenCode إن وُجدت (مفضّلًا `opencodeProvider` المُعَد). OpenCode v2 لم يعد يكتب `model.json`، لذا نموذج الجلسة داخل العملية هو الاحتياطي الأساسي هناك. إرسال معرّف النموذج الحرفي `inherit` غير صالح أبدًا وتسبب سابقًا في `ProviderModelNotFoundError: Model not found: /inherit` على تلك المسارات. ما زال `opencodeProvider` مطلوبًا كبوابة الإعداد العادية. **الرجوع:** إعداد API يدوي (إن لم تستخدم opencodeProvider): @@ -545,7 +593,7 @@ memory({ mode: "import", inputPath: "./memories.json" }); - `openai-chat`: API متوافق مع OpenAI Chat Completions مع استدعاء أدوات/دوال. يمكن أن يعمل مع وكلاء متوافقين مثل LiteLLM فقط عندما يحافظ النموذج العلوي والوكيل المحددان على استدعاءات الأدوات. - `openai-responses`: OpenAI Responses API مع مخرجات استدعاء دوال. - `anthropic`: Anthropic Messages API مع استخدام الأدوات. -- `minimax`: نقطة نهاية MiniMax متوافقة مع Anthropic Messages. عيّن `memoryApiUrl` إلى النقطة العالمية (`https://api.minimax.io`) أو [نقطة الصين](https://platform.minimaxi.com/docs/api-reference/text-anthropic-api.md) (`https://api.minimax.cn`)؛ يُطبَّق مسار `/anthropic/v1/messages` وترويسة `x-api-key` تلقائيًا. استخدم `MiniMax-M3.1-Flash` (موصى به) أو `MiniMax-M3`، وكلاهما بسياق 1,000,000 رمز. Flash يفكر دائمًا؛ ويمكن اختياريًا تعيين `memoryExtraParams` إلى `{ "output_config": { "effort": "max" } }` بالقيم `low` أو `medium` أو `high` أو `xhigh` أو `max` (الافتراضي). يرفض Flash تعطيل التفكير وeffort `none`، ولا يدعم `service_tier`. تفكير M3 معطّل افتراضيًا على هذه النقطة؛ فعّله بـ `{ "thinking": { "type": "adaptive" } }`. تبقى معرّفات النماذج مُعدّة صراحةً؛ وتُمرَّر المعرّفات المخصصة أو القديمة دون تغيير. راجع [مرجع توافق MiniMax](https://platform.minimax.io/docs/api-reference/text-anthropic-api.md). +- `minimax`: نقطة نهاية MiniMax متوافقة مع Anthropic Messages. عيّن `memoryApiUrl` إلى النقطة العالمية (`https://api.minimax.io`) أو [نقطة الصين](https://platform.minimaxi.com/docs/api-reference/text-anthropic-api.md) (`https://api.minimax.cn`)؛ يُطبَّق مسار `/anthropic/v1/messages` وترويسة `x-api-key` تلقائيًا. استخدم `MiniMax-M3.1-Flash` (موصى به) أو `MiniMax-M3`، وكلاهما بسياق 1,000,000 رمز. Flash يفكر دائمًا؛ ويمكن اختياريًا تعيين `memoryExtraParams` إلى `{ "output_config": { "effort": "max" } }` بالقيم `low` أو `medium` أو `high` أو `xhigh` أو `max` (الافتراضي). يرفض Flash تعطيل التفكير وeffort `none`، ولا يدعم `service_tier`. تفكير M3 معطّل افتراضيًا على هذه النقطة؛ فعّله بـ `{ "thinking": { "type": "adaptive" } }`. تبقى معرّفات النماذج مُعدّة صراحةً؛ وتُمرَّر المعرّفات المخصصة أو القديمة دون تغيير. راجع [مرجع توافق MiniMax](https://platform.minimax.io/docs/api-reference/text-anthropic-api.md). - `orcarouter`: بوابة نماذج متوافقة مع OpenAI بمعرّفات نماذج ذات مساحة أسماء. `memoryApiUrl` و`memoryModel` اختياريان — الافتراضي `https://api.orcarouter.ai/v1` و`orcarouter/auto` (اسم مستعار للتوجيه يختار نموذجًا قادرًا لكل طلب). إذا عيّنت `memoryModel`، استخدم معرّفًا ذا مساحة أسماء مثل `openai/gpt-5.5` أو `deepseek/deepseek-v4-flash`؛ يرفض OrcaRouter أسماء النماذج العارية. مثال: ```jsonc "memoryProvider": "orcarouter", @@ -586,12 +634,48 @@ memory({ mode: "import", inputPath: "./memories.json" }); استكشاف الأخطاء: - إخفاقات الالتقاط التلقائي لا تمنع استخدام أداة `memory` اليدوية. +- يحتفظ الالتقاط التلقائي بنص المساعد النهائي المحدود ونتائج الأدوات النهائية من + أحداث V1/V2 المُسلَّمة قبل تشغيل التلخيص المؤجل. ما زال الالتقاط العادي عند الخمول + يفضّل نص المحادثة الحي لدى المضيف؛ والأدلة المعلّقة الجاهزة هي الرجوع عندما تكون الجلسة + قد زالت بالفعل (الحذف أو إعادة التشغيل عند البدء). يقتصر الاسترداد على نفس المشروع + ويستخدم مزود الالتقاط العادي وطابور المطالبة. لا يستنتج العمل المكتمل + من الطلب وحده. حذف جلسة OpenCode **لا** يحذف أدلة الذاكرة + المعلّقة هذه ولا الذكريات الملتقطة بالفعل. +- تُنقَّح الأدلة المعلّقة من الوسوم الخاصة قبل الحفظ (بما في ذلك الوسوم الممتدة عبر + أجزاء النص النهائي ضمن رسالة مساعد واحدة)؛ وتُستبعد خطوات الاستدلال والمرفقات وبيانات + المزود الخام الوصفية ودلتا البث ووسائط الأدوات. الحدود هي 16 KiB لكل + جزء، و16 جزءًا لكل مطالبة، و256 جزءًا إجمالًا (4 MiB من النص كحد أقصى)، و64 KiB لكل + التقاط. يُعلَّم الاقتطاع؛ وتُطرد الأجزاء الأقدم عند تجاوز الميزانية. + تنتهي صلاحية الأدلة بعد 24 ساعة وتُشذَّب عند الوصول اللاحق إلى المخزن. وتُمسح + عند انتهاء الالتقاط/تخطيه أو عند إزالة مطالبتها عبر مسارات الحذف/الاحتفاظ + القائمة. هذه حدود احتفاظ منطقية، وليست محوًا آمنًا لنسخ SQLite/WAL الاحتياطية. +- أحداث V2 تيار متقلب: الأحداث المنقطعة/الفائتة، وربط المطالبة غير القابل للحل، + والأدلة المفقودة بالانتهاء/الطرد لا يمكن استردادها. الضمان + هو الالتقاط من الأدلة المستلمة والمحفوظة والمُعلَّمة جاهزة بنقطة تحقق عبر حدث خمول/حذف، + وليس إعادة بناء نصوص محادثة غير مرئية أو محذوفة سابقًا. بعد نقطة التحقق تلك + تُختم الجلسة ضد إعادة الربط المتأخرة حتى إدخال المستخدم المؤلَّف التالي + (V2 `session.inbox.delivered`، V1 user `message.updated`)، لذا لا يمكن للأجزاء المخزنة مؤقتًا + إعادة الأدلة الجاهزة إلى عدم الجاهزية. الانقطاع قبل نقطة التحقق النهائية + يترك الأدلة الجزئية مؤجلة حتى نقطة تحقق لاحقة؛ وإعادة التشغيل + لا تفترض أن العمل غير المنتهي مكتمل. يستخدم V1 معرّفات أصل المساعد الصريحة؛ + ويجمّد V2 الإدخال المُسلَّم عند بدء الخطوة بدل تخمين أحدث مطالبة + في الطابور. +- إذا أبلغ المضيف الحي عن `Session.NotFoundError` (أو لم يكن لدى الحذف/إعادة التشغيل عند البدء + أدلة جاهزة)، يسجّل الالتقاط `skipped` / `session_not_found`، ويحرر مطالبته + دون تراجع أو استهلاك محاولات إعادة، ويتخطى عمليات البحث المعتمدة على المضيف في تلك + الدفعة. المطالبات اللاحقة ذات الأدلة المحفوظة الجاهزة تستمر. وقد يعيد خمول مستقل لاحق + المحاولة. لا تُحيا المطالبات المستنفدة بالفعل. تحتفظ الإخفاقات الأخرى بسلوك + إعادة المحاولة الحالي. +- تستخدم إضافات الالتقاط التلقائي معرّفًا ثابتًا لكل مشروع/مطالبة حتى تعيد إعادة التشغيل + المتتالية بعد الانهيار استخدام الذاكرة السابقة، بما في ذلك السجلات المحذوفة حذفًا ناعمًا، بدل إدراجها أو + إحيائها. هذا لا يدّعي دلالات "مرة واحدة بالضبط" الموزعة لعمليات التحديث/الاستبدال + الدلالية الاختيارية أو لكل تداخل انهيار متعدد العمليات. - إذا أبلغ الالتقاط التلقائي أن مزودًا غير متصل، أكّد اسم المزود بـ `opencode providers list` وأعد ذلك المزود في opencode أولًا. - إذا أعاد وكيل أو مزود مخصص نصًا عاديًا بدل مخرجات منظمة/أدوات، اختر نموذجًا/مزودًا آخر أو استخدم أحد أوضاع المزود اليدوية أعلاه. - للنماذج التي ترفض `temperature`، أضف `"memoryTemperature": false` عند استخدام إعداد API اليدوي. - للنماذج التي ترفض استدعاءات الأدوات المفروضة (`tool_choice: "required"`، مثل بعض أوضاع التفكير)، أضف `"forceToolChoice": false` عند استخدام `openai-chat` / `orcarouter` / `atlas-cloud` / `cheaper-inference` / `api-route` / `runcrate` / `cloudgpu`. - لـ `opencodeProvider` / `opencodeModel` (مثل DeepSeek V4 thinking)، ما زال OpenCode يرسل `tool_choice` مفروضًا للمخرجات المنظمة. يعطّل opencode-mem التفكير على الوكيل الداخلي `opencode-mem-structured` (ويعيده في `chat.params` بعد دمج المتغير) حتى يكتمل الالتقاط التلقائي وتعلّم الملف. وكيل الدردشة التفاعلي لديك دون تغيير. إذا فشل الالتقاط ما زال بخطأ تفكير/`tool_choice`، اختر نموذجًا غير تفكير لـ `opencodeModel` أو أعد رجوعًا يدويًا كاملًا (`memoryModel` + `memoryApiUrl`). -- **`opencode-claude-auth` / Claude Code:** يستخدم الالتقاط التلقائي OpenCode مع مزودك `anthropic` المصادق. غالبًا ما يتكرر `format: json_schema` المفروض مع Claude-auth، لذا يستخدم opencode-mem مسار **نص-JSON** يحافظ على المصادقة لـ `opencodeProvider: "anthropic"` (بدون أدوات `StructuredOutput` مفروضة؛ تُحلَّل الرد بـ Zod). ما زال مراقب الخطوات يجهض الجلسات الداخلية الجامحة بعد خطوتين. إذا فشل الالتقاط ما زال، أعد رجوع Anthropic بمفتاح API يدوي كامل (`memoryProvider: "anthropic"` + `memoryModel` + `memoryApiUrl` + `memoryApiKey`) — لا يمكن إعادة استخدام Claude Pro/Max OAuth خارج OpenCode. +- **`opencode-claude-auth` / Claude Code:** يستخدم الالتقاط التلقائي OpenCode مع مزودك `anthropic` المصادق. غالبًا ما يتكرر `format: json_schema` المفروض مع Claude-auth، لذا يستخدم opencode-mem مسار **نص-JSON** يحافظ على المصادقة لـ `opencodeProvider: "anthropic"` (بدون أدوات `StructuredOutput` مفروضة؛ تُحلَّل الرد بـ Zod). ما زال مراقب الخطوات يجهض الجلسات الداخلية الجامحة بعد خطوتين. إذا فشل الالتقاط ما زال، أعد رجوع Anthropic بمفتاح API يدوي كامل (`memoryProvider: "anthropic"` + `memoryModel` + `memoryApiUrl` + `memoryApiKey`) — لا يمكن إعادة استخدام Claude Pro/Max OAuth خارج OpenCode. - **المنصات غير المدعومة:** Intel Mac (`darwin/x64`) غير مدعوم — `@tursodatabase/database` وإصدارات `onnxruntime-node` الثابتة (المثبّت `1.31.1`) لا توفّر ربطًا أصليًا لـ x64. استخدم Apple Silicon أو Linux أو Windows، أو نقطة نهاية تضمين بعيدة عبر `embeddingApiUrl` + `embeddingApiKey`. MLX غير مدعوم. ## صادرات المسارات الفرعية العامة @@ -634,10 +718,14 @@ const { user, project } = getTags(process.cwd()); ```bash bun install bun run build -bun run typecheck -bun run format +bun test +bun run check ``` +يشغّل `bun run check` كلًا من `format:check` و`lint` و`typecheck`؛ ويعيد `bun run format` كتابة التنسيق. + +يتم توليد [الموقع](https://opencode-mem.zhafron.my.id) و[توثيقه](https://opencode-mem.zhafron.my.id/docs/) من هذا README والترجمات ضمن `.github/i18n/`. يجب ربط كل عنوان في README بصفحة توثيق في `site/docs-map.json`، وإلا فسيفشل بناء الموقع. ابنِ الموقع محليًا باستخدام `cd site && bun install && bun run build`. + يسعى هذا المشروع بنشاط للمساهمات ليصبح المكون الإضافي النهائي للذاكرة لوكلاء البرمجة بالذكاء الاصطناعي. سواء كنت تصلح أخطاء، أو تضيف ميزات، أو تحسّن التوثيق، أو توسّع دعم نماذج التضمين، مساهماتك حاسمة. قاعدة الشيفرة منظمة جيدًا وجاهزة للتحسين. افتح القضايا بقوالب Issue أو Feature request، واملأ قالب طلب السحب عند إرسال PR — نراجع وندمج المساهمات بسرعة. **ترجمات README:** `README.md` (الإنجليزية) هو المصدر المعتمد. عند تغيير محتواه، حدّث الملفات ضمن `.github/i18n/` (`README.de.md` و`README.zh.md` و`README.ar.md` و`README.tr.md` و`README.nl.md`) لتطابقها. @@ -646,8 +734,11 @@ bun run format رخصة MIT - انظر ملف LICENSE +- **الموقع الإلكتروني**: https://opencode-mem.zhafron.my.id +- **التوثيق**: https://opencode-mem.zhafron.my.id/docs/ - **المستودع**: https://github.com/tickernelz/opencode-mem - **القضايا**: https://github.com/tickernelz/opencode-mem/issues +- **npm**: https://www.npmjs.com/package/opencode-mem - **منصة OpenCode**: https://opencode.ai مستوحى من [opencode-supermemory](https://github.com/supermemoryai/opencode-supermemory) diff --git a/.github/i18n/README.de.md b/.github/i18n/README.de.md index 46a3b7be..355f0b6b 100644 --- a/.github/i18n/README.de.md +++ b/.github/i18n/README.de.md @@ -4,6 +4,8 @@ [![npm downloads](https://img.shields.io/npm/dm/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![license](https://img.shields.io/npm/l/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![GitHub stars](https://img.shields.io/github/stars/tickernelz/opencode-mem.svg)](https://github.com/tickernelz/opencode-mem) +[![Website](https://img.shields.io/badge/website-opencode--mem.zhafron.my.id-blue)](https://opencode-mem.zhafron.my.id) +[![Docs](https://img.shields.io/badge/docs-opencode--mem.zhafron.my.id%2Fdocs-blue)](https://opencode-mem.zhafron.my.id/docs/) ![OpenCode Memory Banner](../pics/banner.png) @@ -13,7 +15,16 @@ Ein persistentes Speichersystem für KI-Coding-Agenten, das langfristige Kontext ## Kernfunktionen -Lokale Turso/libSQL-Datenbank mit nativer Vektorsuche, persistente Projektspeicher, automatisches Lernen des Benutzerprofils, einheitliche Speicher-Prompt-Timeline, vollständige Web-UI, intelligente promptbasierte Speicherextraktion, Multi-Provider-KI-Unterstützung (OpenAI, Anthropic), 12+ lokale Embedding-Modelle, smarte Deduplizierung und integrierter Datenschutz. +- **Lokale Datenbank:** eingebettete Turso/libSQL-Datenbank mit nativer Vektorsuche, gespeichert unter `storagePath`. Keine separate Vektordatenbank. +- **Intelligente promptbasierte Speicherextraktion (auto-capture):** Wenn eine Sitzung inaktiv wird, wandelt eine KI-Anfrage im Hintergrund die technische Arbeit in persistente Projektspeicher um. +- **Automatischer Abruf:** Relevante Speicher und das Benutzerprofil werden in den Kontext des Modells eingefügt (`chatMessage`). +- **Automatisches Lernen des Benutzerprofils:** eine projektübergreifende Zusammenfassung Ihrer Vorlieben, Muster und Workflows. +- **Speicherpflege:** smarte Deduplizierung, optionales update-on-capture und optionale dreaming-Konsolidierung mit wiederherstellbarem Papierkorb. +- **Multi-Provider-KI-Unterstützung:** jeder in OpenCode konfigurierte Provider (`opencodeProvider` / `opencodeModel`) oder eine manuelle API: OpenAI Chat Completions, OpenAI Responses, Anthropic, MiniMax, OrcaRouter, Atlas Cloud, Cheaper Inference, API Route, Runcrate, CloudGPU. +- **Embeddings:** 12+ lokale Embedding-Modelle auf der CPU (keine GPU erforderlich) oder jede OpenAI-kompatible Embeddings-API. +- **Vollständige Web-UI:** einheitliche memory–prompt timeline, Benutzerprofil, Skill-Bibliothek, Markdown vault und Statistiken zum Systemzustand, mit optionaler HTTP Basic Auth. +- **Integrierter Datenschutz:** ``-Tags, Schwärzung von Zugangsdaten vor der Erfassung und optionale Verschlüsselung im Ruhezustand. +- **Portabilität:** optionales Markdown vault-Backend sowie `export` / `import` / `migrate` des `memory`-Tools für verschobene oder kopierte Projekte. ## Voraussetzungen @@ -138,7 +149,7 @@ AES-256-GCM-Verschlüsselung für lokale Turso-Shards in `~/.config/opencode/ope } ``` -Beim ersten Start erstellt das Plugin `~/.config/opencode/opencode-mem-db.key` (32-Byte-Hex-Key, `chmod 600`) und migriert vorhandene Klartext-Shards. Überschreiben mit `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` oder `"file://~/path/to.key"`, wenn du den Key selbst verwaltest. Ohne den Key lassen sich die verschlüsselten Datenbanken nicht öffnen. +Beim ersten Start erstellt das Plugin `~/.config/opencode/opencode-mem-db.key` (32-Byte-Hex-Key, `chmod 600`) und migriert vorhandene Klartext-Shards. Überschreiben mit `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` oder `"file://~/path/to.key"`, wenn du den Key selbst verwaltest. Ohne den Key lassen sich die verschlüsselten Datenbanken nicht öffnen. `databaseEncryptionCipher` wählt die Cipher aus: `aes256gcm` (Standard), `aes128gcm`, `aegis256`, `aegis256x2`, `aegis128l`, `aegis128x2` oder `aegis128x4`. **Windows:** `%USERPROFILE%\.config\opencode\opencode.json` verwenden (z. B. `C:\Users\\.config\opencode\opencode.json`). Dieses Plugin liest **nicht** `%APPDATA%` oder `%LOCALAPPDATA%` für seinen OpenCode-Plugin-Eintrag — die Datei unter `.config\opencode` im User-Profil ablegen und OpenCode neu starten. Erscheint das Plugin nicht, den Pfad prüfen und erneut neu starten. @@ -158,10 +169,10 @@ Du musst OpenCode **nicht** bitten, Dinge zu „merken“, damit das Plugin funk ### Automatischer vs. manueller Speicher -| Ansatz | Wann er läuft | Was du tust | -| ------------------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------ | -| **Auto-Capture** (`autoCaptureEnabled: true`, Standard) | Nach Gesprächsrunden, wenn die Sitzung idle wird | Nichts — die Extraktion ist automatisch | -| **Manuell** `memory`-Tool / Befehle | Auf Abruf | `add`, `search`, `list`, `profile`, `forget`, `list-shards`, `migrate`, `export`, `import` | +| Ansatz | Wann er läuft | Was du tust | +| ------------------------------------------------------- | ------------------------------------------------ | -------------------------------------------------------------------------------------------------- | +| **Auto-Capture** (`autoCaptureEnabled: true`, Standard) | Nach Gesprächsrunden, wenn die Sitzung idle wird | Nichts — die Extraktion ist automatisch | +| **Manuell** `memory`-Tool / Befehle | Auf Abruf | `add`, `search`, `list`, `profile`, `forget`, `list-shards`, `migrate`, `export`, `import`, `help` | Manuelle Suche/Hinzufügen/Listen funktionieren auch, wenn für Auto-Capture kein Provider konfiguriert ist. Auto-Capture und Lernen des Benutzerprofils brauchen einen Provider, der strukturierte/Tool-Call-Ausgabe liefern kann. @@ -205,7 +216,7 @@ Wenn du eine Weile gechattet hast und die Meldung weiterhin siehst, prüfe in de ### Web-UI -Öffne `http://127.0.0.1:4747`, um die Speicher–Prompt-Timeline zu browsen, Captures zu prüfen und das Benutzerprofil zu verwalten. Bindest du den Server über Loopback hinaus, siehe [Web-UI HTTP Basic Auth](#web-ui-http-basic-auth). +Öffne `http://127.0.0.1:4747`, um die memory–prompt timeline zu browsen, Captures zu prüfen und das Benutzerprofil zu verwalten. Die UI hat fünf Ansichten: **Project memories** (`/project-memories`), **User profile** (`/user-profile`), **Skill library** (`/skill-library`), **Markdown vault** (`/markdown-vault`) und **Stats** (`/stats`). Ändere den Port mit `webServerPort`, oder setze `webServerEnabled: false`, um ohne die Web-UI zu arbeiten. Bindest du den Server über Loopback hinaus, siehe [Web-UI HTTP Basic Auth](#web-ui-http-basic-auth). ## Verwendungsbeispiele @@ -235,6 +246,20 @@ Konfiguration unter `~/.config/opencode/opencode-mem.jsonc`: Das Plugin legt beim ersten Start eine voll kommentierte Vorlage unter diesem Pfad an. Für jede Einstellung und jeden Kommentar siehe [`opencode-mem.example.jsonc`](../../opencode-mem.example.jsonc). +Häufig angepasste Top-Level-Optionen: + +| Option | Standard | Funktion | +| --------------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| `storagePath` | `"~/.opencode-mem/data"` | Speicherort der Memory-Datenbanken. | +| `webServerEnabled` / `webServerPort` / `webServerHost` | `true` / `4747` / `"127.0.0.1"` | Schalter, Port und Bind-Adresse des Web-UI-Servers. | +| `autoCaptureEnabled` | `true` | Fasst inaktive Sessions zu Memories zusammen (benötigt einen Provider, siehe [Auto-Capture AI Provider](#auto-capture-ki-provider)). | +| `similarityThreshold` / `maxMemories` | `0.6` / `10` | Minimaler Ähnlichkeitswert und maximale Anzahl an Ergebnissen für die Memory-Suche. | +| `injectProfile` | `true` | Fügt das User profile (Präferenzen, Muster, Workflows) in den KI-Kontext ein. | +| `deduplicationEnabled` / `deduplicationSimilarityThreshold` | `true` / `0.9` | Erkennt und entfernt doppelte Memories. | +| `autoCleanupEnabled` / `autoCleanupRetentionDays` | `true` / `30` | Löscht höchstens einmal täglich Memories, die innerhalb des Aufbewahrungszeitraums nicht aktualisiert wurden. Angepinnte Memories bleiben erhalten. | +| `showAutoCaptureToasts` / `showUserProfileToasts` / `showErrorToasts` | `true` | Toasts für auto-capture, Profil-Updates und Fehler. | +| `autoUpdate` | `true` | Leert die zwischengespeicherte Installation von OpenCode, wenn ein neueres npm-Release verfügbar ist. | + ### Markdown-Vault-Backend (`memoryBackend`) Standardmäßig liegen Memories nur in Turso unter `storagePath`. Optional kannst du einen **generischen Markdown-Ordner** als Source of Truth setzen (Obsidian-/Raneto-kompatible reine `.md`-Dateien — keine Obsidian-spezifische Integration): @@ -268,6 +293,7 @@ Diese Einstellungen liegen unter dem Schlüssel `chatMessage` in `~/.config/open | `injectOn` | `"first"` | Bei `recall: "recent"`: Kontext bei der ersten User-Nachricht oder bei `"always"` jedem Turn. Bei `recall: "relevant"` / `"both"` wird der Kontext bei jedem verfassten Turn neu geladen (Issue #460). | | `recall` | `"relevant"` | Auswahl injizierter Memories: `"relevant"` bettet die User-Nachricht ein und sucht per Vektor (jeder Turn); `"recent"` behält die Legacy-Newest-N-Liste; `"both"` bevorzugt relevant und füllt mit recent auf. | | `recallScope` | `"default"` | Scope für Auto-Recall: `"default"` folgt `memory.defaultScope`, oder `"project"` / `"all-projects"`. Bei All-Projects erhalten Treffer aus dem aktuellen Projekt einen kleinen Similarity-Boost. | +| `similarityThreshold` | (Top-Level) | Optionale Untergrenze pro Injection; sonst wird das Top-Level-`similarityThreshold` verwendet. | | `maxMemories` / `excludeCurrentSession` / `maxAgeDays` | `3` / `true` / — | Wie viele Memories der injizierte Kontext hält, ob Memories aus der aktuellen Sitzung ausgeschlossen werden, und optionaler Alters-Cutoff in Tagen. | | `filterInjectedPrompts` | `true` | Prompt-Text überspringen, der vom Host oder anderen OpenCode-Plugins injiziert wurde (System-Reminders, Orchestrierungsanweisungen, Background-Task-Benachrichtigungen), damit er nie so gespeichert wird, als hätte ihn der User getippt. | | `injectionMarkers` | Built-ins | Zusätzliche Marker zur Erkennung injizierter Blöcke; werden zur Built-in-Liste hinzugefügt, ersetzen sie nie. | @@ -279,6 +305,23 @@ Memories verfügbar wären. Mit `chatMessage.maxMemories` auf `0` wird die Injek von Projekt-Memories deaktiviert; das Nutzerprofil kann weiterhin injiziert werden, wenn es aktiviert ist. +Injizierte Memory-Tags kennzeichnen `selection="recent"` oder `selection="semantic"`. +Recent-Auswahlen (einschließlich Fallback und Recent-Auffüllung bei `both`) haben keinen +numerischen Score. Semantic-Auswahlen tragen, sofern verfügbar, einen endlichen `retrieval_score`; +dies ist ein Ranking-Signal, das den Boost für das aktuelle Projekt enthalten kann, keine +Wahrscheinlichkeit für Relevanz oder sachliche Richtigkeit. Fehlende oder ungültige Scores +werden weggelassen. Dies ersetzt das frühere Prompt-Attribut `relevance="...%"`, ohne +Auswahl, Reihenfolge, Inhalt oder Herkunft der Memories zu ändern. Compaction behält ihr +bisheriges Format. + +Wenn semantischer Recall fehlschlägt (z. B. weil Embedding nicht verfügbar ist), fallen +`relevant` und `both` auf die bestehende Recent-Liste zurück, mit denselben Einschränkungen +für Scope, Anzahl, Sitzung und Alter. Eine erfolgreiche Suche ohne geeignete Treffer bleibt +bei `relevant` leer; `both` füllt wie gewohnt mit recent auf. Warnungen zu Partial-Shards +lösen keinen Fehler-Fallback aus. Schlägt auch der Recent-Fallback fehl, bleibt der Recall +leer und nicht fatal. Das Fallback-Verhalten bei fehlender Query und das Neuladen pro Turn +bleiben unverändert. + ### Update-on-capture (optional) Opt-in-Pfad, der Memories aktuell hält, wenn sich Fakten ändern. Bei @@ -314,21 +357,22 @@ nach `dreaming.trashRetentionDays` beim Cleanup hart bereinigt. Embeddings treiben die Ähnlichkeitssuche für Memories und das Benutzerprofil. Konfiguration in derselben Datei (`~/.config/opencode/opencode-mem.jsonc`). Es gibt **kein MLX-Backend** — lokale Embeddings nutzen `@huggingface/transformers` mit ONNX, nicht Apple MLX. -**Lokal (Standard):** nur `embeddingModel` setzen. Beim ersten Einsatz wird das Modell von Hugging Face heruntergeladen und unter `{storagePath}/.cache` zwischengespeichert (Standard `~/.opencode-mem/data/.cache`). +**Lokal (Standard):** nur `embeddingModel` setzen. Beim ersten Einsatz wird das Modell von Hugging Face heruntergeladen und unter `{storagePath}/.cache` zwischengespeichert (Standard `~/.opencode-mem/data/.cache`). Die Gewichte bleiben für die Lebensdauer des Host-Prozesses im Speicher; `embeddingIdleTimeoutMs` setzen, um sie nach so vielen Millisekunden Leerlauf freizugeben. Die nächste Memory-Operation lädt sie dann wieder aus dem lokalen Cache (etwa eine Sekunde, kein erneuter Download). **Remote (OpenAI-kompatibel):** sowohl `embeddingApiUrl` als auch `embeddingApiKey` setzen. Das Plugin ruft dann `{embeddingApiUrl}/embeddings` mit Bearer-Token auf. `embeddingApiKey` akzeptiert dieselben Secret-Formate wie `memoryApiKey` (`literal`, `env://…`, `file://…`). -| Schlüssel | Rolle | -| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| `embeddingModel` | Hugging-Face-ID (lokal) oder API-Modellname (remote). Standard: `Xenova/nomic-embed-text-v1` | -| `embeddingDimensions` | Optionaler Override; meist weglassen — Dimensionen werden aus einer Built-in-Map nachgeschlagen | -| `embeddingPooling` | Lokales Pooling: `"mean"` (Standard), `"cls"` oder `"last_token"`. Ungesetzt → kleines Known-Model-Preset oder `"mean"` | -| `embeddingQueryPrefix` | Präfix für Query-Task-Embeddings. Ungesetzt → Modell-Preset oder Nomic, wenn `embeddingUseTaskPrefixes` true ist. Explizites `""` deaktiviert | -| `embeddingDocumentPrefix` | Präfix für Document-Task-Embeddings (gleiche Auflösungsregeln wie `embeddingQueryPrefix`) | -| `embeddingUseTaskPrefixes` | Opt-in für Nomic-Präfixe `search_query:` / `search_document:`, wenn Custom-/Preset-Präfixe nicht gesetzt sind. Standard `false` | -| `embeddingDtype` | Optionaler lokaler ONNX-Dtype-Override (z. B. `"q8"`, `"fp32"`). Wenn gesetzt, an transformers.js `pipeline({ dtype })` übergeben | -| `embeddingApiUrl` | Basis-URL für eine OpenAI-kompatible Embeddings-API (kein trailing Path über `/v1` hinaus) | -| `embeddingApiKey` | API-Key für diesen Endpoint (zusammen mit `embeddingApiUrl` erforderlich) | +| Schlüssel | Rolle | +| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `embeddingModel` | Hugging-Face-ID (lokal) oder API-Modellname (remote). Standard: `Xenova/nomic-embed-text-v1` | +| `embeddingDimensions` | Optionaler Override; meist weglassen — Dimensionen werden aus einer Built-in-Map nachgeschlagen | +| `embeddingPooling` | Lokales Pooling: `"mean"` (Standard), `"cls"` oder `"last_token"`. Ungesetzt → kleines Known-Model-Preset oder `"mean"` | +| `embeddingQueryPrefix` | Präfix für Query-Task-Embeddings. Ungesetzt → Modell-Preset oder Nomic, wenn `embeddingUseTaskPrefixes` true ist. Explizites `""` deaktiviert | +| `embeddingDocumentPrefix` | Präfix für Document-Task-Embeddings (gleiche Auflösungsregeln wie `embeddingQueryPrefix`) | +| `embeddingUseTaskPrefixes` | Opt-in für Nomic-Präfixe `search_query:` / `search_document:`, wenn Custom-/Preset-Präfixe nicht gesetzt sind. Standard `false` | +| `embeddingDtype` | Optionaler lokaler ONNX-Dtype-Override (z. B. `"q8"`, `"fp32"`). Wenn gesetzt, an transformers.js `pipeline({ dtype })` übergeben | +| `embeddingIdleTimeoutMs` | Lokales Modell nach so vielen Millisekunden Leerlauf freigeben (z. B. `600000` für 10 Minuten). `0` (Standard) hält es für die Prozesslebensdauer geladen | +| `embeddingApiUrl` | Basis-URL für eine OpenAI-kompatible Embeddings-API (kein trailing Path über `/v1` hinaus) | +| `embeddingApiKey` | API-Key für diesen Endpoint (zusammen mit `embeddingApiUrl` erforderlich) | Empfohlene lokale Modelle: @@ -519,9 +563,13 @@ Optional eine Reasoning-Variante des Modells mit `"opencodeVariant": "xhigh"` pi Langsame Reasoning-Modelle (oder sehr große Profil-Prompts) können das Standard-Budget von 90 s für strukturierte Ausgabe überschreiten. `"opencodeTimeoutMs"` (Millisekunden) setzen, um es für interne Structured-Output-Aufrufe (Auto-Capture-Zusammenfassungen, Profil-Lernen) zu verlängern — z. B. `"opencodeTimeoutMs": 180000` für 3 Minuten. Werte werden auf 10000..600000 geklemmt; der Standard bleibt 90000. Numerische Strings werden coerced. Profil-Cleanup nutzt ein separates, längeres Timeout. -Unterstützte Provider: jeder von `opencode providers list` gelistete Provider (z. B. `anthropic`, `openai`, `github-copilot`, ...). +Unterstützte Provider: jeder von `opencode providers list` gelistete Provider (z. B. `anthropic`, `openai`, `github-copilot`, `openrouter`, ...). + +**Eingebaute Free-/Zen-Modelle** unter der Provider-ID `opencode` (z. B. `big-pickle`) können die internen Structured-Output-Sitzungen des Plugins oft nicht ausführen — OpenCode lehnt sie außerhalb des interaktiven Chats möglicherweise ab. Besser einen authentifizierten Provider aus `opencode providers list` verwenden oder `"opencodeModel": "inherit"` nutzen, damit Capture dem Modell folgt, das du in der Sitzung bereits verwendest. -Wenn `opencodeProvider` und `opencodeModel` gesetzt sind, haben sie Vorrang vor den manuellen `memoryProvider`-Einstellungen unten. +Ist `autoCaptureEnabled` `true` (Standard), aber weder `opencodeProvider`/`opencodeModel` noch ein vollständiger manueller Fallback konfiguriert, loggt das Plugin eine Warnung und zeigt beim Start einen Toast (wenn `showErrorToasts` aktiviert ist), sodass fehlende Konfiguration sichtbar ist, ohne Logs durchsuchen zu müssen. + +Wenn `opencodeProvider` und `opencodeModel` gesetzt sind, haben sie standardmäßig Vorrang vor den manuellen `memoryProvider`-Einstellungen unten (`"autoCaptureProviderOrder": "opencode-first"`). `"autoCaptureProviderOrder": "external-first"` setzen, um die manuelle API zu bevorzugen, wenn beide konfiguriert sind (nützlich, wenn die Session-API des Hosts ausgelastet/langsam ist); der andere Kanal dient als Fallback. `"opencodeTimeoutMs"` senken, um früher vom opencode-Kanal auf den Fallback umzuschalten. **Sitzungsmodell folgen:** `"opencodeModel": "inherit"` setzen, um zur Aufrufzeit ein konkretes OpenCode-Modell statt einer gepinnten ID zu nutzen. Für **Auto-Capture** wird jeder Prompt über den `chat.params`-Hook aufgezeichnet und der Capture-Request wiederverwendet Provider/Modell dieses Prompts. Für **Profil-Lernen** und andere Structured-Output-Pfade (die nicht an eine einzelne User-Nachricht gebunden sind) nutzt `inherit` zuerst das zuletzt vom Host über `chat.params` / den V2-Context-Hook gemeldete Modell und fällt danach auf die Recent-Liste in OpenCodes `model.json` zurück, falls vorhanden (bevorzugt den konfigurierten `opencodeProvider`). OpenCode v2 schreibt `model.json` nicht mehr; dort ist das In-Process-Sitzungsmodell der primäre Fallback. Das wörtliche Modell-ID `inherit` zu senden ist nie gültig und verursachte zuvor `ProviderModelNotFoundError: Model not found: /inherit` auf diesen Pfaden. `opencodeProvider` bleibt als normale Config-Gate erforderlich. @@ -588,6 +636,42 @@ Manuelle `memoryProvider`-Modi: Fehlerbehebung: - Auto-Capture-Fehler blockieren die manuelle Nutzung des `memory`-Tools nicht. +- Auto-Capture bewahrt begrenzten finalen Assistant-Text und terminale Tool-Ergebnisse aus + zugestellten V1/V2-Events, bevor die verzögerte Zusammenfassung läuft. Normales Idle-Capture + bevorzugt weiterhin das Live-Transkript des Hosts; bereite ausstehende Evidenz ist der Fallback, + wenn die Sitzung bereits weg ist (Löschung oder Startup-Replay). Die Wiederherstellung ist auf + dasselbe Projekt beschränkt und nutzt den normalen Capture-Provider und die Claim-Queue. Sie + leitet abgeschlossene Arbeit nicht allein aus der Anfrage ab. Das Löschen einer OpenCode-Sitzung + löscht diese ausstehende Memory-Evidenz oder bereits erfasste Memories **nicht**. +- Ausstehende Evidenz wird vor der Persistierung um Private-Tags bereinigt (einschließlich Tags, + die finale Textteile innerhalb einer Assistant-Nachricht überspannen); Reasoning, Anhänge, rohe + Provider-Metadaten, Streaming-Deltas und Tool-Argumente sind ausgeschlossen. Limits sind 16 KiB + pro Part, 16 Parts pro Prompt, 256 Parts global (höchstens 4 MiB Text) und 64 KiB pro Capture. + Kürzungen werden markiert; die ältesten Parts werden verdrängt, wenn das Budget überschritten + wird. Evidenz läuft nach 24 Stunden ab und wird beim nächsten Store-Zugriff bereinigt. Sie wird + gelöscht, wenn Capture abschließt/überspringt oder ihr Prompt über bestehende Lösch-/Retention-Pfade + entfernt wird. Dies sind logische Aufbewahrungslimits, keine sichere Löschung von SQLite-/WAL-Backups. +- V2-Events sind ein flüchtiger Stream: getrennte/verpasste Events, nicht auflösbare Prompt-Zuordnung + und durch Ablauf/Verdrängung verlorene Evidenz können nicht wiederhergestellt werden. Garantiert + ist Capture aus Evidenz, die empfangen, gespeichert und durch ein Idle-/Deleted-Event als bereit + gecheckpointet wurde, nicht die Rekonstruktion ungesehener oder zuvor gelöschter Transkripte. Nach + diesem Checkpoint ist die Sitzung gegen späte Rebinds versiegelt, bis zur nächsten verfassten + User-Eingabe (V2 `session.inbox.delivered`, V1 User-`message.updated`), sodass gepufferte Parts + bereite Evidenz nicht wieder auf nicht bereit zurücksetzen können. Ein Disconnect vor dem terminalen + Checkpoint lässt die partielle Evidenz bis zu einem späteren Checkpoint zurückgestellt; ein Neustart + nimmt nicht an, dass unfertige Arbeit abgeschlossen ist. V1 nutzt explizite Assistant-Parent-IDs; + V2 friert die zugestellte Eingabe beim Step-Start ein, statt den zuletzt eingereihten Prompt zu raten. +- Meldet der Live-Host `Session.NotFoundError` (oder hat Löschung/Startup-Replay keine bereite + Evidenz), loggt Capture `skipped` / `session_not_found`, gibt seinen Claim ohne Backoff und ohne + Verbrauch von Retries frei und überspringt weitere hostabhängige Lookups in diesem Batch. Spätere + Prompts mit bereiter gespeicherter Evidenz laufen weiterhin. Ein späteres unabhängiges Idle kann + es erneut versuchen. Bereits erschöpfte Prompts werden nicht wiederbelebt. Andere Fehler behalten + ihr bestehendes Retry-Verhalten. +- Auto-Capture-Ergänzungen nutzen eine stabile ID pro Projekt/Prompt, sodass sequenzielles + Crash-/Restart-Replay das vorherige Memory wiederverwendet, einschließlich soft-gelöschter + Einträge, statt es einzufügen oder wiederzubeleben. Dies beansprucht keine verteilte + Exactly-Once-Semantik für optionale semantische Update-/Supersede-Operationen oder jede + Multi-Prozess-Crash-Verschränkung. - Meldet Auto-Capture, dass ein Provider nicht verbunden ist, den Provider-Namen mit `opencode providers list` bestätigen und diesen Provider zuerst in opencode konfigurieren. - Gibt ein Proxy oder Custom-Provider Klartext statt strukturierter/Tool-Ausgabe zurück, ein anderes Modell/einen anderen Provider wählen oder einen der manuellen Provider-Modi oben nutzen. - Für Modelle, die `temperature` ablehnen, bei manueller API-Konfiguration `"memoryTemperature": false` hinzufügen. @@ -636,10 +720,14 @@ Lokal bauen und testen: ```bash bun install bun run build -bun run typecheck -bun run format +bun test +bun run check ``` +`bun run check` führt `format:check`, `lint` und `typecheck` aus; `bun run format` schreibt die Formatierung neu. + +Die [Website](https://opencode-mem.zhafron.my.id) und ihre [Dokumentation](https://opencode-mem.zhafron.my.id/docs/) werden aus dieser README und den Übersetzungen unter `.github/i18n/` generiert. Jede README-Überschrift muss in `site/docs-map.json` einer Docs-Seite zugeordnet sein, sonst schlägt der Site-Build fehl. Baue die Site lokal mit `cd site && bun install && bun run build`. + Dieses Projekt sucht aktiv Beiträge, um das maßgebliche Memory-Plugin für KI-Coding-Agenten zu werden. Ob du Bugs behebst, Features hinzufügst, Dokumentation verbesserst oder die Embedding-Modell-Unterstützung erweiterst — deine Beiträge sind entscheidend. Die Codebasis ist gut strukturiert und bereit für Erweiterungen. Bitte Issues mit den Vorlagen Issue oder Feature request öffnen und beim Einreichen eines PRs die Pull-Request-Vorlage ausfüllen — wir reviewen und mergen Beiträge zügig. **README-Übersetzungen:** `README.md` (Englisch) ist die Quelle der Wahrheit. Wenn du dessen Inhalt änderst, aktualisiere die Dateien unter `.github/i18n/` (`README.de.md`, `README.zh.md`, `README.ar.md`, `README.tr.md` und `README.nl.md`) entsprechend. @@ -648,8 +736,11 @@ Dieses Projekt sucht aktiv Beiträge, um das maßgebliche Memory-Plugin für KI- MIT License - siehe LICENSE-Datei +- **Website**: https://opencode-mem.zhafron.my.id +- **Dokumentation**: https://opencode-mem.zhafron.my.id/docs/ - **Repository**: https://github.com/tickernelz/opencode-mem - **Issues**: https://github.com/tickernelz/opencode-mem/issues +- **npm**: https://www.npmjs.com/package/opencode-mem - **OpenCode Platform**: https://opencode.ai Inspiriert von [opencode-supermemory](https://github.com/supermemoryai/opencode-supermemory) diff --git a/.github/i18n/README.nl.md b/.github/i18n/README.nl.md index d18ed1ec..8e3ea007 100644 --- a/.github/i18n/README.nl.md +++ b/.github/i18n/README.nl.md @@ -4,6 +4,8 @@ [![npm downloads](https://img.shields.io/npm/dm/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![license](https://img.shields.io/npm/l/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![GitHub stars](https://img.shields.io/github/stars/tickernelz/opencode-mem.svg)](https://github.com/tickernelz/opencode-mem) +[![Website](https://img.shields.io/badge/website-opencode--mem.zhafron.my.id-blue)](https://opencode-mem.zhafron.my.id) +[![Docs](https://img.shields.io/badge/docs-opencode--mem.zhafron.my.id%2Fdocs-blue)](https://opencode-mem.zhafron.my.id/docs/) ![OpenCode Memory Banner](../pics/banner.png) @@ -13,7 +15,16 @@ Een persistent geheugensysteem voor AI-codingagents dat langetermijncontextbehou ## Kernfuncties -Lokale Turso/libSQL-database met native vectorzoekopdrachten, persistente projectherinneringen, automatisch leren van gebruikersprofielen, uniforme geheugen-prompttijdlijn, volledige web-UI, intelligente promptgebaseerde geheugenextractie, multi-provider AI-ondersteuning (OpenAI, Anthropic), 12+ lokale embeddingmodellen, slimme deduplicatie en ingebouwde privacybescherming. +- **Lokale database:** ingebedde Turso/libSQL met native vectorzoekopdrachten, opgeslagen onder `storagePath`. Geen aparte vectordatabase. +- **Intelligente promptgebaseerde geheugenextractie (auto-capture):** wanneer een sessie inactief wordt, zet een AI-verzoek op de achtergrond het technische werk om in persistente projectherinneringen. +- **Automatisch ophalen:** relevante herinneringen en het gebruikersprofiel worden in de context van het model geïnjecteerd (`chatMessage`). +- **Automatisch leren van gebruikersprofielen:** een projectoverstijgende samenvatting van je voorkeuren, patronen en workflows. +- **Geheugenhygiëne:** slimme deduplicatie, optionele update-on-capture en optionele dreaming-consolidatie met herstelbare prullenbak. +- **Multi-provider AI-ondersteuning:** elke provider die in OpenCode is geconfigureerd (`opencodeProvider` / `opencodeModel`), of een handmatige API: OpenAI Chat Completions, OpenAI Responses, Anthropic, MiniMax, OrcaRouter, Atlas Cloud, Cheaper Inference, API Route, Runcrate, CloudGPU. +- **Embeddings:** 12+ lokale embeddingmodellen op de CPU (geen GPU nodig) of elke OpenAI-compatibele embeddings-API. +- **Volledige web-UI:** uniforme memory–prompt timeline, gebruikersprofiel, skillbibliotheek, Markdown vault en gezondheidsstatistieken, met optionele HTTP Basic Auth. +- **Ingebouwde privacybescherming:** ``-tags, het verwijderen van inloggegevens vóór het vastleggen en optionele versleuteling in rust. +- **Overdraagbaarheid:** optionele Markdown vault-backend, en `export` / `import` / `migrate` van de `memory`-tool voor verplaatste of gekopieerde projecten. ## Vereisten @@ -138,7 +149,7 @@ Schakel AES-256-GCM-versleuteling in voor lokale Turso-shards in `~/.config/open } ``` -Bij de eerste start maakt de plugin `~/.config/opencode/opencode-mem-db.key` aan (32-byte hex-sleutel, `chmod 600`) en migreert bestaande plaintext-shards. Overschrijf met `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` of `"file://~/path/to.key"` als je de sleutel zelf beheert. Verlies van de sleutel betekent dat de versleutelde databases niet kunnen worden geopend. +Bij de eerste start maakt de plugin `~/.config/opencode/opencode-mem-db.key` aan (32-byte hex-sleutel, `chmod 600`) en migreert bestaande plaintext-shards. Overschrijf met `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` of `"file://~/path/to.key"` als je de sleutel zelf beheert. Verlies van de sleutel betekent dat de versleutelde databases niet kunnen worden geopend. `databaseEncryptionCipher` selecteert de cipher: `aes256gcm` (standaard), `aes128gcm`, `aegis256`, `aegis256x2`, `aegis128l`, `aegis128x2` of `aegis128x4`. **Windows:** gebruik `%USERPROFILE%\.config\opencode\opencode.json` (bijvoorbeeld `C:\Users\\.config\opencode\opencode.json`). Deze plugin leest **niet** `%APPDATA%` of `%LOCALAPPDATA%` voor zijn OpenCode-pluginentry — plaats het bestand onder `.config\opencode` in je gebruikersprofiel en herstart OpenCode. Als de plugin niet verschijnt, controleer dat pad en herstart opnieuw. @@ -158,10 +169,10 @@ Je hoeft OpenCode **niet** te vragen dingen te “onthouden” om de plugin te l ### Automatisch versus handmatig geheugen -| Aanpak | Wanneer het draait | Wat jij doet | -| -------------------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------ | -| **Auto-capture** (`autoCaptureEnabled: true`, standaard) | Na conversatiebeurten wanneer de sessie idle wordt | Niets — extractie is automatisch | -| **Handmatig** `memory`-tool / commands | Op verzoek | `add`, `search`, `list`, `profile`, `forget`, `list-shards`, `migrate`, `export`, `import` | +| Aanpak | Wanneer het draait | Wat jij doet | +| -------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| **Auto-capture** (`autoCaptureEnabled: true`, standaard) | Na conversatiebeurten wanneer de sessie idle wordt | Niets — extractie is automatisch | +| **Handmatig** `memory`-tool / commands | Op verzoek | `add`, `search`, `list`, `profile`, `forget`, `list-shards`, `migrate`, `export`, `import`, `help` | Handmatige search/add/list werken nog steeds, ook als auto-capture geen provider geconfigureerd heeft. Auto-capture en gebruikersprofiel-leren hebben een provider nodig die structured/tool-call-output kan teruggeven. @@ -205,7 +216,7 @@ Als je een tijd hebt gechat en het bericht nog steeds ziet, controleer of auto-c ### Web-UI -Open `http://127.0.0.1:4747` om de geheugen–prompttijdlijn te bekijken, captures te inspecteren en het gebruikersprofiel te beheren. Als je de server buiten loopback bindt, zie [Web-UI HTTP Basic Auth](#web-ui-http-basic-auth). +Open `http://127.0.0.1:4747` om de memory–prompt timeline te bekijken, captures te inspecteren en het gebruikersprofiel te beheren. De UI heeft vijf weergaven: **Project memories** (`/project-memories`), **User profile** (`/user-profile`), **Skill library** (`/skill-library`), **Markdown vault** (`/markdown-vault`) en **Stats** (`/stats`). Wijzig de poort met `webServerPort`, of stel `webServerEnabled: false` in om zonder de web-UI te draaien. Als je de server buiten loopback bindt, zie [Web-UI HTTP Basic Auth](#web-ui-http-basic-auth). ## Gebruiksvoorbeelden @@ -235,6 +246,20 @@ Configureer op `~/.config/opencode/opencode-mem.jsonc`: De plugin maakt bij de eerste start een volledig becommentarieerd template op dit pad. Voor elke instelling en commentaar, zie [`opencode-mem.example.jsonc`](../../opencode-mem.example.jsonc). +Vaak aangepaste opties op het hoogste niveau: + +| Optie | Standaard | Wat het doet | +| --------------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `storagePath` | `"~/.opencode-mem/data"` | Waar de geheugendatabases worden opgeslagen. | +| `webServerEnabled` / `webServerPort` / `webServerHost` | `true` / `4747` / `"127.0.0.1"` | Schakelaar, poort en bindadres van de Web UI-server. | +| `autoCaptureEnabled` | `true` | Vat inactieve sessies samen tot herinneringen (vereist een provider, zie [Auto-Capture AI Provider](#auto-capture-ai-provider)). | +| `similarityThreshold` / `maxMemories` | `0.6` / `10` | Minimale gelijkenisscore en maximaal aantal resultaten bij het zoeken in herinneringen. | +| `injectProfile` | `true` | Injecteert het gebruikersprofiel (voorkeuren, patronen, workflows) in de AI-context. | +| `deduplicationEnabled` / `deduplicationSimilarityThreshold` | `true` / `0.9` | Detecteert en verwijdert dubbele herinneringen. | +| `autoCleanupEnabled` / `autoCleanupRetentionDays` | `true` / `30` | Verwijdert maximaal één keer per dag herinneringen die niet binnen de bewaartermijn zijn bijgewerkt. Vastgezette herinneringen blijven behouden. | +| `showAutoCaptureToasts` / `showUserProfileToasts` / `showErrorToasts` | `true` | Toasts voor auto-capture, profielupdates en fouten. | +| `autoUpdate` | `true` | Wist de gecachte installatie van OpenCode wanneer er een nieuwere npm-release beschikbaar is. | + ### Markdown-vault-backend (`memoryBackend`) Standaard leven herinneringen alleen in Turso onder `storagePath`. Optioneel kun je een **generieke Markdown-map** als bron van waarheid zetten (Obsidian-/Raneto-compatibele platte `.md`-bestanden — geen Obsidian-specifieke integratie): @@ -265,7 +290,10 @@ Deze instellingen staan onder de `chatMessage`-sleutel in `~/.config/opencode/op | Optie | Standaard | Wat het doet | | ------------------------------------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `enabled` | `true` | Leg geschreven gebruikersprompts vast en injecteer geheugencontext. | -| `injectOn` | `"first"` | Injecteer geheugencontext bij het eerste gebruikersbericht van een sessie, of bij `"always"` elke geschreven beurt. | +| `injectOn` | `"first"` | Bij `recall: "recent"`: injecteer bij het eerste gebruikersbericht, of bij `"always"` elke geschreven beurt. Met `recall: "relevant"` / `"both"` wordt de context altijd bij elke geschreven beurt ververst (issue #460). | +| `recall` | `"relevant"` | Hoe geïnjecteerde herinneringen worden gekozen: `"relevant"` maakt een embedding van het gebruikersbericht en voert elke beurt een vectorzoekopdracht uit; `"recent"` behoudt de oude lijst van de nieuwste N; `"both"` geeft de voorkeur aan relevante en vult resterende plaatsen aan met recente. | +| `recallScope` | `"default"` | Bereik voor auto-recall: `"default"` volgt `memory.defaultScope`, of forceer `"project"` / `"all-projects"`. Bij zoeken in alle projecten krijgen treffers uit het huidige project een kleine similarity-boost. | +| `similarityThreshold` | (top-level) | Optionele ondergrens per injectie; anders wordt de top-level `similarityThreshold` gebruikt. | | `maxMemories` / `excludeCurrentSession` / `maxAgeDays` | `3` / `true` / — | Hoeveel herinneringen de geïnjecteerde context bevat, of herinneringen uit de huidige sessie worden uitgesloten, en een optionele leeftijdslimiet in dagen. | | `filterInjectedPrompts` | `true` | Sla prompttekst over die door de host of andere OpenCode-plugins is geïnjecteerd (systeemherinneringen, orchestratierichtlijnen, achtergrondtaakmeldingen) zodat die nooit wordt opgeslagen alsof de gebruiker die heeft getypt. | | `injectionMarkers` | built-ins | Extra markers die geïnjecteerde blokken identificeren; worden toegevoegd aan de ingebouwde lijst, vervangen die nooit. | @@ -277,6 +305,23 @@ in die voor geschikte herinneringen beschikbaar zijn. Met `chatMessage.maxMemori op `0` wordt het injecteren van projectherinneringen uitgeschakeld; het gebruikersprofiel kan nog steeds worden geïnjecteerd als dit is ingeschakeld. +Geïnjecteerde geheugentags geven `selection="recent"` of `selection="semantic"` aan. +Recente selecties (inclusief fallback en recente aanvulling in `both`) hebben geen +numerieke score. Semantische selecties bevatten een eindige `retrieval_score` wanneer +beschikbaar; dit is een rangschikkingssignaal dat de boost voor het huidige project kan +bevatten, geen waarschijnlijkheid van relevantie of feitelijke juistheid. Ontbrekende of +ongeldige scores worden weggelaten. Dit vervangt het vroegere promptattribuut +`relevance="...%"` zonder de selectie, volgorde, inhoud of herkomst van herinneringen te +wijzigen. Compaction behoudt het bestaande formaat. + +Wanneer semantische recall mislukt (bijvoorbeeld omdat embedding niet beschikbaar is), +vallen `relevant` en `both` terug op de bestaande recente lijst met dezelfde +beperkingen voor bereik, aantal, sessie en leeftijd. Een geslaagde zoekopdracht zonder +geschikte treffers blijft leeg in `relevant`; `both` vult zoals gebruikelijk aan met +recente herinneringen. Waarschuwingen over gedeeltelijke shards activeren geen +fallback. Als ook de recente fallback mislukt, blijft recall leeg en niet-fataal. Het +fallbackgedrag bij een ontbrekende query en het verversen per beurt blijven ongewijzigd. + ### Update-on-capture (optioneel) Optioneel pad om herinneringen actueel te houden wanneer feiten veranderen. Met @@ -315,21 +360,22 @@ opgeschoond. Embeddings voeden similarity search voor herinneringen en het gebruikersprofiel. Configureer ze in hetzelfde bestand (`~/.config/opencode/opencode-mem.jsonc`). Er is **geen MLX-backend** — lokale embeddings gebruiken `@huggingface/transformers` met ONNX, niet Apple MLX. -**Lokaal (standaard):** stel alleen `embeddingModel` in. Bij eerste gebruik wordt het model gedownload van Hugging Face en gecached onder `{storagePath}/.cache` (standaard `~/.opencode-mem/data/.cache`). +**Lokaal (standaard):** stel alleen `embeddingModel` in. Bij eerste gebruik wordt het model gedownload van Hugging Face en gecached onder `{storagePath}/.cache` (standaard `~/.opencode-mem/data/.cache`). De gewichten blijven geladen zolang het hostproces draait; stel `embeddingIdleTimeoutMs` in om ze na dat aantal inactieve milliseconden vrij te geven, waarna de volgende geheugenoperatie ze opnieuw opwarmt vanuit de lokale cache (ongeveer een seconde, geen nieuwe download). **Remote (OpenAI-compatibel):** stel zowel `embeddingApiUrl` als `embeddingApiKey` in. De plugin roept dan `{embeddingApiUrl}/embeddings` aan met een Bearer-token. `embeddingApiKey` accepteert dezelfde geheime formaten als `memoryApiKey` (`literal`, `env://…`, `file://…`). -| Sleutel | Rol | -| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -| `embeddingModel` | Hugging Face-id (lokaal) of API-modelnaam (remote). Standaard: `Xenova/nomic-embed-text-v1` | -| `embeddingDimensions` | Optionele override; meestal weglaten — dimensies worden opgezocht uit een ingebouwde map | -| `embeddingPooling` | Lokale pooling: `"mean"` (standaard), `"cls"`, of `"last_token"`. Unset → klein known-model-preset of `"mean"` | -| `embeddingQueryPrefix` | Prefix voor query-task-embeddings. Unset → modelpreset of Nomic wanneer `embeddingUseTaskPrefixes` true is. Expliciete `""` schakelt uit | -| `embeddingDocumentPrefix` | Prefix voor document-task-embeddings (zelfde resolutieregels als `embeddingQueryPrefix`) | -| `embeddingUseTaskPrefixes` | Opt-in Nomic `search_query:` / `search_document:`-prefixes wanneer custom/preset-prefixes unset zijn. Standaard `false` | -| `embeddingDtype` | Optionele lokale ONNX-dtype-override (bijv. `"q8"`, `"fp32"`). Indien gezet, doorgegeven aan transformers.js `pipeline({ dtype })` | -| `embeddingApiUrl` | Basis-URL voor een OpenAI-compatibele embeddings-API (geen trailing path voorbij `/v1`) | -| `embeddingApiKey` | API-sleutel voor dat endpoint (vereist samen met `embeddingApiUrl`) | +| Sleutel | Rol | +| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| `embeddingModel` | Hugging Face-id (lokaal) of API-modelnaam (remote). Standaard: `Xenova/nomic-embed-text-v1` | +| `embeddingDimensions` | Optionele override; meestal weglaten — dimensies worden opgezocht uit een ingebouwde map | +| `embeddingPooling` | Lokale pooling: `"mean"` (standaard), `"cls"`, of `"last_token"`. Unset → klein known-model-preset of `"mean"` | +| `embeddingQueryPrefix` | Prefix voor query-task-embeddings. Unset → modelpreset of Nomic wanneer `embeddingUseTaskPrefixes` true is. Expliciete `""` schakelt uit | +| `embeddingDocumentPrefix` | Prefix voor document-task-embeddings (zelfde resolutieregels als `embeddingQueryPrefix`) | +| `embeddingUseTaskPrefixes` | Opt-in Nomic `search_query:` / `search_document:`-prefixes wanneer custom/preset-prefixes unset zijn. Standaard `false` | +| `embeddingDtype` | Optionele lokale ONNX-dtype-override (bijv. `"q8"`, `"fp32"`). Indien gezet, doorgegeven aan transformers.js `pipeline({ dtype })` | +| `embeddingIdleTimeoutMs` | Geef het lokale model vrij na dit aantal inactieve milliseconden (bijv. `600000` voor 10 minuten). `0` (standaard) houdt het geladen zolang het proces draait | +| `embeddingApiUrl` | Basis-URL voor een OpenAI-compatibele embeddings-API (geen trailing path voorbij `/v1`) | +| `embeddingApiKey` | API-sleutel voor dat endpoint (vereist samen met `embeddingApiUrl`) | Aanbevolen lokale modellen: @@ -521,9 +567,13 @@ Optioneel kun je een model-reasoningvariant vastzetten met `"opencodeVariant": " Trage reasoningmodellen (of zeer grote profielprompts) kunnen het standaard 90 s structured-output-budget overschrijden. Stel `"opencodeTimeoutMs"` (milliseconden) in om het te verlengen voor interne structured-output-calls (auto-capture-samenvattingen, profiel-leren) — bijv. `"opencodeTimeoutMs": 180000` voor 3 minuten. Waarden worden geclampt tot 10000..600000; de standaard blijft 90000. Numerieke strings worden gecoeerd. Profielopschoning gebruikt een aparte, langere timeout. -Ondersteunde providers: elke provider uit `opencode providers list` (bijv. `anthropic`, `openai`, `github-copilot`, ...). +Ondersteunde providers: elke provider uit `opencode providers list` (bijv. `anthropic`, `openai`, `github-copilot`, `openrouter`, ...). + +**Ingebouwde Free / Zen-modellen** onder provider-id `opencode` (bijv. `big-pickle`) kunnen de interne structured-output-sessies van de plugin vaak niet draaien — OpenCode kan ze buiten interactieve chat weigeren. Geef de voorkeur aan een geauthenticeerde provider uit `opencode providers list`, of gebruik `"opencodeModel": "inherit"` zodat capture het model volgt dat je al in de sessie gebruikt. -Als `opencodeProvider` en `opencodeModel` zijn ingesteld, hebben ze voorrang op de handmatige `memoryProvider`-instellingen hieronder. +Als `autoCaptureEnabled` `true` is (standaard) maar noch `opencodeProvider`/`opencodeModel` noch een complete handmatige fallback is geconfigureerd, logt de plugin een waarschuwing en toont een opstarttoast (wanneer `showErrorToasts` is ingeschakeld), zodat ontbrekende config zichtbaar is zonder door logs te hoeven zoeken. + +Als `opencodeProvider` en `opencodeModel` zijn ingesteld, hebben ze standaard voorrang op de handmatige `memoryProvider`-instellingen hieronder (`"autoCaptureProviderOrder": "opencode-first"`). Stel `"autoCaptureProviderOrder": "external-first"` in om de handmatige API te verkiezen wanneer beide zijn geconfigureerd (handig wanneer de session-API van de host druk/traag is); het andere kanaal wordt als fallback gebruikt. Verlaag `"opencodeTimeoutMs"` om sneller van het opencode-kanaal over te schakelen. **Volg het sessiermodel:** stel `"opencodeModel": "inherit"` in om op call-tijd een concreet OpenCode-model te gebruiken in plaats van een vastgezette id. Voor **auto-capture** wordt elke prompt via de `chat.params`-hook vastgelegd en hergebruikt het capture-verzoek provider/model van die prompt. Voor **profiel-leren** en andere structured-output-paden (die niet aan één gebruikersbericht zijn gebonden) hergebruikt `inherit` eerst het laatste model dat de host via `chat.params` / de V2-context-hook meldde, en valt daarna terug op OpenCode’s `model.json`-recentelijst indien aanwezig (met voorkeur voor de geconfigureerde `opencodeProvider`). OpenCode v2 schrijft `model.json` niet meer; daar is het in-process-sessiemodel de primaire fallback. Het letterlijke model-id `inherit` versturen is nooit geldig en veroorzaakte eerder `ProviderModelNotFoundError: Model not found: /inherit` op die paden. `opencodeProvider` blijft vereist als normale configgate. @@ -590,6 +640,42 @@ Handmatige `memoryProvider`-modi: Probleemoplossing: - Auto-capture-fouten blokkeren handmatig `memory`-toolgebruik niet. +- Auto-capture bewaart begrensde finale assistenttekst en terminale tool-uitkomsten uit + afgeleverde V1/V2-events voordat de vertraagde samenvatting draait. Normale idle-capture + geeft nog steeds de voorkeur aan het live host-transcript; gereed pending bewijs is de fallback + wanneer de sessie al weg is (verwijdering of startup-replay). Herstel is beperkt tot hetzelfde + project en gebruikt de normale capture-provider en claim-queue. Het leidt geen voltooid werk + af uit alleen het verzoek. Het verwijderen van een OpenCode-sessie verwijdert dit pending + geheugenbewijs of reeds vastgelegde geheugens **niet**. +- Pending bewijs wordt vóór persistentie op private tags geredigeerd (inclusief tags die + finale tekstdelen binnen één assistentbericht overspannen); reasoning, bijlagen, ruwe + providermetadata, streaming-delta's en tool-argumenten worden uitgesloten. Limieten zijn 16 KiB per + part, 16 parts per prompt, 256 parts globaal (maximaal 4 MiB tekst) en 64 KiB per + capture. Truncatie wordt gemarkeerd; de oudste parts worden verwijderd wanneer het budget wordt overschreden. + Bewijs verloopt na 24 uur en wordt bij volgende store-toegang opgeschoond. Het wordt gewist + wanneer capture voltooit/overslaat of de prompt wordt verwijderd via bestaande verwijder-/retentie- + paden. Dit zijn logische retentielimieten, geen veilige verwijdering van SQLite/WAL-back-ups. +- V2-events zijn een vluchtige stream: verbroken/gemiste events, onoplosbare prompt- + koppeling en bewijs dat door verloop/verwijdering verloren is gegaan, kunnen niet worden hersteld. De garantie + is capture uit bewijs dat is ontvangen, opgeslagen en door een idle/deleted-event als gereed is gecheckpoint, + geen reconstructie van ongeziene of eerder verwijderde transcripts. Na dat + checkpoint wordt de sessie verzegeld tegen late rebinds tot de volgende door de gebruiker geschreven + input (V2 `session.inbox.delivered`, V1 user `message.updated`), zodat gebufferde parts + gereed bewijs niet terug naar niet-gereed kunnen zetten. Een disconnect vóór het terminale + checkpoint laat het gedeeltelijke bewijs uitgesteld tot een later checkpoint; een herstart + gaat er niet van uit dat onvoltooid werk klaar is. V1 gebruikt expliciete parent-ID's van de assistent; + V2 bevriest de afgeleverde input bij step-start in plaats van de laatst in de wachtrij geplaatste + prompt te raden. +- Als de live host `Session.NotFoundError` meldt (of verwijdering/startup-replay geen + gereed bewijs heeft), logt capture `skipped` / `session_not_found`, geeft zijn claim vrij + zonder backoff of verbruik van retries, en slaat verdere host-afhankelijke lookups in die + batch over. Latere prompts met gereed opgeslagen bewijs gaan nog steeds door. Een latere onafhankelijke idle + kan opnieuw proberen. Reeds uitgeputte prompts worden niet herleefd. Andere fouten behouden hun + bestaande retry-gedrag. +- Auto-capture-toevoegingen gebruiken een stabiele ID per project/prompt, zodat sequentiële crash/restart- + replay het eerdere geheugen hergebruikt, inclusief soft-deleted records, in plaats van het in te voegen of + te doen herleven. Dit claimt geen gedistribueerde exactly-once-semantiek voor optionele + semantische update/supersede-operaties of elke multi-process crash-interleaving. - Als auto-capture meldt dat een provider niet verbonden is, bevestig de providernaam met `opencode providers list` en configureer die provider eerst in opencode. - Als een proxy of custom provider platte tekst teruggeeft in plaats van structured/tool-output, kies een ander model/provider of gebruik een van de handmatige providermodi hierboven. - Voor modellen die `temperature` weigeren, voeg `"memoryTemperature": false` toe bij handmatige API-configuratie. @@ -638,10 +724,14 @@ Lokaal bouwen en testen: ```bash bun install bun run build -bun run typecheck -bun run format +bun test +bun run check ``` +`bun run check` voert `format:check`, `lint` en `typecheck` uit; `bun run format` herschrijft de opmaak. + +De [website](https://opencode-mem.zhafron.my.id) en de bijbehorende [docs](https://opencode-mem.zhafron.my.id/docs/) worden gegenereerd uit deze README en de vertalingen onder `.github/i18n/`. Elke README-kop moet in `site/docs-map.json` aan een docs-pagina zijn gekoppeld, anders mislukt de site-build. Bouw de site lokaal met `cd site && bun install && bun run build`. + Dit project zoekt actief bijdragen om de definitieve geheugenplugin voor AI-codingagents te worden. Of je bugs fixt, features toevoegt, documentatie verbetert of embeddingmodelondersteuning uitbreidt: je bijdragen zijn cruciaal. De codebase is goed gestructureerd en klaar voor verbetering. Open issues met de Issue- of Feature request-templates, en vul het pull request-template in wanneer je een PR indient — we reviewen en mergen bijdragen snel. **README-vertalingen:** `README.md` (Engels) is de bron van waarheid. Wanneer je de inhoud wijzigt, werk dan de bestanden onder `.github/i18n/` (`README.de.md`, `README.zh.md`, `README.ar.md`, `README.tr.md` en `README.nl.md`) bij zodat ze overeenkomen. @@ -650,8 +740,11 @@ Dit project zoekt actief bijdragen om de definitieve geheugenplugin voor AI-codi MIT-licentie — zie LICENSE-bestand +- **Website**: https://opencode-mem.zhafron.my.id +- **Documentatie**: https://opencode-mem.zhafron.my.id/docs/ - **Repository**: https://github.com/tickernelz/opencode-mem - **Issues**: https://github.com/tickernelz/opencode-mem/issues +- **npm**: https://www.npmjs.com/package/opencode-mem - **OpenCode-platform**: https://opencode.ai Geïnspireerd door [opencode-supermemory](https://github.com/supermemoryai/opencode-supermemory) diff --git a/.github/i18n/README.tr.md b/.github/i18n/README.tr.md index 8632a3a8..c43dda86 100644 --- a/.github/i18n/README.tr.md +++ b/.github/i18n/README.tr.md @@ -4,6 +4,8 @@ [![npm downloads](https://img.shields.io/npm/dm/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![license](https://img.shields.io/npm/l/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![GitHub stars](https://img.shields.io/github/stars/tickernelz/opencode-mem.svg)](https://github.com/tickernelz/opencode-mem) +[![Website](https://img.shields.io/badge/website-opencode--mem.zhafron.my.id-blue)](https://opencode-mem.zhafron.my.id) +[![Docs](https://img.shields.io/badge/docs-opencode--mem.zhafron.my.id%2Fdocs-blue)](https://opencode-mem.zhafron.my.id/docs/) ![OpenCode Memory Banner](../pics/banner.png) @@ -13,7 +15,16 @@ Yerel vektör veritabanı teknolojisi kullanarak oturumlar arasında uzun vadeli ## Temel Özellikler -Yerel Turso/libSQL veritabanı ve yerel vektör arama, kalıcı proje bellekleri, otomatik kullanıcı profili öğrenme, birleşik bellek-prompt zaman çizelgesi, tam özellikli web arayüzü, akıllı prompt tabanlı bellek çıkarımı, çoklu sağlayıcı AI desteği (OpenAI, Anthropic), 12+ yerel embedding modeli, akıllı tekilleştirme ve yerleşik gizlilik koruması. +- **Yerel veritabanı:** `storagePath` altında saklanan, yerel vektör aramalı gömülü Turso/libSQL. Ayrı bir vektör veritabanı gerekmez. +- **Akıllı prompt tabanlı bellek çıkarımı (auto-capture):** bir oturum boşta kaldığında, arka planda çalışan bir AI isteği teknik çalışmayı kalıcı proje belleklerine dönüştürür. +- **Otomatik hatırlama:** ilgili bellekler ve kullanıcı profili modelin bağlamına (`chatMessage`) eklenir. +- **Otomatik kullanıcı profili öğrenme:** tercihlerinizin, kalıplarınızın ve iş akışlarınızın projeler arası bir özeti. +- **Bellek hijyeni:** akıllı tekilleştirme, isteğe bağlı update-on-capture ve kurtarılabilir çöp kutusuyla isteğe bağlı dreaming birleştirmesi. +- **Çoklu sağlayıcı AI desteği:** OpenCode'da yapılandırılmış herhangi bir sağlayıcı (`opencodeProvider` / `opencodeModel`) veya manuel bir API: OpenAI Chat Completions, OpenAI Responses, Anthropic, MiniMax, OrcaRouter, Atlas Cloud, Cheaper Inference, API Route, Runcrate, CloudGPU. +- **Embedding'ler:** CPU üzerinde çalışan 12+ yerel embedding modeli (GPU gerekmez) veya OpenAI uyumlu herhangi bir embedding API'si. +- **Tam özellikli web arayüzü:** birleşik memory–prompt timeline, kullanıcı profili, beceri kütüphanesi, Markdown vault ve sağlık istatistikleri; isteğe bağlı HTTP Basic Auth ile. +- **Gizlilik:** `` etiketleri, yakalama öncesinde kimlik bilgisi maskeleme ve isteğe bağlı bekleyen veri şifrelemesi. +- **Taşınabilirlik:** isteğe bağlı Markdown vault arka ucu ve taşınan veya kopyalanan projeler için `memory` aracının `export` / `import` / `migrate` komutları. ## Ön Koşullar @@ -140,7 +151,7 @@ Yerel Turso shard’ları için AES-256-GCM şifrelemesini `~/.config/opencode/o } ``` -İlk başlangıçta eklenti `~/.config/opencode/opencode-mem-db.key` oluşturur (32 bayt hex anahtar, `chmod 600`) ve mevcut düz metin shard’larını taşır. Anahtarı kendiniz yönetiyorsanız `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` veya `"file://~/path/to.key"` ile geçersiz kılın. Anahtarı kaybetmek, şifreli veritabanlarının açılamayacağı anlamına gelir. +İlk başlangıçta eklenti `~/.config/opencode/opencode-mem-db.key` oluşturur (32 bayt hex anahtar, `chmod 600`) ve mevcut düz metin shard’larını taşır. Anahtarı kendiniz yönetiyorsanız `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` veya `"file://~/path/to.key"` ile geçersiz kılın. Anahtarı kaybetmek, şifreli veritabanlarının açılamayacağı anlamına gelir. `databaseEncryptionCipher` şifreleme algoritmasını seçer: `aes256gcm` (varsayılan), `aes128gcm`, `aegis256`, `aegis256x2`, `aegis128l`, `aegis128x2` veya `aegis128x4`. **Windows:** `%USERPROFILE%\.config\opencode\opencode.json` kullanın (örneğin `C:\Users\\.config\opencode\opencode.json`). Bu eklenti OpenCode eklenti girişi için `%APPDATA%` veya `%LOCALAPPDATA%` **okumaz** — dosyayı kullanıcı profilinizdeki `.config\opencode` altına koyun, ardından OpenCode’u yeniden başlatın. Eklenti görünmezse yolu doğrulayın ve yeniden başlatın. @@ -160,10 +171,10 @@ Eklentinin çalışması için OpenCode’dan bir şeyleri “hatırlamasını ### Otomatik ve manuel bellek -| Yaklaşım | Ne zaman çalışır | Sizin yaptığınız | -| -------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------ | -| **Otomatik yakalama** (`autoCaptureEnabled: true`, varsayılan) | Oturum boşta kaldığında konuşma turlarından sonra | Hiçbir şey — çıkarım otomatiktir | -| **Manuel** `memory` aracı / komutlar | İsteğe bağlı | `add`, `search`, `list`, `profile`, `forget`, `list-shards`, `migrate`, `export`, `import` | +| Yaklaşım | Ne zaman çalışır | Sizin yaptığınız | +| -------------------------------------------------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| **Otomatik yakalama** (`autoCaptureEnabled: true`, varsayılan) | Oturum boşta kaldığında konuşma turlarından sonra | Hiçbir şey — çıkarım otomatiktir | +| **Manuel** `memory` aracı / komutlar | İsteğe bağlı | `add`, `search`, `list`, `profile`, `forget`, `list-shards`, `migrate`, `export`, `import`, `help` | Manuel arama/ekleme/listeleme, otomatik yakalama için yapılandırılmış bir sağlayıcı olmasa bile çalışır. Otomatik yakalama ve kullanıcı profili öğrenme, yapılandırılmış/araç-çağrısı çıktısı döndürebilen bir sağlayıcı gerektirir. @@ -207,7 +218,7 @@ Bir süre sohbet ettikten sonra hâlâ bu mesajı görüyorsanız, otomatik yaka ### Web arayüzü -Bellek–prompt zaman çizelgesine göz atmak, yakalamaları incelemek ve kullanıcı profilini yönetmek için `http://127.0.0.1:4747` adresini açın. Sunucuyu loopback dışına bağlarsanız bkz. [Web arayüzü HTTP Basic Auth](#web-arayüzü-http-basic-auth). +memory–prompt timeline'a göz atmak, yakalamaları incelemek ve kullanıcı profilini yönetmek için `http://127.0.0.1:4747` adresini açın. Arayüzde beş görünüm bulunur: **Project memories** (`/project-memories`), **User profile** (`/user-profile`), **Skill library** (`/skill-library`), **Markdown vault** (`/markdown-vault`) ve **Stats** (`/stats`). Portu `webServerPort` ile değiştirin veya web arayüzü olmadan çalıştırmak için `webServerEnabled: false` ayarlayın. Sunucuyu loopback dışına bağlarsanız bkz. [Web arayüzü HTTP Basic Auth](#web-arayüzü-http-basic-auth). ## Kullanım Örnekleri @@ -237,6 +248,20 @@ Boyut migrasyonları önce her yeni embedding’i üretir, bunları geçici inde Eklenti ilk başlangıçta bu yolda tam yorumlu bir şablon oluşturur. Her ayar ve yorum için bkz. [`opencode-mem.example.jsonc`](../../opencode-mem.example.jsonc). +Sık ayarlanan üst düzey seçenekler: + +| Seçenek | Varsayılan | Ne yapar | +| --------------------------------------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | +| `storagePath` | `"~/.opencode-mem/data"` | Bellek veritabanlarının bulunduğu konum. | +| `webServerEnabled` / `webServerPort` / `webServerHost` | `true` / `4747` / `"127.0.0.1"` | Web UI sunucusu anahtarı, portu ve bağlanma adresi. | +| `autoCaptureEnabled` | `true` | Boştaki oturumları belleklere özetler (bir sağlayıcı gerektirir, bkz. [Auto-Capture AI Sağlayıcısı](#otomatik-yakalama-ai-sağlayıcısı)). | +| `similarityThreshold` / `maxMemories` | `0.6` / `10` | Bellek araması için minimum benzerlik puanı ve maksimum sonuç sayısı. | +| `injectProfile` | `true` | Kullanıcı profilini (tercihler, kalıplar, iş akışları) AI bağlamına enjekte eder. | +| `deduplicationEnabled` / `deduplicationSimilarityThreshold` | `true` / `0.9` | Yinelenen bellekleri tespit eder ve kaldırır. | +| `autoCleanupEnabled` / `autoCleanupRetentionDays` | `true` / `30` | Günde en fazla bir kez, saklama süresi içinde güncellenmemiş bellekleri siler. Sabitlenmiş bellekler korunur. | +| `showAutoCaptureToasts` / `showUserProfileToasts` / `showErrorToasts` | `true` | auto-capture, profil güncellemeleri ve hatalar için bildirimler. | +| `autoUpdate` | `true` | Daha yeni bir npm sürümü mevcut olduğunda OpenCode’un önbelleğe alınmış kurulumunu temizler. | + ### Markdown vault backend (`memoryBackend`) Varsayılan olarak bellekler yalnızca `storagePath` altındaki Turso’da yaşar. İsteğe bağlı olarak **genel bir Markdown klasörünü** doğruluk kaynağı olarak ayarlayabilirsiniz (Obsidian/Raneto uyumlu düz `.md` dosyaları — Obsidian’a özel bir entegrasyon değildir): @@ -267,7 +292,10 @@ Bu ayarlar `~/.config/opencode/opencode-mem.jsonc` içindeki `chatMessage` anaht | Seçenek | Varsayılan | Ne yapar | | ------------------------------------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `enabled` | `true` | Yazılan kullanıcı prompt’larını yakala ve bellek bağlamını enjekte et. | -| `injectOn` | `"first"` | Bellek bağlamını bir oturumun ilk kullanıcı mesajında veya `"always"` ile her yazılan turda enjekte et. | +| `injectOn` | `"first"` | `recall: "recent"` için ilk kullanıcı mesajında veya `"always"` ile her yazılan turda enjekte et. `recall: "relevant"` / `"both"` ile bağlam her yazılan turda her zaman yenilenir (issue #460). | +| `recall` | `"relevant"` | Enjekte edilen belleklerin nasıl seçildiği: `"relevant"` her turda kullanıcı mesajını gömer ve vektör araması çalıştırır; `"recent"` eski en yeni N listelemesini korur; `"both"` önce ilgili olanları tercih eder, ardından kalan yerleri son belleklerle doldurur. | +| `recallScope` | `"default"` | Otomatik hatırlama kapsamı: `"default"` `memory.defaultScope` değerini izler veya `"project"` / `"all-projects"` zorlanabilir. Tüm projelerde arama yapılırken mevcut projeden gelen sonuçlar küçük bir benzerlik artışı alır. | +| `similarityThreshold` | (üst düzey) | İsteğe bağlı enjeksiyon başına alt sınır; aksi halde üst düzey `similarityThreshold` kullanılır. | | `maxMemories` / `excludeCurrentSession` / `maxAgeDays` | `3` / `true` / — | Enjekte edilen bağlamın kaç bellek tutacağı, mevcut oturumda yakalanan belleklerin hariç tutulup tutulmayacağı ve isteğe bağlı gün cinsinden yaş sınırı. | | `filterInjectedPrompts` | `true` | Ana bilgisayar veya diğer OpenCode eklentileri tarafından enjekte edilen prompt metnini (sistem hatırlatıcıları, orkestrasyon yönergeleri, arka plan görev bildirimleri) atla; böylece kullanıcı yazmış gibi asla saklanmaz. | | `injectionMarkers` | yerleşikler | Enjekte edilmiş blokları tanımlayan ek işaretçiler; yerleşik listeye eklenir, asla onun yerine geçmez. | @@ -278,6 +306,22 @@ Oturum ve yaşa göre hariç tutma kuralları, enjekte edilen bellek sayısı s doldurmaz. `chatMessage.maxMemories` değerini `0` yapmak proje belleği enjeksiyonunu devre dışı bırakır; kullanıcı profili etkinleştirilmişse yine de enjekte edilebilir. +Enjekte edilen bellek etiketleri `selection="recent"` veya `selection="semantic"` olarak +tanımlanır. Son seçimler (`both` içindeki geri dönüş ve son bellek doldurma dahil) sayısal +puan taşımaz. Semantik seçimler, mevcut olduğunda sonlu bir `retrieval_score` taşır; +bu, mevcut proje artışını içerebilen bir sıralama sinyalidir, ilgililik veya olgusal +doğruluk olasılığı değildir. Eksik veya geçersiz puanlar atlanır. Bu, bellek seçimini, +sıralamasını, içeriğini veya kaynağını değiştirmeden eski `relevance="...%"` prompt +özniteliğinin yerini alır. Sıkıştırma (compaction) mevcut biçimini korur. + +Semantik hatırlama başarısız olduğunda (örneğin gömme kullanılamıyorsa), `relevant` ve +`both`, aynı kapsam, sayı, oturum ve yaş kısıtlamalarıyla mevcut son bellek listelemesine +geri döner. Uygun eşleşme bulunmayan başarılı bir arama `relevant` modunda boş kalır; +`both` ise her zamanki gibi son belleklerle doldurmaya devam eder. Kısmi parça (shard) +uyarıları başarısızlık geri dönüşünü tetiklemez. Son bellek geri dönüşü de başarısız olursa, +hatırlama boş ve ölümcül olmayan şekilde kalır. Eksik sorgu geri dönüşü ve tur başına +yenileme davranışı değişmeden kalır. + ### Update-on-capture (isteğe bağlı) Gerçekler değiştikçe bellekleri güncel tutmak için isteğe bağlı yol. @@ -315,7 +359,7 @@ proje etiketleri arasında gruplanır; kullanıcı kapsamı ayrı kalır. Embedding’ler bellekler ve kullanıcı profili için benzerlik aramasını güçlendirir. Bunları aynı dosyada yapılandırın (`~/.config/opencode/opencode-mem.jsonc`). **MLX backend yoktur** — yerel embedding’ler Apple MLX değil, ONNX ile `@huggingface/transformers` kullanır. -**Yerel (varsayılan):** yalnızca `embeddingModel` ayarlayın. İlk kullanımda model Hugging Face’ten indirilir ve `{storagePath}/.cache` altında önbelleğe alınır (varsayılan `~/.opencode-mem/data/.cache`). +**Yerel (varsayılan):** yalnızca `embeddingModel` ayarlayın. İlk kullanımda model Hugging Face’ten indirilir ve `{storagePath}/.cache` altında önbelleğe alınır (varsayılan `~/.opencode-mem/data/.cache`). Ağırlıklar ana süreç yaşadığı sürece bellekte kalır; bunları o kadar milisaniyelik boşta kalma süresinden sonra serbest bırakmak için `embeddingIdleTimeoutMs` ayarlayın; sonraki bellek işlemi onları yerel önbellekten yeniden ısıtır (yeniden indirme değil, yaklaşık bir saniye). **Uzak (OpenAI uyumlu):** hem `embeddingApiUrl` hem `embeddingApiKey` ayarlayın. Eklenti ardından Bearer belirteciyle `{embeddingApiUrl}/embeddings` çağırır. `embeddingApiKey`, `memoryApiKey` ile aynı gizli biçimleri kabul eder (`literal`, `env://…`, `file://…`). @@ -328,6 +372,7 @@ Embedding’ler bellekler ve kullanıcı profili için benzerlik aramasını gü | `embeddingDocumentPrefix` | Belge-görevi embedding’leri için önek (`embeddingQueryPrefix` ile aynı çözüm kuralları) | | `embeddingUseTaskPrefixes` | Özel/ön ayar önekleri ayarlanmamışken Nomic `search_query:` / `search_document:` öneklerine katılma. Varsayılan `false` | | `embeddingDtype` | İsteğe bağlı yerel ONNX dtype geçersiz kılması (örn. `"q8"`, `"fp32"`). Ayarlandığında transformers.js `pipeline({ dtype })`’a iletilir | +| `embeddingIdleTimeoutMs` | Yerel modeli bu kadar milisaniye boşta kaldıktan sonra serbest bırakır (örn. 10 dakika için `600000`). `0` (varsayılan) süreç ömrü boyunca yüklü tutar | | `embeddingApiUrl` | OpenAI uyumlu bir embeddings API’si için temel URL (`/v1` ötesinde sondaki yol yok) | | `embeddingApiKey` | O uç nokta için API anahtarı (`embeddingApiUrl` ile birlikte gerekli) | @@ -520,9 +565,13 @@ Eklenti, sağlayıcı uç noktalarını doğrudan çağırmak yerine yapılandı Yavaş muhakeme modelleri (veya çok büyük profil prompt’ları) varsayılan 90 sn yapılandırılmış çıktı bütçesini aşabilir. Dahili yapılandırılmış çıktı çağrıları (otomatik yakalama özetleri, profil öğrenme) için uzatmak üzere `"opencodeTimeoutMs"` (milisaniye) ayarlayın — örn. 3 dakika için `"opencodeTimeoutMs": 180000`. Değerler 10000..600000’e sıkıştırılır; varsayılan 90000 kalır. Sayısal dizgeler zorlanır. Profil temizleme ayrı, daha uzun bir zaman aşımı kullanır. -Desteklenen sağlayıcılar: `opencode providers list` tarafından listelenen herhangi bir sağlayıcı (örn. `anthropic`, `openai`, `github-copilot`, ...). +Desteklenen sağlayıcılar: `opencode providers list` tarafından listelenen herhangi bir sağlayıcı (örn. `anthropic`, `openai`, `github-copilot`, `openrouter`, ...). + +`opencode` sağlayıcı kimliği altındaki **yerleşik Free / Zen modeller** (örn. `big-pickle`) çoğu zaman eklentinin dahili yapılandırılmış çıktı oturumlarını çalıştıramaz — OpenCode bunları etkileşimli sohbet dışında reddedebilir. `opencode providers list` içinden kimliği doğrulanmış bir sağlayıcıyı tercih edin veya yakalamanın oturumda zaten kullandığınız modeli izlemesi için `"opencodeModel": "inherit"` kullanın. -`opencodeProvider` ve `opencodeModel` ayarlanmışsa, aşağıdaki manuel `memoryProvider` ayarlarına göre önceliklidirler. +`autoCaptureEnabled` `true` (varsayılan) ise ancak ne `opencodeProvider`/`opencodeModel` ne de eksiksiz bir manuel yedek yapılandırılmışsa, eklenti bir uyarı günlüğe yazar ve (`showErrorToasts` etkinse) bir başlangıç bildirimi gösterir; böylece eksik yapılandırma günlükleri incelemeden görünür olur. + +`opencodeProvider` ve `opencodeModel` ayarlanmışsa, varsayılan olarak aşağıdaki manuel `memoryProvider` ayarlarına göre önceliklidirler (`"autoCaptureProviderOrder": "opencode-first"`). Her ikisi de yapılandırıldığında manuel API’yi tercih etmek için `"autoCaptureProviderOrder": "external-first"` ayarlayın (host oturum API’si meşgul/yavaş olduğunda yararlıdır); diğer kanal yedek olarak kullanılır. opencode kanalından daha erken geçiş yapmak için `"opencodeTimeoutMs"` değerini düşürün. **Oturum modelini izle:** çağrı anında sabitlenmiş bir kimlik yerine somut bir OpenCode modeli kullanmak için `"opencodeModel": "inherit"` ayarlayın. **Otomatik yakalama** için her prompt `chat.params` kancası üzerinden kaydedilir ve yakalama isteği o prompt’un sağlayıcı/modelini yeniden kullanır. **Profil öğrenme** ve diğer yapılandırılmış çıktı yolları için (tek bir kullanıcı mesajına bağlı değildir), `inherit` önce host’un `chat.params` / V2 context kancasında bildirdiği son modeli yeniden kullanır; yoksa OpenCode’un `model.json` son listesine düşer (yapılandırılmış `opencodeProvider` tercih edilir). OpenCode v2 artık `model.json` yazmaz; orada birincil geri dönüş süreç içi oturum modelidir. Literâl model kimliği `inherit` göndermek asla geçerli değildir ve daha önce bu yollarda `ProviderModelNotFoundError: Model not found: /inherit`’e neden olmuştur. `opencodeProvider` yine de normal yapılandırma kapısı olarak gereklidir. @@ -589,6 +638,45 @@ Manuel `memoryProvider` modları: Sorun giderme: - Otomatik yakalama hataları manuel `memory` araç kullanımını engellemez. +- Otomatik yakalama, gecikmeli özetleme çalışmadan önce iletilen V1/V2 olaylarından sınırlı + son asistan metnini ve terminal araç sonuçlarını korur. Normal boşta yakalama yine de + canlı host dökümünü tercih eder; oturum zaten yoksa (silme veya başlangıç yeniden oynatma) + hazır bekleyen kanıt yedek olarak kullanılır. Kurtarma aynı projeyle sınırlıdır ve normal + yakalama sağlayıcısını ve sahiplenme kuyruğunu kullanır. Tamamlanmış işi yalnızca istekten + çıkarsamaz. Bir OpenCode oturumunu silmek bu bekleyen bellek kanıtını veya zaten + yakalanmış bellekleri **silmez**. +- Bekleyen kanıt kalıcı hale getirilmeden önce özel etiketlerden arındırılır (tek bir + asistan mesajındaki son metin parçalarına yayılan etiketler dahil); muhakeme, ekler, ham + sağlayıcı meta verileri, akış deltaları ve araç argümanları hariç tutulur. Sınırlar parça + başına 16 KiB, prompt başına 16 parça, genel olarak 256 parça (en fazla 4 MiB metin) ve + yakalama başına 64 KiB’dir. Kesme işaretlenir; bütçe aşıldığında en eski parçalar + çıkarılır. Kanıt 24 saat sonra sona erer ve sonraki depo erişiminde temizlenir. Yakalama + bittiğinde/atlandığında veya prompt’u mevcut silme/saklama yollarıyla kaldırıldığında + silinir. Bunlar mantıksal saklama sınırlarıdır, SQLite/WAL yedeklerinin güvenli silinmesi + değildir. +- V2 olayları geçici bir akıştır: bağlantısı kopan/kaçırılan olaylar, çözülemeyen prompt + ilişkilendirmesi ve süre dolumu/çıkarma nedeniyle kaybolan kanıt kurtarılamaz. Garanti, + alınan, kaydedilen ve bir idle/deleted olayıyla hazır olarak kontrol noktasına alınan + kanıttan yakalamadır; görülmemiş veya daha önce silinmiş dökümlerin yeniden oluşturulması + değildir. Bu kontrol noktasından sonra oturum, bir sonraki yazılmış kullanıcı girdisine + (V2 `session.inbox.delivered`, V1 kullanıcı `message.updated`) kadar geç yeniden + bağlamalara karşı mühürlenir; böylece arabelleğe alınmış parçalar hazır kanıtı yeniden + hazır olmayan duruma çeviremez. Terminal kontrol noktasından önceki bir bağlantı kopması, + kısmi kanıtı sonraki bir kontrol noktasına kadar ertelenmiş bırakır; yeniden başlatma + bitmemiş işin tamamlandığını varsaymaz. V1 açık asistan üst kimliklerini kullanır; + V2 en son kuyruğa alınan prompt’u tahmin etmek yerine iletilen girdiyi adım başında + dondurur. +- Canlı host `Session.NotFoundError` bildirirse (veya silme/başlangıç yeniden oynatmada + hazır kanıt yoksa), yakalama `skipped` / `session_not_found` günlüğe yazar, sahiplenmesini + geri çekilme olmadan veya yeniden denemeleri tüketmeden bırakır ve o toplu işte host’a + bağlı diğer aramaları atlar. Hazır kaydedilmiş kanıtı olan sonraki prompt’lar yine de + devam eder. Sonraki bağımsız bir idle yeniden deneyebilir. Zaten tükenmiş prompt’lar + yeniden canlandırılmaz. Diğer hatalar mevcut yeniden deneme davranışlarını korur. +- Otomatik yakalama eklemeleri proje/prompt başına kararlı bir kimlik kullanır; böylece + ardışık çökme/yeniden başlatma yeniden oynatması, yeni kayıt eklemek veya yeniden + canlandırmak yerine yumuşak silinmiş kayıtlar dahil önceki belleği yeniden kullanır. Bu, + isteğe bağlı anlamsal güncelleme/yerine geçme işlemleri veya her çok süreçli çökme + iç içe geçmesi için dağıtık tam-bir-kez semantiği iddia etmez. - Otomatik yakalama bir sağlayıcının bağlı olmadığını bildirirse, sağlayıcı adını `opencode providers list` ile doğrulayın ve önce o sağlayıcıyı opencode’da yapılandırın. - Bir proxy veya özel sağlayıcı yapılandırılmış/araç çıktısı yerine düz metin döndürürse, başka bir model/sağlayıcı seçin veya yukarıdaki manuel sağlayıcı modlarından birini kullanın. - `temperature` reddeden modeller için manuel API yapılandırması kullanırken `"memoryTemperature": false` ekleyin. @@ -638,10 +726,14 @@ Yerelde derleyin ve test edin: ```bash bun install bun run build -bun run typecheck -bun run format +bun test +bun run check ``` +`bun run check`, `format:check`, `lint` ve `typecheck` komutlarını çalıştırır; `bun run format` biçimlendirmeyi yeniden yazar. + +[Web sitesi](https://opencode-mem.zhafron.my.id) ve [belgeleri](https://opencode-mem.zhafron.my.id/docs/) bu README'den ve `.github/i18n/` altındaki çevirilerden oluşturulur. Her README başlığı `site/docs-map.json` içinde bir belge sayfasına eşlenmelidir, aksi takdirde site derlemesi başarısız olur. Siteyi yerelde `cd site && bun install && bun run build` ile derleyin. + Bu proje, AI kodlama ajanları için nihai bellek eklentisi olmak üzere aktif olarak katkı arıyor. Hataları düzeltmek, özellik eklemek, belgeleri iyileştirmek veya embedding model desteğini genişletmek olsun, katkılarınız kritiktir. Kod tabanı iyi yapılandırılmış ve iyileştirmeye hazırdır. Lütfen Issue veya Feature request şablonlarıyla issue açın ve bir PR gönderdiğinizde pull request şablonunu doldurun — katkıları hızlıca inceler ve birleştiririz. **README çevirileri:** `README.md` (İngilizce) esas kaynaktır. İçeriğini değiştirdiğinizde `.github/i18n/` altındaki dosyaları (`README.de.md`, `README.zh.md`, `README.ar.md`, `README.tr.md` ve `README.nl.md`) buna uyacak şekilde güncelleyin. @@ -650,8 +742,11 @@ Bu proje, AI kodlama ajanları için nihai bellek eklentisi olmak üzere aktif o MIT License - see LICENSE file +- **Web Sitesi**: https://opencode-mem.zhafron.my.id +- **Belgeler**: https://opencode-mem.zhafron.my.id/docs/ - **Depo**: https://github.com/tickernelz/opencode-mem - **Issues**: https://github.com/tickernelz/opencode-mem/issues +- **npm**: https://www.npmjs.com/package/opencode-mem - **OpenCode Platform**: https://opencode.ai [opencode-supermemory](https://github.com/supermemoryai/opencode-supermemory) tarafından ilham alınmıştır diff --git a/.github/i18n/README.zh.md b/.github/i18n/README.zh.md index c258b211..d6029537 100644 --- a/.github/i18n/README.zh.md +++ b/.github/i18n/README.zh.md @@ -4,6 +4,8 @@ [![npm downloads](https://img.shields.io/npm/dm/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![license](https://img.shields.io/npm/l/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![GitHub stars](https://img.shields.io/github/stars/tickernelz/opencode-mem.svg)](https://github.com/tickernelz/opencode-mem) +[![Website](https://img.shields.io/badge/website-opencode--mem.zhafron.my.id-blue)](https://opencode-mem.zhafron.my.id) +[![Docs](https://img.shields.io/badge/docs-opencode--mem.zhafron.my.id%2Fdocs-blue)](https://opencode-mem.zhafron.my.id/docs/) ![OpenCode Memory Banner](../pics/banner.png) @@ -13,7 +15,16 @@ ## 核心功能 -本地 Turso/libSQL 数据库与原生向量搜索、持久化项目记忆、自动用户画像学习、统一的记忆–提示时间线、功能完整的 Web UI、基于提示的智能记忆提取、多提供商 AI 支持(OpenAI、Anthropic)、12+ 本地嵌入模型、智能去重,以及内置隐私保护。 +- **本地数据库:** 内嵌 Turso/libSQL 与原生向量搜索,存储于 `storagePath` 下。无需单独的向量数据库。 +- **基于提示的智能记忆提取 (auto-capture):** 当会话进入空闲状态时,后台 AI 请求会将技术工作转化为持久化项目记忆。 +- **自动召回:** 相关记忆和用户画像会被注入到模型上下文中(`chatMessage`)。 +- **自动用户画像学习:** 跨项目汇总你的偏好、模式和工作流程。 +- **记忆整理:** 智能去重、可选的 update-on-capture,以及可选的 dreaming 整合,并配有可恢复的回收站。 +- **多提供商 AI 支持:** 可使用 OpenCode 中配置的任意提供商(`opencodeProvider` / `opencodeModel`),或手动配置 API:OpenAI Chat Completions、OpenAI Responses、Anthropic、MiniMax、OrcaRouter、Atlas Cloud、Cheaper Inference、API Route、Runcrate、CloudGPU。 +- **嵌入:** 12+ 本地嵌入模型,在 CPU 上运行(无需 GPU),或使用任意 OpenAI 兼容的嵌入 API。 +- **功能完整的 Web UI:** 统一的 memory–prompt timeline、用户画像、技能库、Markdown vault 和健康统计,并支持可选的 HTTP Basic Auth。 +- **内置隐私保护:** `` 标签、捕获前凭据脱敏,以及可选的静态加密。 +- **可移植性:** 可选的 Markdown vault 后端,以及 `memory` 工具的 `export` / `import` / `migrate`,适用于移动或复制的项目。 ## 前置要求 @@ -138,7 +149,7 @@ v2 插件通过模型的系统上下文提供自动记忆上下文。 } ``` -首次启动时,插件会创建 `~/.config/opencode/opencode-mem-db.key`(32 字节十六进制密钥,`chmod 600`)并迁移现有明文分片。若你自行管理密钥,可用 `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` 或 `"file://~/path/to.key"` 覆盖。丢失密钥意味着无法打开已加密的数据库。 +首次启动时,插件会创建 `~/.config/opencode/opencode-mem-db.key`(32 字节十六进制密钥,`chmod 600`)并迁移现有明文分片。若你自行管理密钥,可用 `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` 或 `"file://~/path/to.key"` 覆盖。丢失密钥意味着无法打开已加密的数据库。`databaseEncryptionCipher` 用于选择加密算法:`aes256gcm`(默认)、`aes128gcm`、`aegis256`、`aegis256x2`、`aegis128l`、`aegis128x2` 或 `aegis128x4`。 **Windows:** 使用 `%USERPROFILE%\.config\opencode\opencode.json`(例如 `C:\Users\\.config\opencode\opencode.json`)。本插件**不会**从 `%APPDATA%` 或 `%LOCALAPPDATA%` 读取其 OpenCode 插件条目 — 请将文件放在用户配置文件下的 `.config\opencode`,然后重启 OpenCode。若插件未出现,请确认该路径并再次重启。 @@ -158,10 +169,10 @@ v2 插件通过模型的系统上下文提供自动记忆上下文。 ### 自动与手动记忆 -| 方式 | 何时运行 | 你需要做什么 | -| ------------------------------------------------ | ------------------------ | ------------------------------------------------------------------------------------------ | -| **自动捕获**(`autoCaptureEnabled: true`,默认) | 会话空闲后的对话轮次之后 | 无需操作 — 提取是自动的 | -| **手动** `memory` 工具 / 命令 | 按需 | `add`、`search`、`list`、`profile`、`forget`、`list-shards`、`migrate`、`export`、`import` | +| 方式 | 何时运行 | 你需要做什么 | +| ------------------------------------------------ | ------------------------ | -------------------------------------------------------------------------------------------------- | +| **自动捕获**(`autoCaptureEnabled: true`,默认) | 会话空闲后的对话轮次之后 | 无需操作 — 提取是自动的 | +| **手动** `memory` 工具 / 命令 | 按需 | `add`、`search`、`list`、`profile`、`forget`、`list-shards`、`migrate`、`export`、`import`、`help` | 即使自动捕获未配置提供商,手动搜索/添加/列表仍可工作。自动捕获与用户画像学习需要能返回结构化/工具调用输出的提供商。 @@ -205,7 +216,7 @@ Web UI 的 **Stats** 选项卡(`/stats`)一眼展示记忆系统健康状况 ### Web UI -打开 `http://127.0.0.1:4747` 以浏览记忆–提示时间线、检查捕获内容并管理用户画像。若将服务器绑定到回环以外,参见 [Web UI HTTP Basic Auth](#web-ui-http-basic-auth)。 +打开 `http://127.0.0.1:4747` 以浏览 memory–prompt timeline、检查捕获内容并管理用户画像。该 UI 包含五个视图:**Project memories**(`/project-memories`)、**User profile**(`/user-profile`)、**Skill library**(`/skill-library`)、**Markdown vault**(`/markdown-vault`)和 **Stats**(`/stats`)。可通过 `webServerPort` 更改端口,或设置 `webServerEnabled: false` 以在不启用 Web UI 的情况下运行。若将服务器绑定到回环以外,参见 [Web UI HTTP Basic Auth](#web-ui-http-basic-auth)。 ## 使用示例 @@ -235,6 +246,20 @@ memory({ mode: "import", inputPath: "./memories.json" }); 插件在首次启动时会在此路径创建完整的注释模板。有关每项设置与注释,参见 [`opencode-mem.example.jsonc`](../../opencode-mem.example.jsonc)。 +常用的顶层选项: + +| 选项 | 默认值 | 作用 | +| --------------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------ | +| `storagePath` | `"~/.opencode-mem/data"` | 记忆数据库的存放位置。 | +| `webServerEnabled` / `webServerPort` / `webServerHost` | `true` / `4747` / `"127.0.0.1"` | Web UI 服务器开关、端口与绑定地址。 | +| `autoCaptureEnabled` | `true` | 将空闲会话总结为记忆(需要配置提供方,参见 [Auto-Capture AI Provider](#自动捕获-ai-提供商))。 | +| `similarityThreshold` / `maxMemories` | `0.6` / `10` | 记忆搜索的最低相似度分数与最大结果数量。 | +| `injectProfile` | `true` | 将用户画像(偏好、模式、工作流)注入 AI 上下文。 | +| `deduplicationEnabled` / `deduplicationSimilarityThreshold` | `true` / `0.9` | 检测并移除重复记忆。 | +| `autoCleanupEnabled` / `autoCleanupRetentionDays` | `true` / `30` | 每天最多一次,删除在保留期内未更新的记忆。已置顶的记忆会被保留。 | +| `showAutoCaptureToasts` / `showUserProfileToasts` / `showErrorToasts` | `true` | auto-capture、画像更新与错误的提示通知。 | +| `autoUpdate` | `true` | 当有更新的 npm 版本可用时,清除 OpenCode 缓存的安装。 | + ### Markdown vault 后端(`memoryBackend`) 默认情况下,记忆仅存放在 `storagePath` 下的 Turso 中。也可选将**通用 Markdown 文件夹**设为事实来源(兼容 Obsidian/Raneto 的纯 `.md` 文件 — 并非 Obsidian 专用集成): @@ -265,7 +290,10 @@ memory({ mode: "import", inputPath: "./memories.json" }); | 选项 | 默认值 | 作用 | | ------------------------------------------------------ | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `enabled` | `true` | 捕获已编写的用户提示并注入记忆上下文。 | -| `injectOn` | `"first"` | 在会话的第一条用户消息上注入记忆上下文,或在每次已编写轮次上使用 `"always"`。 | +| `injectOn` | `"first"` | 对于 `recall: "recent"`,在第一条用户消息上注入,或使用 `"always"` 在每次已编写轮次上注入。使用 `recall: "relevant"` / `"both"` 时,上下文总是在每次已编写轮次刷新(issue #460)。 | +| `recall` | `"relevant"` | 注入记忆的选择方式:`"relevant"` 在每轮嵌入用户消息并执行向量搜索;`"recent"` 保留旧版的最新 N 条列表;`"both"` 优先选择相关记忆,再用最近记忆填充剩余名额。 | +| `recallScope` | `"default"` | 自动召回的范围:`"default"` 遵循 `memory.defaultScope`,也可强制使用 `"project"` / `"all-projects"`。搜索所有项目时,来自当前项目的结果会获得少量相似度加成。 | +| `similarityThreshold` | (顶层) | 可选的注入专用下限;否则使用顶层的 `similarityThreshold`。 | | `maxMemories` / `excludeCurrentSession` / `maxAgeDays` | `3` / `true` / — | 注入上下文保留多少条记忆、是否排除当前会话中捕获的记忆,以及可选的天数年龄截止。 | | `filterInjectedPrompts` | `true` | 跳过由主机或其他 OpenCode 插件注入的提示文本(系统提醒、编排指令、后台任务通知),以免将其当作用户亲自输入而存储。 | | `injectionMarkers` | 内置 | 识别注入块的额外标记;添加到内置列表,永不替换它。 | @@ -275,6 +303,16 @@ memory({ mode: "import", inputPath: "./memories.json" }); 不会占用原本可供符合条件的记忆使用的名额。将 `chatMessage.maxMemories` 设为 `0` 会禁用项目记忆注入,但启用用户画像后仍可注入用户画像。 +注入的记忆标签会标明 `selection="recent"` 或 `selection="semantic"`。 +最近选择(包括回退以及 `both` 中的最近填充)不带数值分数。语义选择在可用时会携带有限的 `retrieval_score`; +这是一个排序信号,可能包含当前项目加成,并非相关性或事实正确性的概率。缺失或无效的分数会被省略。 +这取代了以前的 `relevance="...%"` 提示属性,但不改变记忆的选择、排序、内容或来源。压缩保留其现有格式。 + +当语义召回失败时(例如嵌入不可用),`relevant` 和 `both` 会回退到现有的最近列表, +并沿用相同的范围、数量、会话和时间限制。搜索成功但没有符合条件的匹配时,`relevant` 保持为空; +`both` 仍照常用最近记忆填充。部分分片警告不会触发失败回退。如果最近列表回退也失败,召回保持为空且不致命。 +缺失查询时的回退以及每轮刷新行为保持不变。 + ### Update-on-capture(可选) 可选路径,用于在事实变化时保持记忆最新。当 `updateOnCaptureEnabled: true` 时,自动捕获会嵌入新摘要,搜索高于 `updateOnCaptureSimilarityThreshold`(默认 `0.75`)的相似记忆,并由捕获模型选择 `add`、`update`(原地改写)或 `supersede`(保存新条目并将旧条目软删除到回收站)。已固定(pinned)的记忆会被跳过。默认关闭,以便现有安装保持仅新增行为。 @@ -295,7 +333,7 @@ memory({ mode: "import", inputPath: "./memories.json" }); 嵌入为记忆与用户画像提供相似性搜索能力。在同一文件中配置(`~/.config/opencode/opencode-mem.jsonc`)。**没有 MLX 后端** — 本地嵌入使用带 ONNX 的 `@huggingface/transformers`,而非 Apple MLX。 -**本地(默认):** 仅设置 `embeddingModel`。首次使用时模型从 Hugging Face 下载并缓存在 `{storagePath}/.cache`(默认 `~/.opencode-mem/data/.cache`)下。 +**本地(默认):** 仅设置 `embeddingModel`。首次使用时模型从 Hugging Face 下载并缓存在 `{storagePath}/.cache`(默认 `~/.opencode-mem/data/.cache`)下。模型权重会在宿主进程的整个生命周期内常驻内存;设置 `embeddingIdleTimeoutMs` 可在空闲达到该毫秒数后释放它们,下一次记忆操作会从本地缓存重新预热(约一秒,而非重新下载)。 **远程(OpenAI 兼容):** 同时设置 `embeddingApiUrl` 与 `embeddingApiKey`。插件随后使用 Bearer 令牌调用 `{embeddingApiUrl}/embeddings`。`embeddingApiKey` 接受与 `memoryApiKey` 相同的密钥格式(`literal`、`env://…`、`file://…`)。 @@ -308,6 +346,7 @@ memory({ mode: "import", inputPath: "./memories.json" }); | `embeddingDocumentPrefix` | 文档任务嵌入的前缀(与 `embeddingQueryPrefix` 相同的解析规则) | | `embeddingUseTaskPrefixes` | 当自定义/预设前缀未设置时,可选启用 Nomic 的 `search_query:` / `search_document:` 前缀。默认 `false` | | `embeddingDtype` | 可选的本地 ONNX dtype 覆盖(例如 `"q8"`、`"fp32"`)。设置后会传给 transformers.js 的 `pipeline({ dtype })` | +| `embeddingIdleTimeoutMs` | 空闲达到该毫秒数后释放本地模型(例如 `600000` 表示 10 分钟)。`0`(默认)在进程生命周期内保持加载 | | `embeddingApiUrl` | OpenAI 兼容嵌入 API 的基础 URL(末尾路径不超过 `/v1`) | | `embeddingApiKey` | 该端点的 API 密钥(需与 `embeddingApiUrl` 一起设置) | @@ -497,9 +536,13 @@ memory({ mode: "import", inputPath: "./memories.json" }); 慢速推理模型(或非常大的画像提示)可能超过默认的 90 秒结构化输出预算。设置 `"opencodeTimeoutMs"`(毫秒)可为内部结构化输出调用(自动捕获摘要、画像学习)延长 — 例如 `"opencodeTimeoutMs": 180000` 表示 3 分钟。值钳制在 10000..600000;默认保持 90000。数字字符串会被强制转换。画像清理使用单独的、更长的超时。 -支持的提供商:`opencode providers list` 列出的任何提供商(例如 `anthropic`、`openai`、`github-copilot` 等)。 +支持的提供商:`opencode providers list` 列出的任何提供商(例如 `anthropic`、`openai`、`github-copilot`、`openrouter` 等)。 -若设置了 `opencodeProvider` 与 `opencodeModel`,它们优先于下方的手动 `memoryProvider` 设置。 +**内置 Free / Zen 模型**(提供商 id 为 `opencode`,例如 `big-pickle`)通常无法运行插件的内部结构化输出会话 — OpenCode 可能在交互式聊天之外拒绝它们。请优先使用 `opencode providers list` 中已认证的提供商,或使用 `"opencodeModel": "inherit"`,让捕获跟随你在会话中已使用的模型。 + +若 `autoCaptureEnabled` 为 `true`(默认),但既未配置 `opencodeProvider`/`opencodeModel`,也未配置完整的手动回退,插件会记录警告并显示启动提示(当启用 `showErrorToasts` 时),使缺失的配置无需翻查日志即可发现。 + +若设置了 `opencodeProvider` 与 `opencodeModel`,默认情况下它们优先于下方的手动 `memoryProvider` 设置(`"autoCaptureProviderOrder": "opencode-first"`)。设置 `"autoCaptureProviderOrder": "external-first"` 可在两者均已配置时优先使用手动 API(适用于主机会话 API 繁忙/缓慢时);另一通道用作回退。调低 `"opencodeTimeoutMs"` 可更快地从 opencode 通道故障转移。 **跟随会话模型:** 设置 `"opencodeModel": "inherit"` 以在调用时使用具体的 OpenCode 模型,而非固定 id。对于**自动捕获**,每个提示通过 `chat.params` 钩子记录,捕获请求重用该提示的提供商/模型。对于**画像学习**及其他结构化输出路径(不绑定到单条用户消息),`inherit` 先复用主机在 `chat.params` / V2 context 钩子上报的最近模型,再回退到 OpenCode `model.json` 最近列表(若存在;优先使用已配置的 `opencodeProvider`)。OpenCode v2 不再写入 `model.json`,因此进程内会话模型是主要回退。发送字面模型 id `inherit` 永远无效,此前会在这些路径上导致 `ProviderModelNotFoundError: Model not found: /inherit`。`opencodeProvider` 仍作为正常配置门控是必需的。 @@ -566,6 +609,11 @@ memory({ mode: "import", inputPath: "./memories.json" }); 故障排除: - 自动捕获失败不会阻止手动 `memory` 工具使用。 +- 自动捕获会在延迟摘要运行之前,保留来自已投递 V1/V2 事件的有界最终助手文本与终态工具结果。正常的空闲捕获仍优先使用实时主机记录;当会话已不存在时(删除或启动重放),已就绪的待处理证据作为回退。恢复范围限定于同一项目,并使用正常的捕获提供商与认领队列。它不会仅凭请求推断已完成的工作。删除 OpenCode 会话**不会**删除这些待处理记忆证据或已捕获的记忆。 +- 待处理证据在持久化前会进行私有标签脱敏(包括跨越同一助手消息内多个最终文本部分的标签);推理内容、附件、原始提供商元数据、流式增量与工具参数均被排除。限制为每部分 16 KiB、每个提示 16 个部分、全局 256 个部分(文本最多 4 MiB),以及每次捕获 64 KiB。截断会被标记;超出预算时淘汰最旧的部分。证据在 24 小时后过期,并在后续存储访问时清理。当捕获完成/跳过,或其提示被现有删除/保留路径移除时,证据会被清除。这些是逻辑保留限制,而非对 SQLite/WAL 备份的安全擦除。 +- V2 事件是易失流:断开/错过的事件、无法解析的提示关联,以及因过期/淘汰而丢失的证据均无法恢复。所保证的是基于已接收、已保存并由空闲/删除事件检查点标记为就绪的证据进行捕获,而非重建未见过或先前已删除的记录。在该检查点之后,会话会被封存以防止迟到的重新绑定,直至下一次用户撰写的输入(V2 `session.inbox.delivered`、V1 用户 `message.updated`),因此缓冲的部分无法将就绪证据翻转回未就绪。在终态检查点之前断开连接会使部分证据延迟到之后的检查点;重启不会假定未完成的工作已完成。V1 使用显式的助手父 ID;V2 在步骤开始时冻结已投递的输入,而非猜测最新排队的提示。 +- 若实时主机报告 `Session.NotFoundError`(或删除/启动重放没有就绪证据),捕获会记录 `skipped` / `session_not_found`,释放其认领而不退避或消耗重试次数,并跳过该批次中后续依赖主机的查找。之后带有已就绪保存证据的提示仍会继续。之后独立的空闲事件可能会重试。已耗尽重试的提示不会被复活。其他失败保留其现有的重试行为。 +- 自动捕获新增使用稳定的按项目/提示 ID,因此顺序的崩溃/重启重放会复用先前的记忆(包括软删除的记录),而不是插入或复活它。这并不声称对可选的语义更新/取代操作或所有多进程崩溃交错提供分布式恰好一次语义。 - 若自动捕获报告提供商未连接,请用 `opencode providers list` 确认提供商名称,并先在 opencode 中配置该提供商。 - 若代理或自定义提供商返回纯文本而非结构化/工具输出,请选择另一模型/提供商,或使用上方手动提供商模式之一。 - 对于拒绝 `temperature` 的模型,在使用手动 API 配置时添加 `"memoryTemperature": false`。 @@ -612,10 +660,14 @@ const { user, project } = getTags(process.cwd()); ```bash bun install bun run build -bun run typecheck -bun run format +bun test +bun run check ``` +`bun run check` 会运行 `format:check`、`lint` 和 `typecheck`;`bun run format` 会重写格式。 + +[网站](https://opencode-mem.zhafron.my.id)及其[文档](https://opencode-mem.zhafron.my.id/docs/)由本 README 和 `.github/i18n/` 下的翻译生成。每个 README 标题都必须在 `site/docs-map.json` 中映射到一个文档页面,否则站点构建会失败。可使用 `cd site && bun install && bun run build` 在本地构建站点。 + 本项目积极寻求贡献,以成为 AI 编程代理的权威记忆插件。无论你是修复缺陷、添加功能、改进文档,还是扩展嵌入模型支持,你的贡献都至关重要。代码库结构良好,已准备好增强。请使用 Issue 或 Feature request 模板提出问题,并在提交 PR 时填写 pull request 模板 — 我们会快速审查并合并贡献。 **README 翻译:** `README.md`(英文)为唯一权威来源。更改其内容时,请同步更新 `.github/i18n/` 下的文件(`README.de.md`、`README.zh.md`、`README.ar.md`、`README.tr.md` 和 `README.nl.md`)。 @@ -624,8 +676,11 @@ bun run format MIT License - 参见 LICENSE 文件 +- **网站**:https://opencode-mem.zhafron.my.id +- **文档**:https://opencode-mem.zhafron.my.id/docs/ - **仓库**:https://github.com/tickernelz/opencode-mem - **Issues**:https://github.com/tickernelz/opencode-mem/issues +- **npm**:https://www.npmjs.com/package/opencode-mem - **OpenCode 平台**:https://opencode.ai 灵感来自 [opencode-supermemory](https://github.com/supermemoryai/opencode-supermemory) diff --git a/README.md b/README.md index 7082b2fc..4323e7fb 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ [![npm downloads](https://img.shields.io/npm/dm/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![license](https://img.shields.io/npm/l/opencode-mem.svg)](https://www.npmjs.com/package/opencode-mem) [![GitHub stars](https://img.shields.io/github/stars/tickernelz/opencode-mem.svg)](https://github.com/tickernelz/opencode-mem) +[![Website](https://img.shields.io/badge/website-opencode--mem.zhafron.my.id-blue)](https://opencode-mem.zhafron.my.id) +[![Docs](https://img.shields.io/badge/docs-opencode--mem.zhafron.my.id%2Fdocs-blue)](https://opencode-mem.zhafron.my.id/docs/) ![OpenCode Memory Banner](.github/pics/banner.png) @@ -13,7 +15,16 @@ A persistent memory system for AI coding agents that enables long-term context r ## Core Features -Local Turso/libSQL database with native vector search, persistent project memories, automatic user profile learning, unified memory-prompt timeline, full-featured web UI, intelligent prompt-based memory extraction, multi-provider AI support (OpenAI, Anthropic), 12+ local embedding models, smart deduplication, and built-in privacy protection. +- **Local database:** embedded Turso/libSQL with native vector search, stored under `storagePath`. No separate vector database. +- **Intelligent prompt-based memory extraction (auto-capture):** when a session goes idle, a background AI request turns the technical work into persistent project memories. +- **Automatic recall:** relevant memories and the user profile are injected into the model's context (`chatMessage`). +- **User profile learning:** a cross-project summary of your preferences, patterns and workflows. +- **Memory hygiene:** smart deduplication, optional update-on-capture, and optional dreaming consolidation with recoverable trash. +- **Multi-provider AI support:** any provider configured in OpenCode (`opencodeProvider` / `opencodeModel`), or a manual API: OpenAI Chat Completions, OpenAI Responses, Anthropic, MiniMax, OrcaRouter, Atlas Cloud, Cheaper Inference, API Route, Runcrate, CloudGPU. +- **Embeddings:** 12+ local embedding models on CPU (no GPU needed) or any OpenAI-compatible embeddings API. +- **Full-featured web UI:** unified memory–prompt timeline, user profile, skill library, Markdown vault and health stats, with optional HTTP Basic Auth. +- **Privacy:** `` tags, credential redaction before capture, and optional encryption at rest. +- **Portability:** optional Markdown vault backend, and `memory` tool `export` / `import` / `migrate` for moved or copied projects. ## Memory credential redaction @@ -169,7 +180,7 @@ Enable AES-256-GCM encryption for local Turso shards in `~/.config/opencode/open } ``` -On first start the plugin creates `~/.config/opencode/opencode-mem-db.key` (32-byte hex key, `chmod 600`) and migrates existing plaintext shards. Override with `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` or `"file://~/path/to.key"` if you manage the key yourself. Losing the key means the encrypted databases cannot be opened. +On first start the plugin creates `~/.config/opencode/opencode-mem-db.key` (32-byte hex key, `chmod 600`) and migrates existing plaintext shards. Override with `"databaseEncryptionKey": "env://OPENCODE_MEM_DB_KEY"` or `"file://~/path/to.key"` if you manage the key yourself. Losing the key means the encrypted databases cannot be opened. `databaseEncryptionCipher` selects the cipher: `aes256gcm` (default), `aes128gcm`, `aegis256`, `aegis256x2`, `aegis128l`, `aegis128x2` or `aegis128x4`. **Windows:** use `%USERPROFILE%\.config\opencode\opencode.json` (for example `C:\Users\\.config\opencode\opencode.json`). This plugin does **not** read `%APPDATA%` or `%LOCALAPPDATA%` for its OpenCode plugin entry — put the file under `.config\opencode` in your user profile, then restart OpenCode. If the plugin does not appear, confirm that path and restart again. @@ -189,10 +200,10 @@ You do **not** need to ask OpenCode to “remember” things for the plugin to w ### Automatic vs manual memory -| Approach | When it runs | What you do | -| ------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------------------------------------ | -| **Auto-capture** (`autoCaptureEnabled: true`, default) | After conversation turns when the session goes idle | Nothing — extraction is automatic | -| **Manual** `memory` tool / commands | On demand | `add`, `search`, `list`, `profile`, `forget`, `list-shards`, `migrate`, `export`, `import` | +| Approach | When it runs | What you do | +| ------------------------------------------------------ | --------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| **Auto-capture** (`autoCaptureEnabled: true`, default) | After conversation turns when the session goes idle | Nothing — extraction is automatic | +| **Manual** `memory` tool / commands | On demand | `add`, `search`, `list`, `profile`, `forget`, `list-shards`, `migrate`, `export`, `import`, `help` | Manual search/add/list still work even if auto-capture has no provider configured. Auto-capture and user profile learning need a provider that can return structured/tool-call output. @@ -236,7 +247,7 @@ If you have chatted for a while and still see the message, check that auto-captu ### Web UI -Open `http://127.0.0.1:4747` to browse the memory–prompt timeline, inspect captures, and manage the user profile. If you bind the server beyond loopback, see [Web UI HTTP Basic Auth](#web-ui-http-basic-auth). +Open `http://127.0.0.1:4747` to browse the memory–prompt timeline, inspect captures, and manage the user profile. The UI has five views: **Project memories** (`/project-memories`), **User profile** (`/user-profile`), **Skill library** (`/skill-library`), **Markdown vault** (`/markdown-vault`) and **Stats** (`/stats`). Change the port with `webServerPort`, or set `webServerEnabled: false` to run without the web UI. If you bind the server beyond loopback, see [Web UI HTTP Basic Auth](#web-ui-http-basic-auth). ## Usage Examples @@ -266,6 +277,20 @@ Configure at `~/.config/opencode/opencode-mem.jsonc`: The plugin creates a full commented template at this path on first startup. For every setting and comment, see [`opencode-mem.example.jsonc`](opencode-mem.example.jsonc). +Commonly tuned top-level options: + +| Option | Default | What it does | +| --------------------------------------------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| `storagePath` | `"~/.opencode-mem/data"` | Where the memory databases live. | +| `webServerEnabled` / `webServerPort` / `webServerHost` | `true` / `4747` / `"127.0.0.1"` | Web UI server switch, port and bind address. | +| `autoCaptureEnabled` | `true` | Summarize idle sessions into memories (needs a provider, see [Auto-Capture AI Provider](#auto-capture-ai-provider)). | +| `similarityThreshold` / `maxMemories` | `0.6` / `10` | Minimum similarity score and maximum number of results for memory search. | +| `injectProfile` | `true` | Inject the user profile (preferences, patterns, workflows) into the AI context. | +| `deduplicationEnabled` / `deduplicationSimilarityThreshold` | `true` / `0.9` | Detect and remove duplicate memories. | +| `autoCleanupEnabled` / `autoCleanupRetentionDays` | `true` / `30` | At most once a day, delete memories not updated within the retention window. Pinned memories are kept. | +| `showAutoCaptureToasts` / `showUserProfileToasts` / `showErrorToasts` | `true` | Toasts for auto-capture, profile updates and errors. | +| `autoUpdate` | `true` | Clear OpenCode's cached install when a newer npm release is available. | + ### Markdown vault backend (`memoryBackend`) By default memories live only in Turso under `storagePath`. Optionally set a **generic Markdown folder** as the source of truth (Obsidian/Raneto-compatible plain `.md` files — not an Obsidian-specific integration): @@ -356,9 +381,6 @@ are never touched. Set `dreaming.crossProject: true` (or `memory.defaultScope: **Trash** (restore) and **Dream** (manual run). Soft-deleted rows are hard-purged after `dreaming.trashRetentionDays` during normal cleanup. -Deeper related-threshold dreaming (update/supersede/flag, cross-project) lands in the -follow-up PR for #464. - ### Choosing / configuring embeddings Embeddings power similarity search for memories and the user profile. Configure them in the same file (`~/.config/opencode/opencode-mem.jsonc`). There is **no MLX backend** — local embeddings use `@huggingface/transformers` with ONNX, not Apple MLX. @@ -727,10 +749,14 @@ Build and test locally: ```bash bun install bun run build -bun run typecheck -bun run format +bun test +bun run check ``` +`bun run check` runs `format:check`, `lint` and `typecheck`; `bun run format` rewrites formatting. + +The [website](https://opencode-mem.zhafron.my.id) and its [docs](https://opencode-mem.zhafron.my.id/docs/) are generated from this README and the translations under `.github/i18n/`. Every README heading must be mapped to a docs page in `site/docs-map.json`, otherwise the site build fails. Build the site locally with `cd site && bun install && bun run build`. + This project is actively seeking contributions to become the definitive memory plugin for AI coding agents. Whether you are fixing bugs, adding features, improving documentation, or expanding embedding model support, your contributions are critical. The codebase is well-structured and ready for enhancement. Please open issues with the Issue or Feature request templates, and fill out the pull request template when you submit a PR — we review and merge contributions quickly. **README translations:** `README.md` (English) is the source of truth. When you change its content, update the files under `.github/i18n/` (`README.de.md`, `README.zh.md`, `README.ar.md`, `README.tr.md`, and `README.nl.md`) to match. @@ -739,8 +765,11 @@ This project is actively seeking contributions to become the definitive memory p MIT License - see LICENSE file +- **Website**: https://opencode-mem.zhafron.my.id +- **Docs**: https://opencode-mem.zhafron.my.id/docs/ - **Repository**: https://github.com/tickernelz/opencode-mem - **Issues**: https://github.com/tickernelz/opencode-mem/issues +- **npm**: https://www.npmjs.com/package/opencode-mem - **OpenCode Platform**: https://opencode.ai Inspired by [opencode-supermemory](https://github.com/supermemoryai/opencode-supermemory) From 257ebc60b7349cbd9549d2030e3899c2064c2404 Mon Sep 17 00:00:00 2001 From: Zhafron Date: Wed, 4 Nov 2026 09:27:13 +0700 Subject: [PATCH 2/4] chore(package): add homepage and bugs metadata Points npm at the website and the issue tracker. Release only runs on v* tags, so this does not publish. --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index d1736931..a82d18b0 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,10 @@ "type": "git", "url": "git+https://github.com/tickernelz/opencode-mem.git" }, + "homepage": "https://opencode-mem.zhafron.my.id", + "bugs": { + "url": "https://github.com/tickernelz/opencode-mem/issues" + }, "publishConfig": { "access": "public" }, From 3db213d194b6f0de7e96774908875908803318b9 Mon Sep 17 00:00:00 2001 From: Zhafron Date: Wed, 4 Nov 2026 09:27:17 +0700 Subject: [PATCH 3/4] feat(site): complete social and structured metadata Adds og:site_name, og:locale, og:image size and alt, twitter:image:alt and rel=sitemap to the landing page, og:image size and alt to docs, and description, image, sameAs, author and isAccessibleForFree to the SoftwareApplication JSON-LD. --- site/astro.config.mjs | 10 ++++++++++ site/src/i18n/en.ts | 2 ++ site/src/layouts/Landing.astro | 12 ++++++++++++ 3 files changed, 24 insertions(+) diff --git a/site/astro.config.mjs b/site/astro.config.mjs index 4913ea28..df28baba 100644 --- a/site/astro.config.mjs +++ b/site/astro.config.mjs @@ -45,6 +45,16 @@ export default defineConfig({ tag: "meta", attrs: { property: "og:image", content: "https://opencode-mem.zhafron.my.id/og.png" }, }, + { tag: "meta", attrs: { property: "og:image:width", content: "1200" } }, + { tag: "meta", attrs: { property: "og:image:height", content: "630" } }, + { + tag: "meta", + attrs: { + property: "og:image:alt", + content: + "opencode-mem: Your agent finally remembers. Long-term memory for OpenCode. Free, open source, stored on your machine.", + }, + }, ], }), ], diff --git a/site/src/i18n/en.ts b/site/src/i18n/en.ts index dcd30413..271d016d 100644 --- a/site/src/i18n/en.ts +++ b/site/src/i18n/en.ts @@ -3,6 +3,8 @@ export const en = { title: "opencode-mem: your OpenCode agent finally remembers", description: "opencode-mem gives OpenCode a long-term memory. It writes down decisions, fixes, and preferences while you work, and brings them back next session. Free, open source, and stored on your machine.", + ogImageAlt: + "opencode-mem: Your agent finally remembers. Long-term memory for OpenCode. Free, open source, stored on your machine.", }, nav: { how: "How it works", diff --git a/site/src/layouts/Landing.astro b/site/src/layouts/Landing.astro index fd936e5e..a6701048 100644 --- a/site/src/layouts/Landing.astro +++ b/site/src/layouts/Landing.astro @@ -22,7 +22,12 @@ const jsonLd = { softwareVersion: numbers.version, license: "https://opensource.org/licenses/MIT", url: Astro.site?.href, + description: copy.meta.description, + image: new URL("/og.png", Astro.site).href, downloadUrl: "https://www.npmjs.com/package/opencode-mem", + sameAs: ["https://github.com/tickernelz/opencode-mem", "https://www.npmjs.com/package/opencode-mem"], + author: { "@type": "Person", name: "Zhafron Adani Kautsar", url: "https://github.com/tickernelz" }, + isAccessibleForFree: true, offers: { "@type": "Offer", price: "0", priceCurrency: "USD" }, }; --- @@ -40,12 +45,19 @@ const jsonLd = { + + + + + + +