@mingxy/cerebro 1.14.6 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/hooks.d.ts +10 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +395 -19
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +3 -0
- package/src/hooks.ts +434 -17
- package/src/index.ts +29 -10
package/dist/config.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export interface OmemPluginConfig {
|
|
|
41
41
|
};
|
|
42
42
|
agentMemoryPolicy?: Record<string, "none" | "readonly" | "readwrite">;
|
|
43
43
|
defaultPolicy?: "none" | "readonly" | "readwrite";
|
|
44
|
+
injectionStrategy?: "parts" | "system";
|
|
44
45
|
}
|
|
45
46
|
declare const DEFAULTS: OmemPluginConfig;
|
|
46
47
|
export declare function loadPluginConfig(overrides?: Partial<OmemPluginConfig>): OmemPluginConfig;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,OAAO,EAAE;QACP,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,MAAM,EAAE;QACN,oBAAoB,EAAE,MAAM,CAAC;QAC7B,UAAU,EAAE,OAAO,GAAG,KAAK,CAAC;KAC7B,CAAC;IACF,MAAM,EAAE;QACN,mBAAmB,EAAE,MAAM,CAAC;QAC5B,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;QAChD,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,OAAO,EAAE;QACP,UAAU,EAAE,OAAO,CAAC;QACpB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;QAC9C,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,EAAE,EAAE;QACF,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,CAAC,CAAC;IACtE,aAAa,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,OAAO,EAAE;QACP,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,MAAM,EAAE;QACN,oBAAoB,EAAE,MAAM,CAAC;QAC7B,UAAU,EAAE,OAAO,GAAG,KAAK,CAAC;KAC7B,CAAC;IACF,MAAM,EAAE;QACN,mBAAmB,EAAE,MAAM,CAAC;QAC5B,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;QAChD,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,OAAO,EAAE;QACP,UAAU,EAAE,OAAO,CAAC;QACpB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;QAC9C,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,EAAE,EAAE;QACF,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,CAAC,CAAC;IACtE,aAAa,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,CAAC;IAClD,iBAAiB,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CACxC;AAID,QAAA,MAAM,QAAQ,EAAE,gBA0Cf,CAAC;AAgIF,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CA+CxF;AAID,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,CAAC;AAE5D,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAChC,WAAW,CAeb;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -43,6 +43,7 @@ const DEFAULTS = {
|
|
|
43
43
|
excludeTools: ["memory_store", "memory_search", "memory_get", "memory_toggle", "memory_ingest"],
|
|
44
44
|
maxToolNames: 3,
|
|
45
45
|
},
|
|
46
|
+
injectionStrategy: "parts",
|
|
46
47
|
};
|
|
47
48
|
function isFlatConfig(cfg) {
|
|
48
49
|
return "apiUrl" in cfg && !("connection" in cfg);
|
|
@@ -100,6 +101,7 @@ function deepMerge(base, overrides) {
|
|
|
100
101
|
result.agentMemoryPolicy = overrides.agentMemoryPolicy;
|
|
101
102
|
if (overrides.defaultPolicy)
|
|
102
103
|
result.defaultPolicy = overrides.defaultPolicy;
|
|
104
|
+
result.injectionStrategy = overrides.injectionStrategy ?? base.injectionStrategy;
|
|
103
105
|
return result;
|
|
104
106
|
}
|
|
105
107
|
// ── Load config ──────────────────────────────────────────────────────
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAkDjC,wEAAwE;AAExE,MAAM,QAAQ,GAAqB;IACjC,UAAU,EAAE;QACV,MAAM,EAAE,uBAAuB;QAC/B,MAAM,EAAE,EAAE;QACV,gBAAgB,EAAE,KAAK;KACxB;IACD,OAAO,EAAE;QACP,cAAc,EAAE,GAAG;QACnB,eAAe,EAAE,KAAK;QACtB,gBAAgB,EAAE,GAAG;KACtB;IACD,MAAM,EAAE;QACN,oBAAoB,EAAE,CAAC;QACvB,UAAU,EAAE,OAAO;KACpB;IACD,MAAM,EAAE;QACN,mBAAmB,EAAE,GAAG;QACxB,gBAAgB,EAAE,EAAE;QACpB,eAAe,EAAE,CAAC;QAClB,iBAAiB,EAAE,CAAC;QACpB,mBAAmB,EAAE,IAAI;QACzB,gBAAgB,EAAE,GAAG;QACrB,gBAAgB,EAAE,CAAC;QACnB,UAAU,EAAE,EAAE;QACd,cAAc,EAAE,UAAU;QAC1B,iBAAiB,EAAE,GAAG;KACvB;IACD,OAAO,EAAE;QACP,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC;KAC9C;IACD,EAAE,EAAE;QACF,YAAY,EAAE,IAAI;KACnB;IACD,WAAW,EAAE;QACX,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,CAAC,GAAG,CAAC;QACZ,YAAY,EAAE,CAAC,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,CAAC;QAC/F,YAAY,EAAE,CAAC;KAChB;IACD,iBAAiB,EAAE,OAAgB;CACpC,CAAC;AAwBF,SAAS,YAAY,CAAC,GAA4B;IAChD,OAAO,QAAQ,IAAI,GAAG,IAAI,CAAC,CAAC,YAAY,IAAI,GAAG,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAgB;IAC3C,OAAO;QACL,UAAU,EAAE;YACV,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM;YACjD,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM;YACjD,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,IAAI,QAAQ,CAAC,UAAU,CAAC,gBAAgB;SAChF;QACD,OAAO,EAAE;YACP,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,QAAQ,CAAC,OAAO,CAAC,cAAc;YACtE,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,QAAQ,CAAC,OAAO,CAAC,eAAe;YACzE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,IAAI,QAAQ,CAAC,OAAO,CAAC,gBAAgB;SAC7E;QACD,MAAM,EAAE;YACN,oBAAoB,EAAE,IAAI,CAAC,oBAAoB,IAAI,QAAQ,CAAC,MAAM,CAAC,oBAAoB;YACvF,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,QAAQ,CAAC,MAAM,CAAC,UAAU;SAC1D;QACD,MAAM,EAAE;YACN,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,IAAI,QAAQ,CAAC,MAAM,CAAC,mBAAmB;YACpF,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,IAAI,QAAQ,CAAC,MAAM,CAAC,gBAAgB;YAC3E,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe;YAChD,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,iBAAiB;YACpD,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,mBAAmB;YACxD,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB;YAClD,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB;YAClD,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU;YACtC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc;YAC9C,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,iBAAiB;SACrD;QACD,OAAO,EAAE;YACP,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,QAAQ,CAAC,OAAO,CAAC,UAAU;YAC1D,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,QAAQ;YACpD,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM;SAC/C;QACD,EAAE,EAAE;YACF,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC,EAAE,CAAC,YAAY;SAC5D;KACF,CAAC;AACJ,CAAC;AAKD,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAa,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAEhF,SAAS,SAAS,CAAC,IAAsB,EAAE,SAAoC;IAC7E,MAAM,MAAM,GAAqB;QAC/B,UAAU,EAAE,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,SAAS,CAAC,UAAU,EAAE;QAC3D,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE;QAClD,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,EAAE;QAC/C,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,EAAE;QAC/C,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE;QAClD,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,GAAG,SAAS,CAAC,EAAE,EAAE;KACpC,CAAC;IACF,MAAM,CAAC,WAAW,GAAG,EAAE,GAAG,IAAI,CAAC,WAAY,EAAE,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IACxE,IAAI,SAAS,CAAC,iBAAiB;QAAE,MAAM,CAAC,iBAAiB,GAAG,SAAS,CAAC,iBAAiB,CAAC;IACxF,IAAI,SAAS,CAAC,aAAa;QAAE,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC,aAAa,CAAC;IAC5E,MAAM,CAAC,iBAAiB,GAAG,SAAS,CAAC,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,CAAC;IACjF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,wEAAwE;AAExE,MAAM,SAAS,GAA2B,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAEnF,SAAS,sBAAsB;IAC7B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;QACrE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAA4B,CAAC;QAClF,MAAM,MAAM,GAAI,GAAG,EAAE,OAAmC,EAAE,QAA8B,CAAC;QACzF,MAAM,IAAI,GAAG,GAAG,EAAE,QAA8B,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QACvC,OAAO,SAAS,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC,IAAI,CAAC;IACxB,CAAC;AACH,CAAC;AAED,MAAM,oBAAoB,GAAG,sBAAsB,EAAE,CAAC;AAEtD,2FAA2F;AAC3F,SAAS,SAAS,CAAC,OAAe,EAAE,MAAgC,EAAE,QAAgB,MAAM;IAC1F,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,GAAG,GAAG,oBAAoB;QAAE,OAAO;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAC3C,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC7E,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,oBAAoB,OAAO,EAAE,CAAC,CAAC;QACtE,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QACD,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,QAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjI,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAqC;IACpE,IAAI,MAAM,GAAqB,eAAe,CAAC,QAAQ,CAAC,CAAC;IAEzD,+BAA+B;IAC/B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;QACrE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAA4B,CAAC;QAElF,2BAA2B;QAC3B,MAAM,MAAM,GAAqB,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAiB,CAAC,CAAC,CAAC,CAAC,GAAkC,CAAC;QAEjI,+CAA+C;QAC/C,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,SAAS,CAAC,yCAAyC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,oEAAoE;IACpE,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAClF,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAClF,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,CAAC;QACxC,MAAM,CAAC,UAAU,CAAC,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC;IACjI,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,oBAAoB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,oBAAoB,CAAC;IACrI,CAAC;IACD,IAAI,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC,EAAE,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,gBAA8B,CAAC;IACxE,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,mBAAmB,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,mBAAmB,CAAC;IAC/H,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC;IACzH,CAAC;IAED,gDAAgD;IAChD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACxC,CAAC;IAED,uCAAuC;IACvC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAMD,MAAM,UAAU,kBAAkB,CAChC,SAAiB,EACjB,MAAiC;IAEjC,MAAM,QAAQ,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC1C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;QAClC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/E,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,aAAa;QAAE,OAAO,MAAM,CAAC,aAAa,CAAC;IACtD,SAAS,CAAC,6CAA6C,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;IACjF,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/hooks.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Model, UserMessage, Part } from "@opencode-ai/sdk";
|
|
2
|
-
import type { CerebroClient } from "./client.js";
|
|
2
|
+
import type { CerebroClient, SearchResult } from "./client.js";
|
|
3
3
|
import { type OmemPluginConfig } from "./config.js";
|
|
4
4
|
export declare function autoRecallHook(client: CerebroClient, containerTags: string[], tui: any, config?: Partial<OmemPluginConfig>, getAgentName?: () => string, directory?: string): (input: {
|
|
5
5
|
sessionID?: string;
|
|
@@ -7,6 +7,14 @@ export declare function autoRecallHook(client: CerebroClient, containerTags: str
|
|
|
7
7
|
}, output: {
|
|
8
8
|
system: string[];
|
|
9
9
|
}) => Promise<void>;
|
|
10
|
+
export declare function memoryInjectionHook(client: CerebroClient, containerTags: string[], tui: any, config?: Partial<OmemPluginConfig>, getAgentName?: () => string, directory?: string): (input: {
|
|
11
|
+
sessionID?: string;
|
|
12
|
+
messageID?: string;
|
|
13
|
+
model: Model;
|
|
14
|
+
}, output: {
|
|
15
|
+
message: UserMessage;
|
|
16
|
+
parts: Part[];
|
|
17
|
+
}) => Promise<void>;
|
|
10
18
|
export declare function keywordDetectionHook(_client: CerebroClient, _containerTags: string[], threshold: number, _tui: any, _ingestMode?: "smart" | "raw", config?: Partial<OmemPluginConfig>, agentId?: string): (input: {
|
|
11
19
|
sessionID: string;
|
|
12
20
|
messageID?: string;
|
|
@@ -14,6 +22,7 @@ export declare function keywordDetectionHook(_client: CerebroClient, _containerT
|
|
|
14
22
|
message: UserMessage;
|
|
15
23
|
parts: Part[];
|
|
16
24
|
}) => Promise<void>;
|
|
25
|
+
export declare function createCerebroCompactionPrompt(context: string[], projectMemories: SearchResult[]): string;
|
|
17
26
|
export declare function compactingHook(client: CerebroClient, containerTags: string[], tui: any, ingestMode?: "smart" | "raw", isAutoStoreEnabled?: (sessionId: string | undefined) => boolean, getMainSessionId?: () => string | undefined, sdkClient?: any, config?: Partial<OmemPluginConfig>, agentId?: string, directory?: string): (input: {
|
|
18
27
|
sessionID?: string;
|
|
19
28
|
}, output: {
|
package/dist/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks.js
CHANGED
|
@@ -124,7 +124,7 @@ function showToast(tui, title, message, variant = "info", delayMs = 7000) {
|
|
|
124
124
|
tui.showToast({ body: { title, message, variant, duration: 5000 } });
|
|
125
125
|
}
|
|
126
126
|
catch (err) {
|
|
127
|
-
|
|
127
|
+
logErr("showToast failed", { error: String(err) });
|
|
128
128
|
}
|
|
129
129
|
}, delayMs);
|
|
130
130
|
}
|
|
@@ -162,6 +162,17 @@ const injectedMemoryIds = new Map();
|
|
|
162
162
|
const firstMessages = new Map();
|
|
163
163
|
const sessionMessages = new Map();
|
|
164
164
|
const profileInjectedSessions = new Map();
|
|
165
|
+
const injectedSessions = new Set();
|
|
166
|
+
const compactingSummaryCooldown = new Map();
|
|
167
|
+
function hashString(str) {
|
|
168
|
+
let hash = 0;
|
|
169
|
+
for (let i = 0; i < str.length; i++) {
|
|
170
|
+
const char = str.charCodeAt(i);
|
|
171
|
+
hash = ((hash << 5) - hash) + char;
|
|
172
|
+
hash |= 0;
|
|
173
|
+
}
|
|
174
|
+
return hash.toString(36);
|
|
175
|
+
}
|
|
165
176
|
function formatRelativeAge(isoDate) {
|
|
166
177
|
const diffMs = Date.now() - new Date(isoDate).getTime();
|
|
167
178
|
const minutes = Math.floor(diffMs / 60_000);
|
|
@@ -223,7 +234,9 @@ function formatMemoryLine(r, maxContentLength) {
|
|
|
223
234
|
}
|
|
224
235
|
const FETCH_POLICY = [
|
|
225
236
|
"<cerebro-fetch-policy>",
|
|
226
|
-
"Each memory above is a condensed summary
|
|
237
|
+
"IMPORTANT: Each memory above is a condensed summary. The full version contains critical details that may change your response quality.",
|
|
238
|
+
"You MUST use memory_get(\"id\") to retrieve the complete content before making decisions based on any summary.",
|
|
239
|
+
"Do NOT rely on condensed summaries alone — depth of recall determines quality of response.",
|
|
227
240
|
"</cerebro-fetch-policy>",
|
|
228
241
|
].join("\n");
|
|
229
242
|
function buildContextBlock(results, maxContentLength = 500) {
|
|
@@ -551,6 +564,315 @@ export function autoRecallHook(client, containerTags, tui, config = {}, getAgent
|
|
|
551
564
|
}
|
|
552
565
|
};
|
|
553
566
|
}
|
|
567
|
+
export function memoryInjectionHook(client, containerTags, tui, config = {}, getAgentName, directory) {
|
|
568
|
+
const similarityThreshold = config.recall?.similarityThreshold ?? 0.4;
|
|
569
|
+
const maxRecallResults = config.recall?.maxRecallResults ?? 10;
|
|
570
|
+
const fetchMultiplier = config.recall?.fetchMultiplier ?? 3;
|
|
571
|
+
const topkCapMultiplier = config.recall?.topkCapMultiplier ?? 2;
|
|
572
|
+
const mmrJaccardThreshold = config.recall?.mmrJaccardThreshold ?? 0.85;
|
|
573
|
+
const mmrPenaltyFactor = config.recall?.mmrPenaltyFactor ?? 0.5;
|
|
574
|
+
const phase2Multiplier = config.recall?.phase2Multiplier ?? 2;
|
|
575
|
+
const llmMaxEval = config.recall?.llmMaxEval ?? 15;
|
|
576
|
+
const refineStrategy = config.recall?.refineStrategy ?? "balanced";
|
|
577
|
+
const refineMediumChars = config.recall?.refineMediumChars ?? 200;
|
|
578
|
+
const maxContentLength = Math.max(MIN_CONTENT_LENGTH, config.content?.maxContentLength ?? 500);
|
|
579
|
+
const maxContentChars = Math.max(MIN_CONTENT_CHARS, config.content?.maxContentChars ?? 30000);
|
|
580
|
+
const toastDelayMs = config.ui?.toastDelayMs ?? 7000;
|
|
581
|
+
return async (input, output) => {
|
|
582
|
+
if (!input.sessionID)
|
|
583
|
+
return;
|
|
584
|
+
const agentId = getAgentName?.() || process.env.OMEM_AGENT_ID || "opencode";
|
|
585
|
+
const policy = resolveAgentPolicy(agentId, config);
|
|
586
|
+
if (policy === "none")
|
|
587
|
+
return;
|
|
588
|
+
const isFirstInjection = !injectedSessions.has(input.sessionID);
|
|
589
|
+
const isKeywordTriggered = keywordDetectedSessions.has(input.sessionID);
|
|
590
|
+
if (!isFirstInjection && !isKeywordTriggered)
|
|
591
|
+
return;
|
|
592
|
+
try {
|
|
593
|
+
logDebug("memoryInjectionHook start", { sessionId: input.sessionID, agentId, policy, isFirstInjection, isKeywordTriggered, similarityThreshold, maxRecallResults });
|
|
594
|
+
const messages = sessionMessages.get(input.sessionID) ?? [];
|
|
595
|
+
const userMessages = messages.filter((m) => m.role === "user");
|
|
596
|
+
// --- Profile Fetch ---
|
|
597
|
+
const profile = await client.getProfile();
|
|
598
|
+
let profileInjected = false;
|
|
599
|
+
let profileCountText = "";
|
|
600
|
+
let profileBlock = "";
|
|
601
|
+
const lastInjected = profileInjectedSessions.get(input.sessionID);
|
|
602
|
+
const ttlExpired = !lastInjected || (Date.now() - lastInjected > 30 * 60 * 1000);
|
|
603
|
+
const profileIsFirstInjection = !lastInjected;
|
|
604
|
+
if (profile && ttlExpired) {
|
|
605
|
+
const prefs = (profile?.static_facts ?? [])
|
|
606
|
+
.filter((sf) => {
|
|
607
|
+
const t = sf.tags ?? [];
|
|
608
|
+
return t.includes("preferences");
|
|
609
|
+
})
|
|
610
|
+
.map((sf) => sf.l2_content ?? sf.content ?? "")
|
|
611
|
+
.filter(Boolean);
|
|
612
|
+
const profileLines = prefs.length > 0
|
|
613
|
+
? prefs.map((c) => ` · ${c}`).join("\n")
|
|
614
|
+
: " · (preferences queuing, will populate on next refresh)";
|
|
615
|
+
profileBlock = [
|
|
616
|
+
"<cerebro-profile>",
|
|
617
|
+
profileLines,
|
|
618
|
+
"</cerebro-profile>",
|
|
619
|
+
].join("\n");
|
|
620
|
+
profileInjected = true;
|
|
621
|
+
profileInjectedSessions.set(input.sessionID, Date.now());
|
|
622
|
+
const p = profile;
|
|
623
|
+
const dynamicCount = p?.dynamic_context?.length ?? 0;
|
|
624
|
+
const staticCount = p?.static_facts?.length ?? 0;
|
|
625
|
+
profileCountText = `Dynamic(${dynamicCount}) · Static(${staticCount})`;
|
|
626
|
+
if (profileIsFirstInjection) {
|
|
627
|
+
logDebug("memoryInjectionHook profile ready (first)", { dynamicCount, staticCount });
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
logDebug("memoryInjectionHook profile ready (TTL)", { dynamicCount, staticCount });
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (userMessages.length === 0) {
|
|
634
|
+
logDebug("memoryInjectionHook skipped: no user messages in session (post-compacting?)", { sessionId: input.sessionID });
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
const rawQuery = userMessages[userMessages.length - 1]?.content || firstMessages.get(input.sessionID) || "";
|
|
638
|
+
const query_text = extractUserRequest(rawQuery);
|
|
639
|
+
if (!query_text) {
|
|
640
|
+
logDebug("memoryInjectionHook filtered system injection (profile already injected above)", { rawQueryPrefix: rawQuery.slice(0, 60) });
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
const last_query_text = userMessages.length >= 2 ? userMessages[userMessages.length - 2].content : undefined;
|
|
644
|
+
const projectTags = containerTags.filter(t => t.startsWith("omem_project_"));
|
|
645
|
+
const conversationContext = userMessages.length >= 2
|
|
646
|
+
? userMessages.slice(-4, -1).map((m) => {
|
|
647
|
+
const stripped = stripPrivateContent(m.content);
|
|
648
|
+
return stripped.length > 200 ? stripped.slice(0, 200) : stripped;
|
|
649
|
+
})
|
|
650
|
+
: undefined;
|
|
651
|
+
const shouldRecallRes = await client.shouldRecall(query_text, last_query_text, input.sessionID, similarityThreshold, maxRecallResults, projectTags.length > 0 ? projectTags : undefined, conversationContext && conversationContext.length > 0 ? conversationContext : undefined, {
|
|
652
|
+
fetch_multiplier: fetchMultiplier,
|
|
653
|
+
topk_cap_multiplier: topkCapMultiplier,
|
|
654
|
+
mmr_jaccard_threshold: mmrJaccardThreshold,
|
|
655
|
+
mmr_penalty_factor: mmrPenaltyFactor,
|
|
656
|
+
phase2_multiplier: phase2Multiplier,
|
|
657
|
+
llm_max_eval: llmMaxEval,
|
|
658
|
+
refine_strategy: refineStrategy,
|
|
659
|
+
refine_medium_chars: refineMediumChars,
|
|
660
|
+
}, directory || process.env.OMEM_PROJECT_DIR);
|
|
661
|
+
if (!shouldRecallRes) {
|
|
662
|
+
showToast(tui, "🧠 Cerebro Service Unavailable", "Unable to reach memory API · check connection", "error", toastDelayMs);
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
logDebug("memoryInjectionHook shouldRecall result", { shouldRecall: shouldRecallRes.should_recall, confidence: shouldRecallRes.confidence, memCount: shouldRecallRes.memories?.length ?? 0, discardedCount: shouldRecallRes.discarded?.length ?? 0, clustered: !!shouldRecallRes.clustered });
|
|
666
|
+
const storedMemoryIds = shouldRecallRes.memories?.map((r) => r.memory.id) ?? [];
|
|
667
|
+
const storedDiscardedIds = shouldRecallRes.discarded?.map((d) => d.memory_id) ?? [];
|
|
668
|
+
const maxScore = storedMemoryIds.length > 0
|
|
669
|
+
? Math.max(...(shouldRecallRes.memories?.map((r) => r.score) ?? [0]))
|
|
670
|
+
: 0;
|
|
671
|
+
const createEventAndReturn = async (injectedCount, keptCount, discardedCount, injectedContent) => {
|
|
672
|
+
try {
|
|
673
|
+
const items = [
|
|
674
|
+
...(shouldRecallRes.memories?.map((r) => ({
|
|
675
|
+
memory_id: r.memory.id,
|
|
676
|
+
score: r.score,
|
|
677
|
+
refine_relevance: r.refine_relevance,
|
|
678
|
+
refine_reasoning: r.refine_reasoning,
|
|
679
|
+
is_kept: true,
|
|
680
|
+
})) ?? []),
|
|
681
|
+
...(shouldRecallRes.discarded?.map((d) => ({
|
|
682
|
+
memory_id: d.memory_id,
|
|
683
|
+
score: d.score,
|
|
684
|
+
refine_relevance: d.refine_relevance,
|
|
685
|
+
refine_reasoning: d.refine_reasoning,
|
|
686
|
+
is_kept: false,
|
|
687
|
+
})) ?? []),
|
|
688
|
+
];
|
|
689
|
+
const result = await client.createRecallEvent({
|
|
690
|
+
session_id: input.sessionID,
|
|
691
|
+
recall_type: "auto",
|
|
692
|
+
query_text,
|
|
693
|
+
max_score: maxScore,
|
|
694
|
+
llm_confidence: shouldRecallRes.confidence ?? 0,
|
|
695
|
+
profile_injected: profileInjected,
|
|
696
|
+
kept_count: keptCount,
|
|
697
|
+
discarded_count: discardedCount,
|
|
698
|
+
injected_count: injectedCount,
|
|
699
|
+
profile_content: profileInjected && profileBlock ? profileBlock : undefined,
|
|
700
|
+
injected_content: injectedContent,
|
|
701
|
+
items: items.length > 0 ? items : undefined,
|
|
702
|
+
});
|
|
703
|
+
return result?.event_id;
|
|
704
|
+
}
|
|
705
|
+
catch (e) {
|
|
706
|
+
logErr("memoryInjectionHook createRecallEvent failed", { error: String(e) });
|
|
707
|
+
return undefined;
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
// --- no-recall path: inject profile only ---
|
|
711
|
+
if (!shouldRecallRes.should_recall) {
|
|
712
|
+
const partsToInject = [];
|
|
713
|
+
if (profileBlock)
|
|
714
|
+
partsToInject.push(profileBlock);
|
|
715
|
+
if (partsToInject.length > 0) {
|
|
716
|
+
const injectText = partsToInject.join("\n\n");
|
|
717
|
+
const contextPart = {
|
|
718
|
+
id: `prt_cerebro-context-${Date.now()}`,
|
|
719
|
+
sessionID: input.sessionID,
|
|
720
|
+
messageID: output.message.id,
|
|
721
|
+
type: "text",
|
|
722
|
+
text: injectText,
|
|
723
|
+
synthetic: true,
|
|
724
|
+
};
|
|
725
|
+
output.parts.unshift(contextPart);
|
|
726
|
+
logDebug("memoryInjectionHook profile injected (no-recall path)", { sessionId: input.sessionID });
|
|
727
|
+
}
|
|
728
|
+
injectedSessions.add(input.sessionID);
|
|
729
|
+
if (profileInjected && profileIsFirstInjection) {
|
|
730
|
+
await createEventAndReturn(0, 0, 0);
|
|
731
|
+
showToast(tui, "👨 Profile Injected", `${profileCountText} · no memory recall needed`, "success", toastDelayMs);
|
|
732
|
+
}
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
const results = shouldRecallRes.memories ?? [];
|
|
736
|
+
const clustered = shouldRecallRes.clustered;
|
|
737
|
+
const existingIds = injectedMemoryIds.get(input.sessionID) ?? new Set();
|
|
738
|
+
const newResults = results.filter((r) => !existingIds.has(r.memory.id));
|
|
739
|
+
logDebug("memoryInjectionHook dedup", { totalResults: results.length, existingCount: existingIds.size, newCount: newResults.length });
|
|
740
|
+
// --- dedup path: inject profile only ---
|
|
741
|
+
if (newResults.length === 0) {
|
|
742
|
+
const partsToInject = [];
|
|
743
|
+
if (profileBlock)
|
|
744
|
+
partsToInject.push(profileBlock);
|
|
745
|
+
if (partsToInject.length > 0) {
|
|
746
|
+
const injectText = partsToInject.join("\n\n");
|
|
747
|
+
const contextPart = {
|
|
748
|
+
id: `prt_cerebro-context-${Date.now()}`,
|
|
749
|
+
sessionID: input.sessionID,
|
|
750
|
+
messageID: output.message.id,
|
|
751
|
+
type: "text",
|
|
752
|
+
text: injectText,
|
|
753
|
+
synthetic: true,
|
|
754
|
+
};
|
|
755
|
+
output.parts.unshift(contextPart);
|
|
756
|
+
logDebug("memoryInjectionHook profile injected (dedup path)", { sessionId: input.sessionID });
|
|
757
|
+
}
|
|
758
|
+
injectedSessions.add(input.sessionID);
|
|
759
|
+
if (profileInjected && profileIsFirstInjection) {
|
|
760
|
+
showToast(tui, "👨 Profile Injected", `${profileCountText} · all memories already injected`, "success", toastDelayMs);
|
|
761
|
+
}
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
// --- Token Budget Calculation ---
|
|
765
|
+
const profileChars = profileInjected ? profileBlock.length : 0;
|
|
766
|
+
const budgetRemaining = maxContentChars - profileChars;
|
|
767
|
+
if (budgetRemaining < 0) {
|
|
768
|
+
logDebug("memoryInjectionHook budget overflow", { profileChars, maxContentChars, deficit: -budgetRemaining });
|
|
769
|
+
}
|
|
770
|
+
const itemCount = clustered
|
|
771
|
+
? (clustered.cluster_summaries.length + clustered.standalone_memories.length)
|
|
772
|
+
: newResults.length;
|
|
773
|
+
const dynamicMaxContentLength = itemCount > 0
|
|
774
|
+
? Math.min(maxContentLength, Math.max(MIN_ITEM_CONTENT_CHARS, Math.floor(budgetRemaining / itemCount)))
|
|
775
|
+
: maxContentLength;
|
|
776
|
+
logDebug("memoryInjectionHook budget", {
|
|
777
|
+
maxContentChars, profileChars, budgetRemaining, itemCount,
|
|
778
|
+
configuredMax: maxContentLength, dynamicMax: dynamicMaxContentLength,
|
|
779
|
+
});
|
|
780
|
+
const block = clustered
|
|
781
|
+
? buildClusteredContextBlock(clustered, dynamicMaxContentLength)
|
|
782
|
+
: buildContextBlock(newResults, dynamicMaxContentLength);
|
|
783
|
+
// ★★★ Core change: inject via output.parts.unshift + synthetic:true ★★★
|
|
784
|
+
const partsToInject = [];
|
|
785
|
+
if (profileBlock)
|
|
786
|
+
partsToInject.push(profileBlock);
|
|
787
|
+
if (block)
|
|
788
|
+
partsToInject.push(block);
|
|
789
|
+
if (block)
|
|
790
|
+
partsToInject.push(FETCH_POLICY);
|
|
791
|
+
if (isKeywordTriggered)
|
|
792
|
+
partsToInject.push(KEYWORD_NUDGE);
|
|
793
|
+
if (partsToInject.length > 0) {
|
|
794
|
+
const injectText = partsToInject.join("\n\n");
|
|
795
|
+
const contextPart = {
|
|
796
|
+
id: `prt_cerebro-context-${Date.now()}`,
|
|
797
|
+
sessionID: input.sessionID,
|
|
798
|
+
messageID: output.message.id,
|
|
799
|
+
type: "text",
|
|
800
|
+
text: injectText,
|
|
801
|
+
synthetic: true,
|
|
802
|
+
};
|
|
803
|
+
output.parts.unshift(contextPart);
|
|
804
|
+
logDebug("memoryInjectionHook block injected to output.parts", {
|
|
805
|
+
sessionId: input.sessionID,
|
|
806
|
+
injectTextLen: injectText.length,
|
|
807
|
+
blockPreview: block?.slice(0, 200),
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
logDebug("memoryInjectionHook no content to inject", { sessionId: input.sessionID });
|
|
812
|
+
}
|
|
813
|
+
injectedSessions.add(input.sessionID);
|
|
814
|
+
if (isKeywordTriggered) {
|
|
815
|
+
keywordDetectedSessions.delete(input.sessionID);
|
|
816
|
+
}
|
|
817
|
+
const newIds = newResults.map((r) => r.memory.id);
|
|
818
|
+
injectedMemoryIds.set(input.sessionID, new Set([...existingIds, ...newIds]));
|
|
819
|
+
logDebug("memoryInjectionHook injection complete", { newIds: newIds.length, clustered: !!clustered, sessionId: input.sessionID });
|
|
820
|
+
await createEventAndReturn(newResults.length, storedMemoryIds.length, storedDiscardedIds.length, block || undefined);
|
|
821
|
+
const memDynamic = newResults.filter((r) => r.memory.memory_type === "fact" || r.memory.memory_type === "event").length;
|
|
822
|
+
const memStatic = newResults.filter((r) => r.memory.memory_type === "pinned" || r.memory.memory_type === "preference").length;
|
|
823
|
+
const memOther = newResults.length - memDynamic - memStatic;
|
|
824
|
+
let memCountMsg = "";
|
|
825
|
+
if (memDynamic > 0)
|
|
826
|
+
memCountMsg += `Dynamic(${memDynamic}) `;
|
|
827
|
+
if (memStatic > 0)
|
|
828
|
+
memCountMsg += `Static(${memStatic}) `;
|
|
829
|
+
if (memOther > 0)
|
|
830
|
+
memCountMsg += `Other(${memOther}) `;
|
|
831
|
+
const categories = categorize(newResults);
|
|
832
|
+
const catSummary = Array.from(categories.entries())
|
|
833
|
+
.map(([label, items]) => `${label}(${items.length})`)
|
|
834
|
+
.join(" · ");
|
|
835
|
+
let toastTitle;
|
|
836
|
+
let toastMessage;
|
|
837
|
+
if (clustered) {
|
|
838
|
+
const clusterCount = clustered.cluster_summaries.length;
|
|
839
|
+
const standaloneCount = clustered.standalone_memories.length;
|
|
840
|
+
toastTitle = `🧠 Context Injected · ${clusterCount} 主题簇${standaloneCount > 0 ? ` · ${standaloneCount} 补充` : ""}`;
|
|
841
|
+
toastMessage = profileInjected
|
|
842
|
+
? `Profile: ${profileCountText} · 聚合记忆展示`
|
|
843
|
+
: `聚合记忆展示`;
|
|
844
|
+
}
|
|
845
|
+
else {
|
|
846
|
+
toastTitle = `🧠 Context Injected · ${newResults.length} fragments`;
|
|
847
|
+
toastMessage = profileInjected
|
|
848
|
+
? `Profile: ${profileCountText} · Memories: ${memCountMsg.trim()}${catSummary ? ` · ${catSummary}` : ""}`
|
|
849
|
+
: `${memCountMsg.trim()}${catSummary ? ` · ${catSummary}` : ""}`;
|
|
850
|
+
}
|
|
851
|
+
showToast(tui, toastTitle, toastMessage, "success", toastDelayMs);
|
|
852
|
+
}
|
|
853
|
+
catch (err) {
|
|
854
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
855
|
+
if (errMsg.includes("[cerebro]")) {
|
|
856
|
+
const cleanMsg = errMsg.replace(/^\[cerebro\]\s*/, "");
|
|
857
|
+
if (cleanMsg.startsWith("500")) {
|
|
858
|
+
showToast(tui, "🧠 Cerebro Server Error", cleanMsg.substring(0, 200), "error");
|
|
859
|
+
}
|
|
860
|
+
else if (cleanMsg.includes("timed out")) {
|
|
861
|
+
showToast(tui, "🧠 Cerebro Service Timeout", cleanMsg.substring(0, 100), "error");
|
|
862
|
+
}
|
|
863
|
+
else {
|
|
864
|
+
showToast(tui, "🧠 Cerebro Error", cleanMsg.substring(0, 150), "error");
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
else if (errMsg.includes("fetch") || errMsg.includes("network")) {
|
|
868
|
+
showToast(tui, "🧠 Cerebro Service Unavailable", "Network error · check API connection", "error");
|
|
869
|
+
}
|
|
870
|
+
else {
|
|
871
|
+
showToast(tui, "🧠 Memory Recall Error", errMsg.substring(0, 100), "error");
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
};
|
|
875
|
+
}
|
|
554
876
|
export function keywordDetectionHook(_client, _containerTags, threshold, _tui, _ingestMode = "smart", config = {}, agentId) {
|
|
555
877
|
const effectiveAgentId = agentId || process.env.OMEM_AGENT_ID || "opencode";
|
|
556
878
|
return async (input, output) => {
|
|
@@ -584,6 +906,50 @@ export function keywordDetectionHook(_client, _containerTags, threshold, _tui, _
|
|
|
584
906
|
}
|
|
585
907
|
};
|
|
586
908
|
}
|
|
909
|
+
export function createCerebroCompactionPrompt(context, projectMemories) {
|
|
910
|
+
const sections = [
|
|
911
|
+
"[Cerebro Compaction Context]",
|
|
912
|
+
"",
|
|
913
|
+
"## 1. User's Original Request",
|
|
914
|
+
"Preserve the user's verbatim original request from the conversation above.",
|
|
915
|
+
"",
|
|
916
|
+
"## 2. Final Goal",
|
|
917
|
+
"What is the ultimate objective the user wants to achieve?",
|
|
918
|
+
"",
|
|
919
|
+
"## 3. Work Completed",
|
|
920
|
+
"List all completed work with file paths and technical decisions made.",
|
|
921
|
+
"",
|
|
922
|
+
"## 4. Remaining Tasks",
|
|
923
|
+
"What is still unfinished or pending?",
|
|
924
|
+
"",
|
|
925
|
+
"## 5. Prohibited Actions",
|
|
926
|
+
"Key constraints and forbidden operations to remember.",
|
|
927
|
+
"",
|
|
928
|
+
"## 6. Existing Project Knowledge",
|
|
929
|
+
];
|
|
930
|
+
if (projectMemories.length > 0) {
|
|
931
|
+
const memBlock = projectMemories
|
|
932
|
+
.slice(0, 10)
|
|
933
|
+
.map((r) => {
|
|
934
|
+
const content = r.memory.content ?? "";
|
|
935
|
+
const truncated = content.length > 200 ? content.slice(0, 200) + "..." : content;
|
|
936
|
+
return ` - [${r.memory.category ?? "general"}] ${truncated}`;
|
|
937
|
+
})
|
|
938
|
+
.join("\n");
|
|
939
|
+
sections.push(memBlock);
|
|
940
|
+
}
|
|
941
|
+
else {
|
|
942
|
+
sections.push(" (No project memories retrieved)");
|
|
943
|
+
}
|
|
944
|
+
if (context.length > 0) {
|
|
945
|
+
sections.push("");
|
|
946
|
+
sections.push("### Additional Context");
|
|
947
|
+
sections.push(...context);
|
|
948
|
+
}
|
|
949
|
+
sections.push("");
|
|
950
|
+
sections.push("IMPORTANT: Output must preserve the user's original language (Chinese/English/etc). Do not translate.");
|
|
951
|
+
return sections.join("\n");
|
|
952
|
+
}
|
|
587
953
|
export function compactingHook(client, containerTags, tui, ingestMode = "smart", isAutoStoreEnabled, getMainSessionId, sdkClient, config = {}, agentId, directory) {
|
|
588
954
|
const effectiveAgentId = agentId || process.env.OMEM_AGENT_ID || "opencode";
|
|
589
955
|
return async (input, output) => {
|
|
@@ -591,20 +957,21 @@ export function compactingHook(client, containerTags, tui, ingestMode = "smart",
|
|
|
591
957
|
// Search (read) always runs — even readonly agents need context during compacting
|
|
592
958
|
try {
|
|
593
959
|
const results = await client.searchMemories("*", 20, undefined, containerTags);
|
|
594
|
-
const
|
|
595
|
-
if (
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
960
|
+
const compactionPrompt = createCerebroCompactionPrompt(output.context, results);
|
|
961
|
+
if (output.prompt !== undefined) {
|
|
962
|
+
output.prompt = compactionPrompt;
|
|
963
|
+
}
|
|
964
|
+
else if (output.context.length > 0) {
|
|
965
|
+
output.context[output.context.length - 1] += "\n\n" + compactionPrompt;
|
|
966
|
+
}
|
|
967
|
+
else {
|
|
968
|
+
output.context.push(compactionPrompt);
|
|
969
|
+
}
|
|
970
|
+
if (output.context.length > 0) {
|
|
971
|
+
output.context[output.context.length - 1] += "\n\n" + FETCH_POLICY;
|
|
972
|
+
}
|
|
973
|
+
else {
|
|
974
|
+
output.context.push(FETCH_POLICY);
|
|
608
975
|
}
|
|
609
976
|
// 将compacting搜索结果的ID写入injectedMemoryIds,避免后续autoRecall重复注入
|
|
610
977
|
if (input.sessionID && results.length > 0) {
|
|
@@ -800,8 +1167,17 @@ export function compactingHook(client, containerTags, tui, ingestMode = "smart",
|
|
|
800
1167
|
logInfo("compactingHook: storing compact summary", {
|
|
801
1168
|
summaryLen: summaryText.length, msgId: compactMsg.info?.id,
|
|
802
1169
|
});
|
|
1170
|
+
// Dedup check: 30s cooldown per session+content hash
|
|
1171
|
+
const summaryHash = `${pollSessionId}:${hashString(summaryText)}`;
|
|
1172
|
+
const lastCompacting = compactingSummaryCooldown.get(summaryHash);
|
|
1173
|
+
if (lastCompacting && Date.now() - lastCompacting < 30000) {
|
|
1174
|
+
logDebug("compactingHook summary dedup", { sessionId: pollSessionId });
|
|
1175
|
+
break;
|
|
1176
|
+
}
|
|
1177
|
+
compactingSummaryCooldown.set(summaryHash, Date.now());
|
|
1178
|
+
const prefixedSummary = `[Session Summary] ${summaryText}`;
|
|
803
1179
|
try {
|
|
804
|
-
const result = await client.ingestMessages([{ role: "user", content:
|
|
1180
|
+
const result = await client.ingestMessages([{ role: "user", content: prefixedSummary }], {
|
|
805
1181
|
mode: ingestMode,
|
|
806
1182
|
tags: [...containerTags, "auto-capture", "compact-summary"],
|
|
807
1183
|
sessionId: pollEffectiveSessionId,
|
|
@@ -957,10 +1333,10 @@ export function buildWhisperText(toolNames, maxToolNames) {
|
|
|
957
1333
|
return null;
|
|
958
1334
|
const lines = ["<cerebro-memory-activation>"];
|
|
959
1335
|
if (toolNames.length <= maxToolNames) {
|
|
960
|
-
lines.push(`
|
|
1336
|
+
lines.push(`Before using ${toolNames.join(", ")}, memory_search() may surface relevant past decisions or patterns. Brief recall → better outcomes.`);
|
|
961
1337
|
}
|
|
962
1338
|
else {
|
|
963
|
-
lines.push("Before you act —
|
|
1339
|
+
lines.push("Before you act — memory_search() surfaces cross-session context: past decisions, user preferences, hard-won insights. The strongest responses are built on remembered context.");
|
|
964
1340
|
}
|
|
965
1341
|
lines.push("</cerebro-memory-activation>");
|
|
966
1342
|
return lines.join("\n");
|