@xopcai/xopc 0.0.25 → 0.0.27
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/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/agents-w8_jzuiX.js +216 -0
- package/dist/gateway/static/root/assets/agents-w8_jzuiX.js.map +1 -0
- package/dist/gateway/static/root/assets/{apps-page-DbzO48lg.js → apps-page-CBBh_Ww8.js} +2 -2
- package/dist/gateway/static/root/assets/{apps-page-DbzO48lg.js.map → apps-page-CBBh_Ww8.js.map} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-DUKRPC7C.js +9 -0
- package/dist/gateway/static/root/assets/{channels-settings-CeGoU9v8.js.map → channels-settings-DUKRPC7C.js.map} +1 -1
- package/dist/gateway/static/root/assets/cron-page-S18t1yG-.js +2 -0
- package/dist/gateway/static/root/assets/{cron-page-DpEYUvxB.js.map → cron-page-S18t1yG-.js.map} +1 -1
- package/dist/gateway/static/root/assets/{cron-utils-Cvv0F3pa.js → cron-utils-08gdQfl9.js} +2 -2
- package/dist/gateway/static/root/assets/{cron-utils-Cvv0F3pa.js.map → cron-utils-08gdQfl9.js.map} +1 -1
- package/dist/gateway/static/root/assets/dist-C1MrygQH.js +2 -0
- package/dist/gateway/static/root/assets/{dist-C41N3YrO.js.map → dist-C1MrygQH.js.map} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CkkYZjNP.js → extension-debug-page-DN3HKUGS.js} +2 -2
- package/dist/gateway/static/root/assets/{extension-debug-page-CkkYZjNP.js.map → extension-debug-page-DN3HKUGS.js.map} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BjUIPVNG.js → extension-page-CoFDHZtZ.js} +2 -2
- package/dist/gateway/static/root/assets/{extension-page-BjUIPVNG.js.map → extension-page-CoFDHZtZ.js.map} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CwuFDOdk.js → extension-settings-page-BcPCu_Go.js} +2 -2
- package/dist/gateway/static/root/assets/{extension-settings-page-CwuFDOdk.js.map → extension-settings-page-BcPCu_Go.js.map} +1 -1
- package/dist/gateway/static/root/assets/index-OT4cGzon.css +1 -0
- package/dist/gateway/static/root/assets/index-PfkB8N37.js +4734 -0
- package/dist/gateway/static/root/assets/index-PfkB8N37.js.map +1 -0
- package/dist/gateway/static/root/assets/logs-page-DoWe1GWy.js +2 -0
- package/dist/gateway/static/root/assets/{logs-page-BtwGPuw2.js.map → logs-page-DoWe1GWy.js.map} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-2uOYwEwd.js +2 -0
- package/dist/gateway/static/root/assets/{sessions-page-4rKFDn2k.js.map → sessions-page-2uOYwEwd.js.map} +1 -1
- package/dist/gateway/static/root/assets/settings-page-fQWswCuq.js +2 -0
- package/dist/gateway/static/root/assets/settings-page-fQWswCuq.js.map +1 -0
- package/dist/gateway/static/root/assets/skills-page-BmBDCEbY.js +3 -0
- package/dist/gateway/static/root/assets/{skills-page-_siDuHeF.js.map → skills-page-BmBDCEbY.js.map} +1 -1
- package/dist/gateway/static/root/index.html +2 -2
- package/dist/package.js +1 -1
- package/dist/src/agent/memory/dreaming/config.d.ts +37 -9
- package/dist/src/agent/memory/dreaming/config.js +60 -18
- package/dist/src/agent/memory/dreaming/config.js.map +1 -1
- package/dist/src/agent/memory/dreaming/constants.d.ts +22 -1
- package/dist/src/agent/memory/dreaming/constants.js +26 -2
- package/dist/src/agent/memory/dreaming/constants.js.map +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.d.ts +5 -6
- package/dist/src/agent/memory/dreaming/deep-promotion.js +90 -156
- package/dist/src/agent/memory/dreaming/deep-promotion.js.map +1 -1
- package/dist/src/agent/memory/dreaming/events.d.ts +36 -0
- package/dist/src/agent/memory/dreaming/events.js +44 -0
- package/dist/src/agent/memory/dreaming/events.js.map +1 -0
- package/dist/src/agent/memory/dreaming/last-run.d.ts +80 -0
- package/dist/src/agent/memory/dreaming/last-run.js +98 -0
- package/dist/src/agent/memory/dreaming/last-run.js.map +1 -0
- package/dist/src/agent/memory/dreaming/light-sweep.d.ts +19 -0
- package/dist/src/agent/memory/dreaming/light-sweep.js +328 -0
- package/dist/src/agent/memory/dreaming/light-sweep.js.map +1 -0
- package/dist/src/agent/memory/dreaming/preview.d.ts +3 -1
- package/dist/src/agent/memory/dreaming/preview.js +11 -90
- package/dist/src/agent/memory/dreaming/preview.js.map +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.d.ts +21 -0
- package/dist/src/agent/memory/dreaming/rem-patterns.js +286 -0
- package/dist/src/agent/memory/dreaming/rem-patterns.js.map +1 -0
- package/dist/src/agent/memory/dreaming/short-term-store.d.ts +20 -0
- package/dist/src/agent/memory/dreaming/short-term-store.js +25 -15
- package/dist/src/agent/memory/dreaming/short-term-store.js.map +1 -1
- package/dist/src/agent/memory/dreaming/utils.d.ts +42 -0
- package/dist/src/agent/memory/dreaming/utils.js +141 -0
- package/dist/src/agent/memory/dreaming/utils.js.map +1 -0
- package/dist/src/agent/orchestration/agent-orchestrator.js +54 -12
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/service.js +54 -28
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/config/schema.d.ts +54 -0
- package/dist/src/config/schema.js +34 -8
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +18 -0
- package/dist/src/gateway/hono/routes/dreaming.js +105 -15
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +26 -1
- package/dist/src/gateway/hono/routes/models.js.map +1 -1
- package/dist/src/gateway/hono/routes/public-gateway.js +1 -0
- package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agents-C_bPhtBs.js +0 -216
- package/dist/gateway/static/root/assets/agents-C_bPhtBs.js.map +0 -1
- package/dist/gateway/static/root/assets/channels-settings-CeGoU9v8.js +0 -9
- package/dist/gateway/static/root/assets/cron-page-DpEYUvxB.js +0 -2
- package/dist/gateway/static/root/assets/dist-C41N3YrO.js +0 -2
- package/dist/gateway/static/root/assets/index-DwzwDCjW.js +0 -150
- package/dist/gateway/static/root/assets/index-DwzwDCjW.js.map +0 -1
- package/dist/gateway/static/root/assets/index-dhtHG1nU.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-BtwGPuw2.js +0 -2
- package/dist/gateway/static/root/assets/sessions-page-4rKFDn2k.js +0 -2
- package/dist/gateway/static/root/assets/settings-page-iYLSxQYc.js +0 -2
- package/dist/gateway/static/root/assets/settings-page-iYLSxQYc.js.map +0 -1
- package/dist/gateway/static/root/assets/skills-page-_siDuHeF.js +0 -3
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DEFAULT_DEEP_CRON, DEFAULT_LIGHT_CRON, DEFAULT_REM_CRON } from "./constants.js";
|
|
1
2
|
//#region src/agent/memory/dreaming/config.ts
|
|
2
3
|
function clampScore(value, fallback) {
|
|
3
4
|
if (!Number.isFinite(value)) return fallback;
|
|
@@ -9,36 +10,77 @@ function toPositiveInt(value, fallback) {
|
|
|
9
10
|
const floored = Math.floor(num);
|
|
10
11
|
return floored > 0 ? floored : fallback;
|
|
11
12
|
}
|
|
13
|
+
function toNonNegInt(value, fallback) {
|
|
14
|
+
const num = typeof value === "string" ? Number(value) : Number(value);
|
|
15
|
+
if (!Number.isFinite(num)) return fallback;
|
|
16
|
+
const floored = Math.floor(num);
|
|
17
|
+
return floored >= 0 ? floored : fallback;
|
|
18
|
+
}
|
|
19
|
+
function trimmedStringOr(value, fallback) {
|
|
20
|
+
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
21
|
+
}
|
|
22
|
+
function optionalTrimmedString(value) {
|
|
23
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
24
|
+
}
|
|
12
25
|
/**
|
|
13
|
-
*
|
|
26
|
+
* Resolve the full three-phase dreaming config from the app Config.
|
|
14
27
|
*
|
|
15
|
-
*
|
|
16
|
-
* Expected shape:
|
|
17
|
-
* `agents.defaults.memory.dreaming.{ enabled, frequency, timezone, phases.deep.{minScore,minRecallCount,limit} }`
|
|
28
|
+
* Reads through `any` so it can ship independently of the schema evolution.
|
|
29
|
+
* Expected shape: `agents.defaults.memory.dreaming.{ enabled, frequency, timezone, phases.{light,deep,rem}.* }`
|
|
18
30
|
*/
|
|
19
31
|
function resolveDreamingConfig(cfg) {
|
|
20
32
|
const dreaming = cfg?.agents?.defaults?.memory?.dreaming;
|
|
21
33
|
const enabled = dreaming?.enabled === true;
|
|
22
|
-
const frequency =
|
|
23
|
-
const timezone =
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
34
|
+
const frequency = trimmedStringOr(dreaming?.frequency, DEFAULT_DEEP_CRON);
|
|
35
|
+
const timezone = optionalTrimmedString(dreaming?.timezone);
|
|
36
|
+
const lightRaw = dreaming?.phases?.light ?? {};
|
|
37
|
+
const light = {
|
|
38
|
+
enabled: enabled && lightRaw?.enabled !== false,
|
|
39
|
+
cron: trimmedStringOr(lightRaw?.cron, DEFAULT_LIGHT_CRON),
|
|
40
|
+
lookbackDays: toPositiveInt(lightRaw?.lookbackDays, 2),
|
|
41
|
+
limit: toNonNegInt(lightRaw?.limit, 100),
|
|
42
|
+
dedupeSimilarity: clampScore(Number(lightRaw?.dedupeSimilarity), .9)
|
|
43
|
+
};
|
|
44
|
+
const deepRaw = dreaming?.phases?.deep ?? {};
|
|
45
|
+
const deep = {
|
|
46
|
+
enabled: enabled && deepRaw?.enabled !== false,
|
|
47
|
+
cron: trimmedStringOr(deepRaw?.cron, frequency),
|
|
48
|
+
minScore: clampScore(Number(deepRaw?.minScore), .8),
|
|
49
|
+
minRecallCount: toPositiveInt(deepRaw?.minRecallCount, 3),
|
|
50
|
+
minUniqueQueries: toPositiveInt(deepRaw?.minUniqueQueries, 3),
|
|
51
|
+
limit: toNonNegInt(deepRaw?.limit, 10),
|
|
52
|
+
recencyHalfLifeDays: toPositiveInt(deepRaw?.recencyHalfLifeDays, 14),
|
|
53
|
+
maxAgeDays: toPositiveInt(deepRaw?.maxAgeDays, 30)
|
|
54
|
+
};
|
|
55
|
+
const remRaw = dreaming?.phases?.rem ?? {};
|
|
56
|
+
const rem = {
|
|
57
|
+
enabled: enabled && remRaw?.enabled !== false,
|
|
58
|
+
cron: trimmedStringOr(remRaw?.cron, DEFAULT_REM_CRON),
|
|
59
|
+
lookbackDays: toPositiveInt(remRaw?.lookbackDays, 7),
|
|
60
|
+
limit: toNonNegInt(remRaw?.limit, 10),
|
|
61
|
+
minPatternStrength: clampScore(Number(remRaw?.minPatternStrength), .75)
|
|
62
|
+
};
|
|
29
63
|
return {
|
|
30
64
|
enabled,
|
|
31
65
|
frequency,
|
|
32
66
|
...timezone ? { timezone } : {},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
67
|
+
phases: {
|
|
68
|
+
light,
|
|
69
|
+
deep,
|
|
70
|
+
rem
|
|
71
|
+
},
|
|
72
|
+
deep
|
|
39
73
|
};
|
|
40
74
|
}
|
|
75
|
+
/** Get the cron expression for a specific phase from resolved config. */
|
|
76
|
+
function getPhaseCron(config, phase) {
|
|
77
|
+
return config.phases[phase].cron;
|
|
78
|
+
}
|
|
79
|
+
/** Check if a specific phase is enabled (global + phase-level). */
|
|
80
|
+
function isPhaseEnabled(config, phase) {
|
|
81
|
+
return config.enabled && config.phases[phase].enabled;
|
|
82
|
+
}
|
|
41
83
|
//#endregion
|
|
42
|
-
export { resolveDreamingConfig };
|
|
84
|
+
export { getPhaseCron, isPhaseEnabled, resolveDreamingConfig };
|
|
43
85
|
|
|
44
86
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":["anyCfg"],"sources":["../../../../../src/agent/memory/dreaming/config.ts"],"sourcesContent":["import type { Config } from '../../../config/schema.js';\n\nexport type
|
|
1
|
+
{"version":3,"file":"config.js","names":["anyCfg"],"sources":["../../../../../src/agent/memory/dreaming/config.ts"],"sourcesContent":["import type { Config } from '../../../config/schema.js';\nimport {\n DEFAULT_DEEP_CRON,\n DEFAULT_LIGHT_CRON,\n DEFAULT_MAX_AGE_DAYS,\n DEFAULT_RECENCY_HALF_LIFE_DAYS,\n DEFAULT_REM_CRON,\n type DreamingPhaseId,\n} from './constants.js';\n\n// ── Phase config types ─────────────────────────────────────────────────\n\nexport type DreamingLightConfig = {\n enabled: boolean;\n cron: string;\n lookbackDays: number;\n limit: number;\n dedupeSimilarity: number;\n};\n\nexport type DreamingDeepConfig = {\n enabled: boolean;\n cron: string;\n minScore: number;\n minRecallCount: number;\n minUniqueQueries: number;\n limit: number;\n recencyHalfLifeDays: number;\n maxAgeDays: number;\n};\n\nexport type DreamingRemConfig = {\n enabled: boolean;\n cron: string;\n lookbackDays: number;\n limit: number;\n minPatternStrength: number;\n};\n\nexport type DreamingResolvedConfig = {\n enabled: boolean;\n frequency: string;\n timezone?: string;\n phases: {\n light: DreamingLightConfig;\n deep: DreamingDeepConfig;\n rem: DreamingRemConfig;\n };\n deep: DreamingDeepConfig;\n};\n\n// ── Helpers ────────────────────────────────────────────────────────────\n\nfunction clampScore(value: number, fallback: number): number {\n if (!Number.isFinite(value)) return fallback;\n return Math.max(0, Math.min(1, value));\n}\n\nfunction toPositiveInt(value: unknown, fallback: number): number {\n const num = typeof value === 'string' ? Number(value) : Number(value);\n if (!Number.isFinite(num)) return fallback;\n const floored = Math.floor(num);\n return floored > 0 ? floored : fallback;\n}\n\nfunction toNonNegInt(value: unknown, fallback: number): number {\n const num = typeof value === 'string' ? Number(value) : Number(value);\n if (!Number.isFinite(num)) return fallback;\n const floored = Math.floor(num);\n return floored >= 0 ? floored : fallback;\n}\n\nfunction trimmedStringOr(value: unknown, fallback: string): string {\n return typeof value === 'string' && value.trim() ? value.trim() : fallback;\n}\n\nfunction optionalTrimmedString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\n// ── Resolver ───────────────────────────────────────────────────────────\n\n/**\n * Resolve the full three-phase dreaming config from the app Config.\n *\n * Reads through `any` so it can ship independently of the schema evolution.\n * Expected shape: `agents.defaults.memory.dreaming.{ enabled, frequency, timezone, phases.{light,deep,rem}.* }`\n */\nexport function resolveDreamingConfig(cfg: Config | undefined): DreamingResolvedConfig {\n const anyCfg = cfg as any;\n const dreaming = anyCfg?.agents?.defaults?.memory?.dreaming;\n const enabled = dreaming?.enabled === true;\n\n const frequency = trimmedStringOr(dreaming?.frequency, DEFAULT_DEEP_CRON);\n const timezone = optionalTrimmedString(dreaming?.timezone);\n\n // ── Light phase ────────────────────────────────────────────────────\n const lightRaw = dreaming?.phases?.light ?? {};\n const light: DreamingLightConfig = {\n enabled: enabled && lightRaw?.enabled !== false,\n cron: trimmedStringOr(lightRaw?.cron, DEFAULT_LIGHT_CRON),\n lookbackDays: toPositiveInt(lightRaw?.lookbackDays, 2),\n limit: toNonNegInt(lightRaw?.limit, 100),\n dedupeSimilarity: clampScore(Number(lightRaw?.dedupeSimilarity), 0.9),\n };\n\n // ── Deep phase ─────────────────────────────────────────────────────\n const deepRaw = dreaming?.phases?.deep ?? {};\n const deep: DreamingDeepConfig = {\n enabled: enabled && deepRaw?.enabled !== false,\n cron: trimmedStringOr(deepRaw?.cron, frequency),\n minScore: clampScore(Number(deepRaw?.minScore), 0.8),\n minRecallCount: toPositiveInt(deepRaw?.minRecallCount, 3),\n minUniqueQueries: toPositiveInt(deepRaw?.minUniqueQueries, 3),\n limit: toNonNegInt(deepRaw?.limit, 10),\n recencyHalfLifeDays: toPositiveInt(deepRaw?.recencyHalfLifeDays, DEFAULT_RECENCY_HALF_LIFE_DAYS),\n maxAgeDays: toPositiveInt(deepRaw?.maxAgeDays, DEFAULT_MAX_AGE_DAYS),\n };\n\n // ── REM phase ──────────────────────────────────────────────────────\n const remRaw = dreaming?.phases?.rem ?? {};\n const rem: DreamingRemConfig = {\n enabled: enabled && remRaw?.enabled !== false,\n cron: trimmedStringOr(remRaw?.cron, DEFAULT_REM_CRON),\n lookbackDays: toPositiveInt(remRaw?.lookbackDays, 7),\n limit: toNonNegInt(remRaw?.limit, 10),\n minPatternStrength: clampScore(Number(remRaw?.minPatternStrength), 0.75),\n };\n\n return {\n enabled,\n frequency,\n ...(timezone ? { timezone } : {}),\n phases: { light, deep, rem },\n deep,\n };\n}\n\n/** Get the cron expression for a specific phase from resolved config. */\nexport function getPhaseCron(config: DreamingResolvedConfig, phase: DreamingPhaseId): string {\n return config.phases[phase].cron;\n}\n\n/** Check if a specific phase is enabled (global + phase-level). */\nexport function isPhaseEnabled(config: DreamingResolvedConfig, phase: DreamingPhaseId): boolean {\n return config.enabled && config.phases[phase].enabled;\n}\n\n"],"mappings":";;AAqDA,SAAS,WAAW,OAAe,UAA0B;AAC3D,KAAI,CAAC,OAAO,SAAS,MAAM,CAAE,QAAO;AACpC,QAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC;;AAGxC,SAAS,cAAc,OAAgB,UAA0B;CAC/D,MAAM,MAAM,OAAO,UAAU,WAAW,OAAO,MAAM,GAAG,OAAO,MAAM;AACrE,KAAI,CAAC,OAAO,SAAS,IAAI,CAAE,QAAO;CAClC,MAAM,UAAU,KAAK,MAAM,IAAI;AAC/B,QAAO,UAAU,IAAI,UAAU;;AAGjC,SAAS,YAAY,OAAgB,UAA0B;CAC7D,MAAM,MAAM,OAAO,UAAU,WAAW,OAAO,MAAM,GAAG,OAAO,MAAM;AACrE,KAAI,CAAC,OAAO,SAAS,IAAI,CAAE,QAAO;CAClC,MAAM,UAAU,KAAK,MAAM,IAAI;AAC/B,QAAO,WAAW,IAAI,UAAU;;AAGlC,SAAS,gBAAgB,OAAgB,UAA0B;AACjE,QAAO,OAAO,UAAU,YAAY,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG;;AAGpE,SAAS,sBAAsB,OAAoC;AACjE,QAAO,OAAO,UAAU,YAAY,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG,KAAA;;;;;;;;AAWpE,SAAgB,sBAAsB,KAAiD;CAErF,MAAM,WAAWA,KAAQ,QAAQ,UAAU,QAAQ;CACnD,MAAM,UAAU,UAAU,YAAY;CAEtC,MAAM,YAAY,gBAAgB,UAAU,WAAW,kBAAkB;CACzE,MAAM,WAAW,sBAAsB,UAAU,SAAS;CAG1D,MAAM,WAAW,UAAU,QAAQ,SAAS,EAAE;CAC9C,MAAM,QAA6B;EACjC,SAAS,WAAW,UAAU,YAAY;EAC1C,MAAM,gBAAgB,UAAU,MAAM,mBAAmB;EACzD,cAAc,cAAc,UAAU,cAAc,EAAE;EACtD,OAAO,YAAY,UAAU,OAAO,IAAI;EACxC,kBAAkB,WAAW,OAAO,UAAU,iBAAiB,EAAE,GAAI;EACtE;CAGD,MAAM,UAAU,UAAU,QAAQ,QAAQ,EAAE;CAC5C,MAAM,OAA2B;EAC/B,SAAS,WAAW,SAAS,YAAY;EACzC,MAAM,gBAAgB,SAAS,MAAM,UAAU;EAC/C,UAAU,WAAW,OAAO,SAAS,SAAS,EAAE,GAAI;EACpD,gBAAgB,cAAc,SAAS,gBAAgB,EAAE;EACzD,kBAAkB,cAAc,SAAS,kBAAkB,EAAE;EAC7D,OAAO,YAAY,SAAS,OAAO,GAAG;EACtC,qBAAqB,cAAc,SAAS,qBAAA,GAAoD;EAChG,YAAY,cAAc,SAAS,YAAA,GAAiC;EACrE;CAGD,MAAM,SAAS,UAAU,QAAQ,OAAO,EAAE;CAC1C,MAAM,MAAyB;EAC7B,SAAS,WAAW,QAAQ,YAAY;EACxC,MAAM,gBAAgB,QAAQ,MAAM,iBAAiB;EACrD,cAAc,cAAc,QAAQ,cAAc,EAAE;EACpD,OAAO,YAAY,QAAQ,OAAO,GAAG;EACrC,oBAAoB,WAAW,OAAO,QAAQ,mBAAmB,EAAE,IAAK;EACzE;AAED,QAAO;EACL;EACA;EACA,GAAI,WAAW,EAAE,UAAU,GAAG,EAAE;EAChC,QAAQ;GAAE;GAAO;GAAM;GAAK;EAC5B;EACD;;;AAIH,SAAgB,aAAa,QAAgC,OAAgC;AAC3F,QAAO,OAAO,OAAO,OAAO;;;AAI9B,SAAgB,eAAe,QAAgC,OAAiC;AAC9F,QAAO,OAAO,WAAW,OAAO,OAAO,OAAO"}
|
|
@@ -1,8 +1,29 @@
|
|
|
1
|
+
export type DreamingPhaseId = 'light' | 'deep' | 'rem';
|
|
2
|
+
export declare const DREAMING_PHASES: readonly DreamingPhaseId[];
|
|
1
3
|
export declare const DREAMING_SWEEP_TOKEN = "__xopc_memory_dreaming_sweep__";
|
|
2
|
-
export declare const
|
|
4
|
+
export declare const DREAMING_LIGHT_SWEEP_TOKEN = "__xopc_memory_dreaming_light_sweep__";
|
|
5
|
+
export declare const DREAMING_REM_SWEEP_TOKEN = "__xopc_memory_dreaming_rem_sweep__";
|
|
3
6
|
export declare const DREAMING_CRON_TAG = "[managed-by=xopc.memory.dreaming]";
|
|
7
|
+
export declare const DREAMING_CRON_NAME = "Memory Dreaming - Deep Promotion";
|
|
8
|
+
export declare const DREAMING_LIGHT_CRON_NAME = "Memory Dreaming - Light Sweep";
|
|
9
|
+
export declare const DREAMING_REM_CRON_NAME = "Memory Dreaming - REM Patterns";
|
|
10
|
+
export declare const DEFAULT_DEEP_CRON = "0 3 * * *";
|
|
11
|
+
export declare const DEFAULT_LIGHT_CRON = "0 */6 * * *";
|
|
12
|
+
export declare const DEFAULT_REM_CRON = "0 5 * * 0";
|
|
13
|
+
export declare const DEFAULT_RECENCY_HALF_LIFE_DAYS = 14;
|
|
14
|
+
export declare const DEFAULT_MAX_AGE_DAYS = 30;
|
|
15
|
+
/** Milliseconds in one day (used for time-decay calculations). */
|
|
16
|
+
export declare const MS_PER_DAY = 86400000;
|
|
17
|
+
/** Weight applied to recall-count reinforcement (logarithmic boost). */
|
|
18
|
+
export declare const REINFORCEMENT_WEIGHT = 0.12;
|
|
19
|
+
/** Weight applied to signal-diversity bonus. */
|
|
20
|
+
export declare const DIVERSITY_WEIGHT = 0.08;
|
|
21
|
+
/** Number of signal dimensions used for diversity calculation. */
|
|
22
|
+
export declare const DIVERSITY_DIMENSION_COUNT = 4;
|
|
4
23
|
export declare const DREAMING_DIR_RELATIVE: string;
|
|
5
24
|
export declare const SHORT_TERM_RECALL_STORE_RELATIVE: string;
|
|
6
25
|
export declare const SHORT_TERM_PROMOTION_LOCK_RELATIVE: string;
|
|
7
26
|
export declare const DREAMING_LAST_RUN_RELATIVE: string;
|
|
27
|
+
export declare const DREAMING_EVENTS_LOG_RELATIVE: string;
|
|
8
28
|
export declare const MEMORY_MD_FILENAME = "MEMORY.md";
|
|
29
|
+
export declare const DREAMS_MD_FILENAME = "DREAMS.md";
|
|
@@ -1,14 +1,38 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
//#region src/agent/memory/dreaming/constants.ts
|
|
3
|
+
const DREAMING_PHASES = [
|
|
4
|
+
"light",
|
|
5
|
+
"deep",
|
|
6
|
+
"rem"
|
|
7
|
+
];
|
|
3
8
|
const DREAMING_SWEEP_TOKEN = "__xopc_memory_dreaming_sweep__";
|
|
4
|
-
const
|
|
9
|
+
const DREAMING_LIGHT_SWEEP_TOKEN = "__xopc_memory_dreaming_light_sweep__";
|
|
10
|
+
const DREAMING_REM_SWEEP_TOKEN = "__xopc_memory_dreaming_rem_sweep__";
|
|
5
11
|
const DREAMING_CRON_TAG = "[managed-by=xopc.memory.dreaming]";
|
|
12
|
+
const DREAMING_CRON_NAME = "Memory Dreaming - Deep Promotion";
|
|
13
|
+
const DREAMING_LIGHT_CRON_NAME = "Memory Dreaming - Light Sweep";
|
|
14
|
+
const DREAMING_REM_CRON_NAME = "Memory Dreaming - REM Patterns";
|
|
15
|
+
const DEFAULT_DEEP_CRON = "0 3 * * *";
|
|
16
|
+
const DEFAULT_LIGHT_CRON = "0 */6 * * *";
|
|
17
|
+
const DEFAULT_REM_CRON = "0 5 * * 0";
|
|
18
|
+
const DEFAULT_RECENCY_HALF_LIFE_DAYS = 14;
|
|
19
|
+
const DEFAULT_MAX_AGE_DAYS = 30;
|
|
20
|
+
/** Milliseconds in one day (used for time-decay calculations). */
|
|
21
|
+
const MS_PER_DAY = 864e5;
|
|
22
|
+
/** Weight applied to recall-count reinforcement (logarithmic boost). */
|
|
23
|
+
const REINFORCEMENT_WEIGHT = .12;
|
|
24
|
+
/** Weight applied to signal-diversity bonus. */
|
|
25
|
+
const DIVERSITY_WEIGHT = .08;
|
|
26
|
+
/** Number of signal dimensions used for diversity calculation. */
|
|
27
|
+
const DIVERSITY_DIMENSION_COUNT = 4;
|
|
6
28
|
const DREAMING_DIR_RELATIVE = path.join("memory", ".dreams");
|
|
7
29
|
const SHORT_TERM_RECALL_STORE_RELATIVE = path.join(DREAMING_DIR_RELATIVE, "short-term-recall.json");
|
|
8
30
|
const SHORT_TERM_PROMOTION_LOCK_RELATIVE = path.join(DREAMING_DIR_RELATIVE, "short-term-promotion.lock");
|
|
9
31
|
const DREAMING_LAST_RUN_RELATIVE = path.join(DREAMING_DIR_RELATIVE, "last-run.json");
|
|
32
|
+
const DREAMING_EVENTS_LOG_RELATIVE = path.join(DREAMING_DIR_RELATIVE, "events.jsonl");
|
|
10
33
|
const MEMORY_MD_FILENAME = "MEMORY.md";
|
|
34
|
+
const DREAMS_MD_FILENAME = "DREAMS.md";
|
|
11
35
|
//#endregion
|
|
12
|
-
export { DREAMING_CRON_NAME, DREAMING_CRON_TAG, DREAMING_DIR_RELATIVE, DREAMING_LAST_RUN_RELATIVE, DREAMING_SWEEP_TOKEN, MEMORY_MD_FILENAME, SHORT_TERM_PROMOTION_LOCK_RELATIVE, SHORT_TERM_RECALL_STORE_RELATIVE };
|
|
36
|
+
export { DEFAULT_DEEP_CRON, DEFAULT_LIGHT_CRON, DEFAULT_MAX_AGE_DAYS, DEFAULT_RECENCY_HALF_LIFE_DAYS, DEFAULT_REM_CRON, DIVERSITY_DIMENSION_COUNT, DIVERSITY_WEIGHT, DREAMING_CRON_NAME, DREAMING_CRON_TAG, DREAMING_DIR_RELATIVE, DREAMING_EVENTS_LOG_RELATIVE, DREAMING_LAST_RUN_RELATIVE, DREAMING_LIGHT_CRON_NAME, DREAMING_LIGHT_SWEEP_TOKEN, DREAMING_PHASES, DREAMING_REM_CRON_NAME, DREAMING_REM_SWEEP_TOKEN, DREAMING_SWEEP_TOKEN, DREAMS_MD_FILENAME, MEMORY_MD_FILENAME, MS_PER_DAY, REINFORCEMENT_WEIGHT, SHORT_TERM_PROMOTION_LOCK_RELATIVE, SHORT_TERM_RECALL_STORE_RELATIVE };
|
|
13
37
|
|
|
14
38
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/constants.ts"],"sourcesContent":["import path from 'node:path';\n\nexport const
|
|
1
|
+
{"version":3,"file":"constants.js","names":[],"sources":["../../../../../src/agent/memory/dreaming/constants.ts"],"sourcesContent":["import path from 'node:path';\n\n// ── Phase identifiers ──────────────────────────────────────────────────\n\nexport type DreamingPhaseId = 'light' | 'deep' | 'rem';\n\nexport const DREAMING_PHASES: readonly DreamingPhaseId[] = ['light', 'deep', 'rem'] as const;\n\n// ── Sweep tokens (used in cron payloads to trigger each phase) ─────────\n\nexport const DREAMING_SWEEP_TOKEN = '__xopc_memory_dreaming_sweep__';\nexport const DREAMING_LIGHT_SWEEP_TOKEN = '__xopc_memory_dreaming_light_sweep__';\nexport const DREAMING_REM_SWEEP_TOKEN = '__xopc_memory_dreaming_rem_sweep__';\n\n// ── Cron job metadata ──────────────────────────────────────────────────\n\nexport const DREAMING_CRON_TAG = '[managed-by=xopc.memory.dreaming]';\n\nexport const DREAMING_CRON_NAME = 'Memory Dreaming - Deep Promotion';\nexport const DREAMING_LIGHT_CRON_NAME = 'Memory Dreaming - Light Sweep';\nexport const DREAMING_REM_CRON_NAME = 'Memory Dreaming - REM Patterns';\n\n// ── Default cron schedules ─────────────────────────────────────────────\n\nexport const DEFAULT_DEEP_CRON = '0 3 * * *';\nexport const DEFAULT_LIGHT_CRON = '0 */6 * * *';\nexport const DEFAULT_REM_CRON = '0 5 * * 0';\n\n// ── Time-decay defaults ────────────────────────────────────────────────\n\nexport const DEFAULT_RECENCY_HALF_LIFE_DAYS = 14;\nexport const DEFAULT_MAX_AGE_DAYS = 30;\n\n// ── Scoring weights ────────────────────────────────────────────────────\n\n/** Milliseconds in one day (used for time-decay calculations). */\nexport const MS_PER_DAY = 86_400_000;\n\n/** Weight applied to recall-count reinforcement (logarithmic boost). */\nexport const REINFORCEMENT_WEIGHT = 0.12;\n\n/** Weight applied to signal-diversity bonus. */\nexport const DIVERSITY_WEIGHT = 0.08;\n\n/** Number of signal dimensions used for diversity calculation. */\nexport const DIVERSITY_DIMENSION_COUNT = 4;\n\n// ── File paths ─────────────────────────────────────────────────────────\n\nexport const DREAMING_DIR_RELATIVE = path.join('memory', '.dreams');\nexport const SHORT_TERM_RECALL_STORE_RELATIVE = path.join(DREAMING_DIR_RELATIVE, 'short-term-recall.json');\nexport const SHORT_TERM_PROMOTION_LOCK_RELATIVE = path.join(\n DREAMING_DIR_RELATIVE,\n 'short-term-promotion.lock',\n);\nexport const DREAMING_LAST_RUN_RELATIVE = path.join(DREAMING_DIR_RELATIVE, 'last-run.json');\nexport const DREAMING_EVENTS_LOG_RELATIVE = path.join(DREAMING_DIR_RELATIVE, 'events.jsonl');\n\nexport const MEMORY_MD_FILENAME = 'MEMORY.md';\nexport const DREAMS_MD_FILENAME = 'DREAMS.md';\n\n"],"mappings":";;AAMA,MAAa,kBAA8C;CAAC;CAAS;CAAQ;CAAM;AAInF,MAAa,uBAAuB;AACpC,MAAa,6BAA6B;AAC1C,MAAa,2BAA2B;AAIxC,MAAa,oBAAoB;AAEjC,MAAa,qBAAqB;AAClC,MAAa,2BAA2B;AACxC,MAAa,yBAAyB;AAItC,MAAa,oBAAoB;AACjC,MAAa,qBAAqB;AAClC,MAAa,mBAAmB;AAIhC,MAAa,iCAAiC;AAC9C,MAAa,uBAAuB;;AAKpC,MAAa,aAAa;;AAG1B,MAAa,uBAAuB;;AAGpC,MAAa,mBAAmB;;AAGhC,MAAa,4BAA4B;AAIzC,MAAa,wBAAwB,KAAK,KAAK,UAAU,UAAU;AACnE,MAAa,mCAAmC,KAAK,KAAK,uBAAuB,yBAAyB;AAC1G,MAAa,qCAAqC,KAAK,KACrD,uBACA,4BACD;AACD,MAAa,6BAA6B,KAAK,KAAK,uBAAuB,gBAAgB;AAC3F,MAAa,+BAA+B,KAAK,KAAK,uBAAuB,eAAe;AAE5F,MAAa,qBAAqB;AAClC,MAAa,qBAAqB"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { type DreamingStoreEntry } from './short-term-store.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
minScore: number;
|
|
5
|
-
minRecallCount: number;
|
|
6
|
-
limit: number;
|
|
7
|
-
};
|
|
2
|
+
import type { DreamingDeepConfig } from './config.js';
|
|
3
|
+
export type { DreamingDeepConfig } from './config.js';
|
|
8
4
|
export type DreamingPromotionCandidate = DreamingStoreEntry & {
|
|
9
5
|
avgScore: number;
|
|
6
|
+
/** Time-decay-adjusted final score used for ranking. */
|
|
10
7
|
score: number;
|
|
8
|
+
/** Raw recency decay multiplier (0–1). */
|
|
9
|
+
recencyDecay: number;
|
|
11
10
|
};
|
|
12
11
|
export declare function runDreamingDeepPromotion(params: {
|
|
13
12
|
workspaceDir: string;
|
|
@@ -1,92 +1,17 @@
|
|
|
1
1
|
import { createLogger } from "../../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../../utils/logger.js";
|
|
3
|
-
import {
|
|
3
|
+
import { MEMORY_MD_FILENAME } from "./constants.js";
|
|
4
|
+
import { clamp01, compareCandidatesByScore, computeCandidateScore, extractPromotionMarkers, isContaminatedSnippet, isExpiredEntry, isoDay, readFileLines, resolveDeepDefaults, sliceRange, snippetHash } from "./utils.js";
|
|
4
5
|
import { loadDreamingStore, saveDreamingStore, withDreamingPromotionLock } from "./short-term-store.js";
|
|
6
|
+
import { emptyDeepPhaseSkipped, writeDreamingDeepLastRun } from "./last-run.js";
|
|
5
7
|
import path from "node:path";
|
|
6
8
|
import fs from "node:fs/promises";
|
|
7
|
-
import { createHash } from "node:crypto";
|
|
8
9
|
//#region src/agent/memory/dreaming/deep-promotion.ts
|
|
9
10
|
init_logger();
|
|
10
11
|
const log = createLogger("Dreaming:Deep");
|
|
11
|
-
function clampScore(value) {
|
|
12
|
-
if (!Number.isFinite(value)) return 0;
|
|
13
|
-
return Math.max(0, Math.min(1, value));
|
|
14
|
-
}
|
|
15
|
-
function formatIsoDay(now) {
|
|
16
|
-
return now.toISOString().slice(0, 10);
|
|
17
|
-
}
|
|
18
|
-
function compareCandidates(a, b) {
|
|
19
|
-
if (b.score !== a.score) return b.score - a.score;
|
|
20
|
-
if (b.recallCount !== a.recallCount) return b.recallCount - a.recallCount;
|
|
21
|
-
const aMs = Date.parse(a.lastRecalledAt);
|
|
22
|
-
const bMs = Date.parse(b.lastRecalledAt);
|
|
23
|
-
if (Number.isFinite(aMs) || Number.isFinite(bMs)) {
|
|
24
|
-
if (bMs !== aMs) return bMs - aMs;
|
|
25
|
-
}
|
|
26
|
-
return a.path.localeCompare(b.path);
|
|
27
|
-
}
|
|
28
|
-
function normalizeSnippetForHash(snippet) {
|
|
29
|
-
return snippet.trim().replace(/\s+/g, " ").replace(/[“”]/g, "\"").replace(/[‘’]/g, "'").toLowerCase().slice(0, 512);
|
|
30
|
-
}
|
|
31
|
-
function snippetHash(snippet) {
|
|
32
|
-
const normalized = normalizeSnippetForHash(snippet);
|
|
33
|
-
return createHash("sha1").update(normalized).digest("hex").slice(0, 12);
|
|
34
|
-
}
|
|
35
12
|
function markerForPromotion(key, hash) {
|
|
36
13
|
return `<!-- xopc-memory-promotion key="${key}" hash="${hash}" -->`;
|
|
37
14
|
}
|
|
38
|
-
function extractPromotionMarkers(memoryText) {
|
|
39
|
-
const keys = /* @__PURE__ */ new Set();
|
|
40
|
-
const hashes = /* @__PURE__ */ new Set();
|
|
41
|
-
for (const match of memoryText.matchAll(/<!--\s*xopc-memory-promotion\b([\s\S]*?)-->/gi)) {
|
|
42
|
-
const body = match[1] ?? "";
|
|
43
|
-
const k = body.match(/\bkey\s*=\s*"([^"]+)"/i)?.[1]?.trim();
|
|
44
|
-
const h = body.match(/\bhash\s*=\s*"([^"]+)"/i)?.[1]?.trim();
|
|
45
|
-
if (k) keys.add(k);
|
|
46
|
-
if (h) hashes.add(h);
|
|
47
|
-
}
|
|
48
|
-
for (const match of memoryText.matchAll(/<!--\s*xopc-memory-promotion:([^\n]+?)\s*-->/gi)) {
|
|
49
|
-
const key = match[1]?.trim();
|
|
50
|
-
if (key) keys.add(key);
|
|
51
|
-
}
|
|
52
|
-
return {
|
|
53
|
-
keys,
|
|
54
|
-
hashes
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
function isContaminatedSnippet(snippet) {
|
|
58
|
-
const s = snippet.trim();
|
|
59
|
-
if (!s) return true;
|
|
60
|
-
const lower = s.toLowerCase();
|
|
61
|
-
if ([
|
|
62
|
-
/\b(system|assistant|tool)\s*:/i,
|
|
63
|
-
/<\s*(system|assistant|tool)\b/i,
|
|
64
|
-
/<!--\s*xopc-memory-promotion\b/i,
|
|
65
|
-
/tool_call_id|toolcallid|function_call|arguments\s*:\s*\{/i,
|
|
66
|
-
/"tool"\s*:\s*|\btool_name\b|\btool\b\s*results?/i,
|
|
67
|
-
/you are (an|a)\s+(ai|assistant)|follow these instructions/i,
|
|
68
|
-
/begin\s+(system prompt|instructions)|end\s+(system prompt|instructions)/i,
|
|
69
|
-
/```/i,
|
|
70
|
-
/\b__xopc_/i
|
|
71
|
-
].some((p) => p.test(s))) return true;
|
|
72
|
-
if ((s.match(/[{}[\]]/g) ?? []).length >= 12) return true;
|
|
73
|
-
if ((lower.match(/https?:\/\//g) ?? []).length >= 3) return true;
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
async function readFileLines(fullPath) {
|
|
77
|
-
try {
|
|
78
|
-
return (await fs.readFile(fullPath, "utf-8")).split(/\r?\n/);
|
|
79
|
-
} catch (err) {
|
|
80
|
-
if (err?.code === "ENOENT") return null;
|
|
81
|
-
throw err;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
function sliceRange(lines, startLine, endLine) {
|
|
85
|
-
const startIdx = Math.max(0, startLine - 1);
|
|
86
|
-
const endIdx = Math.min(lines.length, endLine);
|
|
87
|
-
if (startIdx >= endIdx) return "";
|
|
88
|
-
return lines.slice(startIdx, endIdx).map((l) => l.trim()).filter(Boolean).join(" ").replace(/\s+/g, " ").trim().slice(0, 360);
|
|
89
|
-
}
|
|
90
15
|
async function rehydrateSnippet(params) {
|
|
91
16
|
const lines = await readFileLines(path.join(params.workspaceDir, params.candidate.path));
|
|
92
17
|
if (!lines) return null;
|
|
@@ -100,76 +25,55 @@ async function rehydrateSnippet(params) {
|
|
|
100
25
|
endLine
|
|
101
26
|
};
|
|
102
27
|
}
|
|
103
|
-
function
|
|
104
|
-
const
|
|
105
|
-
const minScore = typeof overrides?.minScore === "number" ? overrides.minScore : .8;
|
|
106
|
-
const minRecallCount = typeof overrides?.minRecallCount === "number" ? overrides.minRecallCount : 3;
|
|
107
|
-
const limit = typeof overrides?.limit === "number" ? overrides.limit : 10;
|
|
28
|
+
function buildDeepLastRun(base) {
|
|
29
|
+
const durationMs = Math.max(0, Date.now() - base.t0);
|
|
108
30
|
return {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
31
|
+
version: 2,
|
|
32
|
+
phase: "deep",
|
|
33
|
+
runId: base.runId,
|
|
34
|
+
startedAt: base.startedAt,
|
|
35
|
+
finishedAt: base.finishedAt,
|
|
36
|
+
durationMs,
|
|
37
|
+
ok: base.ok,
|
|
38
|
+
reason: base.reason,
|
|
39
|
+
config: base.config,
|
|
40
|
+
memoryPath: base.memoryPath,
|
|
41
|
+
...base.errorMessage ? { errorMessage: base.errorMessage } : {},
|
|
42
|
+
deep: base.deep
|
|
113
43
|
};
|
|
114
44
|
}
|
|
115
|
-
async function writeLastRun(params) {
|
|
116
|
-
const fullPath = path.join(params.workspaceDir, DREAMING_LAST_RUN_RELATIVE);
|
|
117
|
-
await fs.mkdir(path.dirname(fullPath), { recursive: true });
|
|
118
|
-
const tmp = `${fullPath}.${process.pid}.${Date.now()}.tmp`;
|
|
119
|
-
await fs.writeFile(tmp, `${JSON.stringify(params.lastRun, null, 2)}\n`, "utf-8");
|
|
120
|
-
await fs.rename(tmp, fullPath);
|
|
121
|
-
}
|
|
122
45
|
async function runDreamingDeepPromotion(params) {
|
|
123
|
-
const cfg =
|
|
46
|
+
const cfg = resolveDeepDefaults(params.config);
|
|
124
47
|
const now = params.now ?? /* @__PURE__ */ new Date();
|
|
125
48
|
const startedAt = now.toISOString();
|
|
126
49
|
const runId = `${startedAt}:${process.pid}:${Math.random().toString(16).slice(2)}`;
|
|
127
50
|
const memoryPath = path.join(params.workspaceDir, MEMORY_MD_FILENAME);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
workspaceDir: params.workspaceDir,
|
|
132
|
-
lastRun: {
|
|
133
|
-
version: 1,
|
|
134
|
-
runId,
|
|
135
|
-
startedAt,
|
|
136
|
-
finishedAt,
|
|
137
|
-
ok: true,
|
|
138
|
-
reason: "dreaming mvp disabled",
|
|
139
|
-
config: cfg,
|
|
140
|
-
candidates: 0,
|
|
141
|
-
applied: 0,
|
|
142
|
-
memoryPath
|
|
143
|
-
}
|
|
144
|
-
}).catch(() => void 0);
|
|
145
|
-
return {
|
|
146
|
-
ok: true,
|
|
147
|
-
reason: "dreaming mvp disabled",
|
|
148
|
-
candidates: 0,
|
|
149
|
-
applied: 0,
|
|
150
|
-
memoryPath
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
if (cfg.limit === 0) {
|
|
51
|
+
const t0 = Date.now();
|
|
52
|
+
const earlyExitReason = !cfg.enabled ? "dreaming disabled" : cfg.limit === 0 ? "dreaming limit=0" : null;
|
|
53
|
+
if (earlyExitReason) {
|
|
154
54
|
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
155
|
-
|
|
55
|
+
const empty = emptyDeepPhaseSkipped();
|
|
56
|
+
await writeDreamingDeepLastRun({
|
|
156
57
|
workspaceDir: params.workspaceDir,
|
|
157
|
-
lastRun: {
|
|
158
|
-
version: 1,
|
|
58
|
+
lastRun: buildDeepLastRun({
|
|
159
59
|
runId,
|
|
160
60
|
startedAt,
|
|
161
61
|
finishedAt,
|
|
62
|
+
t0,
|
|
162
63
|
ok: true,
|
|
163
|
-
reason:
|
|
64
|
+
reason: earlyExitReason,
|
|
164
65
|
config: cfg,
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
66
|
+
memoryPath,
|
|
67
|
+
deep: {
|
|
68
|
+
candidatesRanked: 0,
|
|
69
|
+
applied: 0,
|
|
70
|
+
skipped: empty
|
|
71
|
+
}
|
|
72
|
+
})
|
|
169
73
|
}).catch(() => void 0);
|
|
170
74
|
return {
|
|
171
75
|
ok: true,
|
|
172
|
-
reason:
|
|
76
|
+
reason: earlyExitReason,
|
|
173
77
|
candidates: 0,
|
|
174
78
|
applied: 0,
|
|
175
79
|
memoryPath
|
|
@@ -178,27 +82,31 @@ async function runDreamingDeepPromotion(params) {
|
|
|
178
82
|
try {
|
|
179
83
|
const result = await withDreamingPromotionLock(params.workspaceDir, async () => {
|
|
180
84
|
const { store } = await loadDreamingStore({ workspaceDir: params.workspaceDir });
|
|
85
|
+
const nowMs = now.getTime();
|
|
181
86
|
const ranked = Object.values(store.entries ?? {}).filter((e) => {
|
|
182
87
|
if (!e || typeof e !== "object") return false;
|
|
183
88
|
if (e.promotedAt) return false;
|
|
184
89
|
if (!e.path || !e.path.startsWith("memory/")) return false;
|
|
185
90
|
if (e.recallCount < cfg.minRecallCount) return false;
|
|
186
|
-
|
|
91
|
+
if ((e.queryHashes?.length ?? 0) < cfg.minUniqueQueries) return false;
|
|
92
|
+
if (isExpiredEntry(e.lastRecalledAt, nowMs, cfg.maxAgeDays)) return false;
|
|
93
|
+
return clamp01(e.recallCount > 0 ? e.totalScore / e.recallCount : 0) >= cfg.minScore;
|
|
187
94
|
}).map((e) => {
|
|
188
|
-
const avgScore
|
|
189
|
-
const score = clampScore(avgScore + clampScore(Math.log1p(e.recallCount) / Math.log1p(10)) * .12);
|
|
95
|
+
const { avgScore, score, recencyDecay } = computeCandidateScore(e, nowMs, cfg.recencyHalfLifeDays);
|
|
190
96
|
return {
|
|
191
97
|
...e,
|
|
192
98
|
avgScore,
|
|
193
|
-
score
|
|
99
|
+
score,
|
|
100
|
+
recencyDecay
|
|
194
101
|
};
|
|
195
|
-
}).sort(
|
|
102
|
+
}).sort(compareCandidatesByScore).slice(0, cfg.limit);
|
|
196
103
|
if (ranked.length === 0) return {
|
|
197
104
|
ok: true,
|
|
198
105
|
reason: "no eligible candidates",
|
|
199
106
|
candidates: 0,
|
|
200
107
|
applied: 0,
|
|
201
|
-
memoryPath
|
|
108
|
+
memoryPath,
|
|
109
|
+
skipped: emptyDeepPhaseSkipped()
|
|
202
110
|
};
|
|
203
111
|
const existing = await fs.readFile(memoryPath, "utf-8").catch((err) => {
|
|
204
112
|
if (err?.code === "ENOENT") return "";
|
|
@@ -206,8 +114,10 @@ async function runDreamingDeepPromotion(params) {
|
|
|
206
114
|
});
|
|
207
115
|
const existingMarkers = extractPromotionMarkers(existing);
|
|
208
116
|
const appliedCandidates = [];
|
|
117
|
+
const skipped = emptyDeepPhaseSkipped();
|
|
209
118
|
for (const candidate of ranked) {
|
|
210
119
|
if (existingMarkers.keys.has(candidate.key)) {
|
|
120
|
+
skipped.alreadyPromotedKey += 1;
|
|
211
121
|
const entry = store.entries[candidate.key];
|
|
212
122
|
if (entry && !entry.promotedAt) entry.promotedAt = now.toISOString();
|
|
213
123
|
continue;
|
|
@@ -216,10 +126,17 @@ async function runDreamingDeepPromotion(params) {
|
|
|
216
126
|
workspaceDir: params.workspaceDir,
|
|
217
127
|
candidate
|
|
218
128
|
});
|
|
219
|
-
if (!rehydrated)
|
|
220
|
-
|
|
129
|
+
if (!rehydrated) {
|
|
130
|
+
skipped.rehydrateFailed += 1;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (isContaminatedSnippet(rehydrated.snippet)) {
|
|
134
|
+
skipped.contaminated += 1;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
221
137
|
const hash = snippetHash(rehydrated.snippet);
|
|
222
138
|
if (existingMarkers.hashes.has(hash)) {
|
|
139
|
+
skipped.hashDuplicate += 1;
|
|
223
140
|
const entry = store.entries[candidate.key];
|
|
224
141
|
if (entry && !entry.promotedAt) entry.promotedAt = now.toISOString();
|
|
225
142
|
continue;
|
|
@@ -246,10 +163,11 @@ async function runDreamingDeepPromotion(params) {
|
|
|
246
163
|
reason: "candidates were stale or already applied",
|
|
247
164
|
candidates: ranked.length,
|
|
248
165
|
applied: 0,
|
|
249
|
-
memoryPath
|
|
166
|
+
memoryPath,
|
|
167
|
+
skipped
|
|
250
168
|
};
|
|
251
169
|
}
|
|
252
|
-
const day =
|
|
170
|
+
const day = isoDay(now);
|
|
253
171
|
const header = existing.trim().length > 0 ? "" : "# Long-Term Memory\n\n";
|
|
254
172
|
const sectionLines = [
|
|
255
173
|
"",
|
|
@@ -289,44 +207,60 @@ async function runDreamingDeepPromotion(params) {
|
|
|
289
207
|
reason: "applied promotions",
|
|
290
208
|
candidates: ranked.length,
|
|
291
209
|
applied: appliedCandidates.length,
|
|
292
|
-
memoryPath
|
|
210
|
+
memoryPath,
|
|
211
|
+
skipped
|
|
293
212
|
};
|
|
294
213
|
});
|
|
295
214
|
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
296
|
-
|
|
215
|
+
const empty = emptyDeepPhaseSkipped();
|
|
216
|
+
const resultSkipped = "skipped" in result ? result.skipped : empty;
|
|
217
|
+
await writeDreamingDeepLastRun({
|
|
297
218
|
workspaceDir: params.workspaceDir,
|
|
298
|
-
lastRun: {
|
|
299
|
-
version: 1,
|
|
219
|
+
lastRun: buildDeepLastRun({
|
|
300
220
|
runId,
|
|
301
221
|
startedAt,
|
|
302
222
|
finishedAt,
|
|
223
|
+
t0,
|
|
303
224
|
ok: result.ok,
|
|
304
225
|
reason: result.reason,
|
|
305
226
|
config: cfg,
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
227
|
+
memoryPath: result.memoryPath,
|
|
228
|
+
deep: {
|
|
229
|
+
candidatesRanked: result.candidates,
|
|
230
|
+
applied: result.applied,
|
|
231
|
+
skipped: resultSkipped
|
|
232
|
+
}
|
|
233
|
+
})
|
|
310
234
|
}).catch(() => void 0);
|
|
311
|
-
return
|
|
235
|
+
return {
|
|
236
|
+
ok: result.ok,
|
|
237
|
+
reason: result.reason,
|
|
238
|
+
candidates: result.candidates,
|
|
239
|
+
applied: result.applied,
|
|
240
|
+
memoryPath: result.memoryPath
|
|
241
|
+
};
|
|
312
242
|
} catch (err) {
|
|
313
243
|
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
314
244
|
const em = err instanceof Error ? err.message : String(err);
|
|
315
|
-
|
|
245
|
+
const z = emptyDeepPhaseSkipped();
|
|
246
|
+
await writeDreamingDeepLastRun({
|
|
316
247
|
workspaceDir: params.workspaceDir,
|
|
317
|
-
lastRun: {
|
|
318
|
-
version: 1,
|
|
248
|
+
lastRun: buildDeepLastRun({
|
|
319
249
|
runId,
|
|
320
250
|
startedAt,
|
|
321
251
|
finishedAt,
|
|
252
|
+
t0,
|
|
322
253
|
ok: false,
|
|
323
254
|
reason: "error",
|
|
324
255
|
config: cfg,
|
|
325
|
-
candidates: 0,
|
|
326
|
-
applied: 0,
|
|
327
256
|
memoryPath,
|
|
328
|
-
errorMessage: em
|
|
329
|
-
|
|
257
|
+
errorMessage: em,
|
|
258
|
+
deep: {
|
|
259
|
+
candidatesRanked: 0,
|
|
260
|
+
applied: 0,
|
|
261
|
+
skipped: z
|
|
262
|
+
}
|
|
263
|
+
})
|
|
330
264
|
}).catch(() => void 0);
|
|
331
265
|
throw err;
|
|
332
266
|
}
|