@zhijiewang/openharness 0.11.1 → 0.12.0
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/README.md +199 -23
- package/dist/DeferredTool.d.ts +34 -0
- package/dist/DeferredTool.d.ts.map +1 -0
- package/dist/DeferredTool.js +62 -0
- package/dist/DeferredTool.js.map +1 -0
- package/dist/DeferredTool.test.d.ts +2 -0
- package/dist/DeferredTool.test.d.ts.map +1 -0
- package/dist/DeferredTool.test.js +79 -0
- package/dist/DeferredTool.test.js.map +1 -0
- package/dist/agents/roles.d.ts.map +1 -1
- package/dist/agents/roles.js +20 -6
- package/dist/agents/roles.js.map +1 -1
- package/dist/agents/roles.test.js +26 -2
- package/dist/agents/roles.test.js.map +1 -1
- package/dist/harness/config.d.ts +15 -0
- package/dist/harness/config.d.ts.map +1 -1
- package/dist/harness/config.js +45 -23
- package/dist/harness/config.js.map +1 -1
- package/dist/harness/memory-consolidation.test.d.ts +2 -0
- package/dist/harness/memory-consolidation.test.d.ts.map +1 -0
- package/dist/harness/memory-consolidation.test.js +152 -0
- package/dist/harness/memory-consolidation.test.js.map +1 -0
- package/dist/harness/memory.d.ts +12 -0
- package/dist/harness/memory.d.ts.map +1 -1
- package/dist/harness/memory.js +53 -2
- package/dist/harness/memory.js.map +1 -1
- package/dist/harness/memory.test.js +43 -1
- package/dist/harness/memory.test.js.map +1 -1
- package/dist/harness/session.test.js +36 -0
- package/dist/harness/session.test.js.map +1 -1
- package/dist/harness/verification.d.ts +41 -0
- package/dist/harness/verification.d.ts.map +1 -0
- package/dist/harness/verification.js +197 -0
- package/dist/harness/verification.js.map +1 -0
- package/dist/harness/verification.test.d.ts +2 -0
- package/dist/harness/verification.test.d.ts.map +1 -0
- package/dist/harness/verification.test.js +181 -0
- package/dist/harness/verification.test.js.map +1 -0
- package/dist/query/index.d.ts.map +1 -1
- package/dist/query/index.js +9 -1
- package/dist/query/index.js.map +1 -1
- package/dist/query/tools.d.ts.map +1 -1
- package/dist/query/tools.js +30 -4
- package/dist/query/tools.js.map +1 -1
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +21 -0
- package/dist/repl.js.map +1 -1
- package/dist/services/AgentDispatcher.d.ts +1 -0
- package/dist/services/AgentDispatcher.d.ts.map +1 -1
- package/dist/services/AgentDispatcher.js +10 -1
- package/dist/services/AgentDispatcher.js.map +1 -1
- package/dist/services/CronExecutor.d.ts +38 -0
- package/dist/services/CronExecutor.d.ts.map +1 -0
- package/dist/services/CronExecutor.js +130 -0
- package/dist/services/CronExecutor.js.map +1 -0
- package/dist/services/CronExecutor.test.d.ts +2 -0
- package/dist/services/CronExecutor.test.d.ts.map +1 -0
- package/dist/services/CronExecutor.test.js +128 -0
- package/dist/services/CronExecutor.test.js.map +1 -0
- package/dist/services/StreamingToolExecutor.d.ts.map +1 -1
- package/dist/services/StreamingToolExecutor.js +28 -0
- package/dist/services/StreamingToolExecutor.js.map +1 -1
- package/dist/services/cron.d.ts +4 -0
- package/dist/services/cron.d.ts.map +1 -1
- package/dist/services/cron.js +27 -0
- package/dist/services/cron.js.map +1 -1
- package/dist/tools/AgentTool/index.d.ts +3 -0
- package/dist/tools/AgentTool/index.d.ts.map +1 -1
- package/dist/tools/AgentTool/index.js +17 -4
- package/dist/tools/AgentTool/index.js.map +1 -1
- package/dist/tools/MemoryTool/index.d.ts +2 -2
- package/dist/tools/ToolSearchTool/index.d.ts.map +1 -1
- package/dist/tools/ToolSearchTool/index.js +7 -0
- package/dist/tools/ToolSearchTool/index.js.map +1 -1
- package/dist/tools.d.ts +8 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +40 -41
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roles.test.js","sourceRoot":"","sources":["../../src/agents/roles.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5D,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;QACzB,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,kBAAkB,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"roles.test.js","sourceRoot":"","sources":["../../src/agents/roles.test.ts"],"names":[],"mappings":"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"}
|
package/dist/harness/config.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export type ToolPermissionRule = {
|
|
|
25
25
|
action: "allow" | "deny" | "ask";
|
|
26
26
|
pattern?: string;
|
|
27
27
|
};
|
|
28
|
+
export type VerificationRuleConfig = {
|
|
29
|
+
extensions: string[];
|
|
30
|
+
lint?: string;
|
|
31
|
+
timeout?: number;
|
|
32
|
+
};
|
|
28
33
|
export type OhConfig = {
|
|
29
34
|
provider: string;
|
|
30
35
|
model: string;
|
|
@@ -36,6 +41,16 @@ export type OhConfig = {
|
|
|
36
41
|
hooks?: HooksConfig;
|
|
37
42
|
toolPermissions?: ToolPermissionRule[];
|
|
38
43
|
statusLineFormat?: string;
|
|
44
|
+
/** Verification loops — auto-run lint/typecheck after file edits */
|
|
45
|
+
verification?: {
|
|
46
|
+
enabled?: boolean;
|
|
47
|
+
mode?: 'warn' | 'block';
|
|
48
|
+
rules?: VerificationRuleConfig[];
|
|
49
|
+
};
|
|
50
|
+
/** Memory consolidation settings */
|
|
51
|
+
memory?: {
|
|
52
|
+
consolidateOnExit?: boolean;
|
|
53
|
+
};
|
|
39
54
|
};
|
|
40
55
|
/** Clear cached config (call after writes or to force re-read) */
|
|
41
56
|
export declare function invalidateConfigCache(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/harness/config.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/harness/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,cAAc,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,eAAe,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,YAAY,CAAC,EAAE;QACb,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QACxB,KAAK,CAAC,EAAE,sBAAsB,EAAE,CAAC;KAClC,CAAC;IACF,oCAAoC;IACpC,MAAM,CAAC,EAAE;QACP,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B,CAAC;CACH,CAAC;AAaF,kEAAkE;AAClE,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAgBD,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAyC3D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAmChE"}
|
package/dist/harness/config.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
6
|
+
import { homedir } from "node:os";
|
|
6
7
|
import { parse, stringify } from "yaml";
|
|
7
8
|
function yamlScalar(value) {
|
|
8
9
|
return `'${value.replace(/'/g, "''")}'`;
|
|
@@ -17,41 +18,62 @@ export function invalidateConfigCache() {
|
|
|
17
18
|
_configCache = undefined;
|
|
18
19
|
_configCacheRoot = undefined;
|
|
19
20
|
}
|
|
21
|
+
/** Path to global config: ~/.oh/config.yaml */
|
|
22
|
+
function globalConfigPath() {
|
|
23
|
+
return join(homedir(), '.oh', 'config.yaml');
|
|
24
|
+
}
|
|
25
|
+
/** Read global config as fallback defaults */
|
|
26
|
+
function readGlobalConfig() {
|
|
27
|
+
const p = globalConfigPath();
|
|
28
|
+
if (!existsSync(p))
|
|
29
|
+
return null;
|
|
30
|
+
try {
|
|
31
|
+
return parse(readFileSync(p, 'utf-8'));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
20
37
|
export function readOhConfig(root) {
|
|
21
38
|
const effectiveRoot = root ?? ".";
|
|
22
39
|
if (_configCache !== undefined && _configCacheRoot === effectiveRoot)
|
|
23
40
|
return _configCache;
|
|
24
41
|
const p = configPath(root);
|
|
25
|
-
|
|
42
|
+
// Layer 1: Global defaults from ~/.oh/config.yaml
|
|
43
|
+
const globalCfg = readGlobalConfig();
|
|
44
|
+
// Layer 2: Project config from .oh/config.yaml
|
|
45
|
+
let projectCfg = null;
|
|
46
|
+
if (existsSync(p)) {
|
|
47
|
+
try {
|
|
48
|
+
projectCfg = parse(readFileSync(p, "utf-8"));
|
|
49
|
+
}
|
|
50
|
+
catch { /* ignore malformed project config */ }
|
|
51
|
+
}
|
|
52
|
+
// If neither exists, no config
|
|
53
|
+
if (!globalCfg && !projectCfg) {
|
|
26
54
|
_configCache = null;
|
|
27
55
|
_configCacheRoot = effectiveRoot;
|
|
28
56
|
return null;
|
|
29
57
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
58
|
+
// Merge: global → project (project overrides global)
|
|
59
|
+
const base = { ...globalCfg, ...projectCfg };
|
|
60
|
+
// Layer 3: Local overrides from .oh/config.local.yaml (gitignored personal settings)
|
|
61
|
+
const localPath = join(root ?? ".", ".oh", "config.local.yaml");
|
|
62
|
+
if (existsSync(localPath)) {
|
|
63
|
+
try {
|
|
64
|
+
const local = parse(readFileSync(localPath, "utf-8"));
|
|
65
|
+
if (local) {
|
|
66
|
+
const merged = { ...base, ...local };
|
|
67
|
+
_configCache = merged;
|
|
68
|
+
_configCacheRoot = effectiveRoot;
|
|
69
|
+
return merged;
|
|
43
70
|
}
|
|
44
|
-
catch { /* ignore malformed local config */ }
|
|
45
71
|
}
|
|
46
|
-
|
|
47
|
-
_configCacheRoot = effectiveRoot;
|
|
48
|
-
return base;
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
_configCache = null;
|
|
52
|
-
_configCacheRoot = effectiveRoot;
|
|
53
|
-
return null;
|
|
72
|
+
catch { /* ignore malformed local config */ }
|
|
54
73
|
}
|
|
74
|
+
_configCache = base;
|
|
75
|
+
_configCacheRoot = effectiveRoot;
|
|
76
|
+
return base;
|
|
55
77
|
}
|
|
56
78
|
export function writeOhConfig(cfg, root) {
|
|
57
79
|
invalidateConfigCache();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/harness/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/harness/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-consolidation.test.d.ts","sourceRoot":"","sources":["../../src/harness/memory-consolidation.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
5
|
+
import { makeTmpDir } from '../test-helpers.js';
|
|
6
|
+
import { decayAndPrune, deletePrunedMemories, consolidateMemories, } from './memory.js';
|
|
7
|
+
/** Create a memory file with backdated timestamps */
|
|
8
|
+
function createMemoryFile(dir, name, opts = {}) {
|
|
9
|
+
mkdirSync(dir, { recursive: true });
|
|
10
|
+
const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-');
|
|
11
|
+
const filePath = join(dir, `${slug}.md`);
|
|
12
|
+
const relevance = opts.relevance ?? 0.5;
|
|
13
|
+
const lastAccessed = opts.lastAccessed ?? Date.now();
|
|
14
|
+
const type = opts.type ?? 'convention';
|
|
15
|
+
writeFileSync(filePath, `---
|
|
16
|
+
name: ${name}
|
|
17
|
+
type: ${type}
|
|
18
|
+
description: Test memory
|
|
19
|
+
relevance: ${relevance}
|
|
20
|
+
createdAt: ${lastAccessed}
|
|
21
|
+
lastAccessed: ${lastAccessed}
|
|
22
|
+
accessCount: 1
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Test content for ${name}
|
|
26
|
+
`);
|
|
27
|
+
return filePath;
|
|
28
|
+
}
|
|
29
|
+
describe('dream consolidation', () => {
|
|
30
|
+
describe('decayAndPrune', () => {
|
|
31
|
+
it('keeps recent memories active', () => {
|
|
32
|
+
const now = Date.now();
|
|
33
|
+
const memories = [{
|
|
34
|
+
name: 'recent',
|
|
35
|
+
type: 'convention',
|
|
36
|
+
description: 'test',
|
|
37
|
+
content: 'test',
|
|
38
|
+
filePath: '/tmp/recent.md',
|
|
39
|
+
relevance: 0.5,
|
|
40
|
+
lastAccessed: now,
|
|
41
|
+
createdAt: now,
|
|
42
|
+
accessCount: 1,
|
|
43
|
+
}];
|
|
44
|
+
const { active, pruned } = decayAndPrune(memories);
|
|
45
|
+
assert.equal(active.length, 1);
|
|
46
|
+
assert.equal(pruned.length, 0);
|
|
47
|
+
});
|
|
48
|
+
it('decays memories older than 30 days', () => {
|
|
49
|
+
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;
|
|
50
|
+
const memories = [{
|
|
51
|
+
name: 'old',
|
|
52
|
+
type: 'convention',
|
|
53
|
+
description: 'test',
|
|
54
|
+
content: 'test',
|
|
55
|
+
filePath: '/tmp/old.md',
|
|
56
|
+
relevance: 0.5,
|
|
57
|
+
lastAccessed: Date.now() - THIRTY_DAYS * 2,
|
|
58
|
+
createdAt: Date.now() - THIRTY_DAYS * 3,
|
|
59
|
+
accessCount: 1,
|
|
60
|
+
}];
|
|
61
|
+
const { active, pruned } = decayAndPrune(memories);
|
|
62
|
+
assert.equal(active.length, 1);
|
|
63
|
+
assert.equal(pruned.length, 0);
|
|
64
|
+
// Should have decayed by 0.2 (2 periods)
|
|
65
|
+
assert.ok(active[0].relevance < 0.5);
|
|
66
|
+
assert.ok(active[0].relevance >= 0.2);
|
|
67
|
+
});
|
|
68
|
+
it('prunes memories below 0.1 relevance', () => {
|
|
69
|
+
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;
|
|
70
|
+
const memories = [{
|
|
71
|
+
name: 'ancient',
|
|
72
|
+
type: 'convention',
|
|
73
|
+
description: 'test',
|
|
74
|
+
content: 'test',
|
|
75
|
+
filePath: '/tmp/ancient.md',
|
|
76
|
+
relevance: 0.5,
|
|
77
|
+
lastAccessed: Date.now() - THIRTY_DAYS * 6, // 6 periods = -0.6 decay
|
|
78
|
+
createdAt: Date.now() - THIRTY_DAYS * 7,
|
|
79
|
+
accessCount: 1,
|
|
80
|
+
}];
|
|
81
|
+
const { active, pruned } = decayAndPrune(memories);
|
|
82
|
+
assert.equal(active.length, 0);
|
|
83
|
+
assert.equal(pruned.length, 1);
|
|
84
|
+
assert.equal(pruned[0].name, 'ancient');
|
|
85
|
+
});
|
|
86
|
+
it('handles memories without timestamps gracefully', () => {
|
|
87
|
+
const memories = [{
|
|
88
|
+
name: 'no-dates',
|
|
89
|
+
type: 'convention',
|
|
90
|
+
description: 'test',
|
|
91
|
+
content: 'test',
|
|
92
|
+
filePath: '/tmp/no-dates.md',
|
|
93
|
+
relevance: 0.5,
|
|
94
|
+
}];
|
|
95
|
+
const { active, pruned } = decayAndPrune(memories);
|
|
96
|
+
// Without lastAccessed, falls back to now — should not decay
|
|
97
|
+
assert.equal(active.length, 1);
|
|
98
|
+
assert.equal(pruned.length, 0);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe('deletePrunedMemories', () => {
|
|
102
|
+
it('deletes files within allowed directories', () => {
|
|
103
|
+
const tmp = makeTmpDir();
|
|
104
|
+
const memDir = join(tmp, '.oh', 'memory');
|
|
105
|
+
const filePath = createMemoryFile(memDir, 'to-delete');
|
|
106
|
+
assert.ok(existsSync(filePath));
|
|
107
|
+
// Mock: deletePrunedMemories checks against PROJECT_MEMORY_DIR and GLOBAL_MEMORY_DIR
|
|
108
|
+
// which are hardcoded. For this test, just verify the function signature works.
|
|
109
|
+
const entry = {
|
|
110
|
+
name: 'to-delete',
|
|
111
|
+
type: 'convention',
|
|
112
|
+
description: 'test',
|
|
113
|
+
content: 'test',
|
|
114
|
+
filePath,
|
|
115
|
+
relevance: 0.05,
|
|
116
|
+
};
|
|
117
|
+
// deletePrunedMemories uses directory guards against .oh/memory and ~/.oh/memory
|
|
118
|
+
// Since our tmp dir doesn't match, it should skip deletion (guard works)
|
|
119
|
+
const deleted = deletePrunedMemories([entry]);
|
|
120
|
+
// The directory guard should prevent deletion since tmp dir != .oh/memory
|
|
121
|
+
assert.equal(deleted, 0);
|
|
122
|
+
});
|
|
123
|
+
it('handles missing files gracefully', () => {
|
|
124
|
+
const entry = {
|
|
125
|
+
name: 'nonexistent',
|
|
126
|
+
type: 'convention',
|
|
127
|
+
description: 'test',
|
|
128
|
+
content: 'test',
|
|
129
|
+
filePath: '/tmp/definitely-does-not-exist-12345.md',
|
|
130
|
+
relevance: 0.05,
|
|
131
|
+
};
|
|
132
|
+
// Should not throw
|
|
133
|
+
const deleted = deletePrunedMemories([entry]);
|
|
134
|
+
assert.equal(deleted, 0);
|
|
135
|
+
});
|
|
136
|
+
it('handles empty pruned list', () => {
|
|
137
|
+
const deleted = deletePrunedMemories([]);
|
|
138
|
+
assert.equal(deleted, 0);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe('consolidateMemories', () => {
|
|
142
|
+
it('returns zero stats when no memories exist', () => {
|
|
143
|
+
// consolidateMemories loads from .oh/memory/ which may or may not exist
|
|
144
|
+
// In test environment, it should handle gracefully
|
|
145
|
+
const result = consolidateMemories();
|
|
146
|
+
assert.equal(typeof result.total, 'number');
|
|
147
|
+
assert.equal(typeof result.pruned, 'number');
|
|
148
|
+
assert.equal(typeof result.decayed, 'number');
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
//# sourceMappingURL=memory-consolidation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-consolidation.test.js","sourceRoot":"","sources":["../../src/harness/memory-consolidation.test.ts"],"names":[],"mappings":"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"}
|
package/dist/harness/memory.d.ts
CHANGED
|
@@ -41,6 +41,18 @@ export declare function decayAndPrune(memories: MemoryEntry[]): {
|
|
|
41
41
|
};
|
|
42
42
|
/** Load memories with decay applied, sorted by relevance */
|
|
43
43
|
export declare function loadActiveMemories(): MemoryEntry[];
|
|
44
|
+
/** Delete memory files that have been pruned (relevance < 0.1) */
|
|
45
|
+
export declare function deletePrunedMemories(pruned: MemoryEntry[]): number;
|
|
46
|
+
export type ConsolidationResult = {
|
|
47
|
+
total: number;
|
|
48
|
+
pruned: number;
|
|
49
|
+
decayed: number;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Run full memory consolidation: apply decay, delete pruned files,
|
|
53
|
+
* persist updated relevance scores. Designed to run on session end.
|
|
54
|
+
*/
|
|
55
|
+
export declare function consolidateMemories(): ConsolidationResult;
|
|
44
56
|
/**
|
|
45
57
|
* Detect if recent assistant messages contain learnable patterns.
|
|
46
58
|
* Returns structured memories to save, or empty array.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/harness/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMrD,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,qDAAqD;AACrD,wBAAgB,YAAY,IAAI,WAAW,EAAE,CAgB5C;AA+BD,yDAAyD;AACzD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAMhE;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,UAAQ,GACb,MAAM,CAuBR;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAsBpD;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,SAAM,GAAG,IAAI,CAUrE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG;IAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CAyBvG;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,IAAI,WAAW,EAAE,CAKlD;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,OAAO,EAAE,EACzB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CA0CnG"}
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/harness/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMrD,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,qDAAqD;AACrD,wBAAgB,YAAY,IAAI,WAAW,EAAE,CAgB5C;AA+BD,yDAAyD;AACzD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAMhE;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,UAAQ,GACb,MAAM,CAuBR;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAsBpD;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,SAAM,GAAG,IAAI,CAUrE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG;IAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CAyBvG;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,IAAI,WAAW,EAAE,CAKlD;AAKD,kEAAkE;AAClE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAUlE;AAaD,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,mBAAmB,CAmBzD;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,OAAO,EAAE,EACzB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CA0CnG"}
|
package/dist/harness/memory.js
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* The system detects learnable patterns from assistant responses and saves them
|
|
8
8
|
* without user intervention.
|
|
9
9
|
*/
|
|
10
|
-
import { readFileSync, writeFileSync, mkdirSync, readdirSync, existsSync } from 'node:fs';
|
|
11
|
-
import { join } from 'node:path';
|
|
10
|
+
import { readFileSync, writeFileSync, mkdirSync, readdirSync, existsSync, unlinkSync } from 'node:fs';
|
|
11
|
+
import { join, resolve, sep } from 'node:path';
|
|
12
12
|
import { homedir } from 'node:os';
|
|
13
13
|
import { createUserMessage } from '../types/message.js';
|
|
14
14
|
const PROJECT_MEMORY_DIR = join('.oh', 'memory');
|
|
@@ -159,6 +159,57 @@ export function loadActiveMemories() {
|
|
|
159
159
|
// Sort by relevance (highest first), then by access count
|
|
160
160
|
return active.sort((a, b) => (b.relevance ?? 0.5) - (a.relevance ?? 0.5) || (b.accessCount ?? 0) - (a.accessCount ?? 0));
|
|
161
161
|
}
|
|
162
|
+
// ── Dream Consolidation ──
|
|
163
|
+
// Background memory pruning and relevance persistence on session end.
|
|
164
|
+
/** Delete memory files that have been pruned (relevance < 0.1) */
|
|
165
|
+
export function deletePrunedMemories(pruned) {
|
|
166
|
+
// Guard: only delete files within known memory directories
|
|
167
|
+
const allowedDirs = [PROJECT_MEMORY_DIR, GLOBAL_MEMORY_DIR].map(d => resolve(d));
|
|
168
|
+
let count = 0;
|
|
169
|
+
for (const m of pruned) {
|
|
170
|
+
const resolved = resolve(m.filePath);
|
|
171
|
+
if (!allowedDirs.some(d => resolved.startsWith(d + sep)))
|
|
172
|
+
continue;
|
|
173
|
+
try {
|
|
174
|
+
unlinkSync(m.filePath);
|
|
175
|
+
count++;
|
|
176
|
+
}
|
|
177
|
+
catch { /* ignore */ }
|
|
178
|
+
}
|
|
179
|
+
return count;
|
|
180
|
+
}
|
|
181
|
+
/** Write back decayed relevance score to file frontmatter */
|
|
182
|
+
function persistDecayedRelevance(entry) {
|
|
183
|
+
try {
|
|
184
|
+
let raw = readFileSync(entry.filePath, 'utf-8');
|
|
185
|
+
if (raw.match(/^relevance:/m)) {
|
|
186
|
+
raw = raw.replace(/^relevance:\s*[0-9.]+$/m, `relevance: ${(entry.relevance ?? 0.5).toFixed(2)}`);
|
|
187
|
+
writeFileSync(entry.filePath, raw);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
catch { /* ignore */ }
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Run full memory consolidation: apply decay, delete pruned files,
|
|
194
|
+
* persist updated relevance scores. Designed to run on session end.
|
|
195
|
+
*/
|
|
196
|
+
export function consolidateMemories() {
|
|
197
|
+
const all = loadMemories();
|
|
198
|
+
if (all.length === 0)
|
|
199
|
+
return { total: 0, pruned: 0, decayed: 0 };
|
|
200
|
+
const { active, pruned } = decayAndPrune(all);
|
|
201
|
+
// Delete pruned memory files
|
|
202
|
+
const prunedCount = deletePrunedMemories(pruned);
|
|
203
|
+
// Persist updated relevance scores for decayed memories
|
|
204
|
+
let decayedCount = 0;
|
|
205
|
+
for (const m of active) {
|
|
206
|
+
if ((m.relevance ?? 0.5) < 0.5) {
|
|
207
|
+
persistDecayedRelevance(m);
|
|
208
|
+
decayedCount++;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return { total: all.length, pruned: prunedCount, decayed: decayedCount };
|
|
212
|
+
}
|
|
162
213
|
/**
|
|
163
214
|
* Detect if recent assistant messages contain learnable patterns.
|
|
164
215
|
* Returns structured memories to save, or empty array.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/harness/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/harness/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACtG,OAAO,EAAE,IAAI,EAAY,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACjD,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;AAc3D,qDAAqD;AACrD,MAAM,UAAU,YAAY;IAC1B,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,GAAG,IAAI,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,EAAE,CAAC;QAC1D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAC/B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACnE,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACjC,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAC5C,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;gBACzC,IAAI,KAAK;oBAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjC,CAAC;YAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,mCAAmC;AACnC,SAAS,WAAW,CAAC,GAAW,EAAE,QAAgB;IAChD,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACtD,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAE5B,0DAA0D;IAC1D,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7D,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC9D,MAAM,iBAAiB,GAAG,GAAG,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAChE,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC1D,MAAM,gBAAgB,GAAG,GAAG,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAE9D,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE;QAC1B,IAAI,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,YAAY,CAAwB;QACrE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE;QACzC,OAAO;QACP,QAAQ;QACR,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,GAAG;QAChE,YAAY,EAAE,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,SAAS;QAC7E,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,SAAS;QACpE,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC;KACnE,CAAC;AACJ,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,gBAAgB,CAAC,QAAuB;IACtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAC7B,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC1D,CAAC;IACF,OAAO,yBAAyB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,IAAyB,EACzB,WAAmB,EACnB,OAAe,EACf,MAAM,GAAG,KAAK;IAEd,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,kBAAkB,CAAC;IAC5D,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;IAEzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,EAAE,GAAG;QACL,IAAI;QACJ,IAAI;eACG,WAAW;;aAEb,GAAG;gBACA,GAAG;;;;EAIjB,OAAO;CACR,CAAC;IAEA,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC5B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,WAAW,CAAC,KAAkB;IAC5C,IAAI,CAAC;QACH,IAAI,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAE9C,kDAAkD;QAClD,IAAI,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACjC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE,iBAAiB,GAAG,EAAE,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAChC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,uBAAuB,EAAE,gBAAgB,QAAQ,EAAE,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,gBAAgB,QAAQ,OAAO,CAAC,CAAC;QAClE,CAAC;QAED,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACnC,KAAK,CAAC,YAAY,GAAG,GAAG,CAAC;QACzB,KAAK,CAAC,WAAW,GAAG,QAAQ,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC,CAAC,yBAAyB,CAAC,CAAC;AACvC,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,cAAc,CAAC,KAAkB,EAAE,MAAM,GAAG,GAAG;IAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,IAAI,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAC9B,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,yBAAyB,EAAE,cAAc,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACnC,KAAK,CAAC,SAAS,GAAG,YAAY,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,QAAuB;IACnD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC7C,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,MAAM,MAAM,GAAkB,EAAE,CAAC;IAEjC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC;QACxD,MAAM,GAAG,GAAG,GAAG,GAAG,UAAU,CAAC;QAE7B,IAAI,GAAG,GAAG,WAAW,EAAE,CAAC;YACtB,sDAAsD;YACtD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,WAAW,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,YAAY,GAAG,GAAG,CAAC,CAAC;YACvE,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC;YAEtB,IAAI,OAAO,GAAG,GAAG,EAAE,CAAC;gBAClB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACf,SAAS;YACX,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB;IAChC,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACtC,0DAA0D;IAC1D,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3H,CAAC;AAED,4BAA4B;AAC5B,sEAAsE;AAEtE,kEAAkE;AAClE,MAAM,UAAU,oBAAoB,CAAC,MAAqB;IACxD,2DAA2D;IAC3D,MAAM,WAAW,GAAG,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAAE,SAAS;QACnE,IAAI,CAAC;YAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,6DAA6D;AAC7D,SAAS,uBAAuB,CAAC,KAAkB;IACjD,IAAI,CAAC;QACH,IAAI,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAC9B,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,yBAAyB,EAAE,cAAc,CAAC,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClG,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;AAC1B,CAAC;AAQD;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAEjE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAE9C,6BAA6B;IAC7B,MAAM,WAAW,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAEjD,wDAAwD;IACxD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;YAC/B,uBAAuB,CAAC,CAAC,CAAC,CAAC;YAC3B,YAAY,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AAC3E,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAkB,EAClB,cAAyB,EACzB,KAAc;IAEd,4CAA4C;IAC5C,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEzC,+CAA+C;IAC/C,MAAM,aAAa,GAAG,cAAc;SACjC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;SAC5D,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACb,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE1C,MAAM,WAAW,GAAG,aAAa;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SACjC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEnB,MAAM,MAAM,GAAG;;;;;;EAMf,WAAW,EAAE,CAAC;IAEd,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,CACtC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAC3B,mEAAmE,EACnE,SAAS,EACT,KAAK,CACN,CAAC;QAEF,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QAE1B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,CAAC;QAEtC,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAC3E,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -2,7 +2,7 @@ import test from "node:test";
|
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { makeTmpDir } from "../test-helpers.js";
|
|
5
|
-
import { loadMemories, saveMemory, memoriesToPrompt } from "./memory.js";
|
|
5
|
+
import { loadMemories, saveMemory, memoriesToPrompt, touchMemory, boostRelevance } from "./memory.js";
|
|
6
6
|
function withTmpCwd(fn) {
|
|
7
7
|
const dir = makeTmpDir();
|
|
8
8
|
const original = process.cwd();
|
|
@@ -62,4 +62,46 @@ test("saved memory has correct name/type/description in file content", () => {
|
|
|
62
62
|
assert.ok(raw.includes("Check for null before access"));
|
|
63
63
|
});
|
|
64
64
|
});
|
|
65
|
+
test("touchMemory updates lastAccessed and accessCount", () => {
|
|
66
|
+
withTmpCwd(() => {
|
|
67
|
+
const filePath = saveMemory("touch-test", "convention", "test", "content");
|
|
68
|
+
const raw1 = readFileSync(filePath, "utf-8");
|
|
69
|
+
assert.ok(raw1.includes("accessCount: 0"));
|
|
70
|
+
const entry = {
|
|
71
|
+
name: "touch-test", type: "convention", description: "test",
|
|
72
|
+
content: "content", filePath, accessCount: 0, lastAccessed: Date.now() - 10000,
|
|
73
|
+
};
|
|
74
|
+
touchMemory(entry);
|
|
75
|
+
const raw2 = readFileSync(filePath, "utf-8");
|
|
76
|
+
assert.ok(raw2.includes("accessCount: 1"));
|
|
77
|
+
assert.ok(entry.accessCount === 1);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
test("boostRelevance increases score and caps at 1.0", () => {
|
|
81
|
+
withTmpCwd(() => {
|
|
82
|
+
const filePath = saveMemory("boost-test", "convention", "test", "content");
|
|
83
|
+
const entry = {
|
|
84
|
+
name: "boost-test", type: "convention", description: "test",
|
|
85
|
+
content: "content", filePath, relevance: 0.5,
|
|
86
|
+
};
|
|
87
|
+
boostRelevance(entry, 0.3);
|
|
88
|
+
assert.equal(entry.relevance, 0.8);
|
|
89
|
+
// Verify written to file
|
|
90
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
91
|
+
assert.ok(raw.includes("relevance: 0.80"));
|
|
92
|
+
// Cap at 1.0
|
|
93
|
+
boostRelevance(entry, 0.5);
|
|
94
|
+
assert.equal(entry.relevance, 1.0);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
test("saved memory has relevance and timestamps in frontmatter", () => {
|
|
98
|
+
withTmpCwd(() => {
|
|
99
|
+
const filePath = saveMemory("meta-test", "preference", "test", "content");
|
|
100
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
101
|
+
assert.ok(raw.includes("relevance: 0.5"));
|
|
102
|
+
assert.ok(raw.match(/createdAt: \d+/));
|
|
103
|
+
assert.ok(raw.match(/lastAccessed: \d+/));
|
|
104
|
+
assert.ok(raw.includes("accessCount: 0"));
|
|
105
|
+
});
|
|
106
|
+
});
|
|
65
107
|
//# sourceMappingURL=memory.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.test.js","sourceRoot":"","sources":["../../src/harness/memory.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,UAAU,EAAa,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"memory.test.js","sourceRoot":"","sources":["../../src/harness/memory.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,4 +34,40 @@ test("listSessions() returns saved sessions sorted by updatedAt", async () => {
|
|
|
34
34
|
assert.equal(list[0].id, s2.id);
|
|
35
35
|
assert.equal(list[1].id, s1.id);
|
|
36
36
|
});
|
|
37
|
+
test("session IDs are unique across multiple creations", () => {
|
|
38
|
+
const ids = new Set();
|
|
39
|
+
for (let i = 0; i < 50; i++) {
|
|
40
|
+
const s = createSession("mock", "mock-model");
|
|
41
|
+
assert.ok(!ids.has(s.id), `Duplicate session ID: ${s.id}`);
|
|
42
|
+
ids.add(s.id);
|
|
43
|
+
}
|
|
44
|
+
assert.equal(ids.size, 50);
|
|
45
|
+
});
|
|
46
|
+
test("session preserves messages through save/load", () => {
|
|
47
|
+
const tmp = mkdtempSync(join(tmpdir(), "oh-test-"));
|
|
48
|
+
const s = createSession("openai", "gpt-4o");
|
|
49
|
+
s.messages = [
|
|
50
|
+
{ role: "user", content: "hello", uuid: "u1", timestamp: Date.now() },
|
|
51
|
+
{ role: "assistant", content: "hi there", uuid: "u2", timestamp: Date.now() },
|
|
52
|
+
];
|
|
53
|
+
s.totalCost = 0.0042;
|
|
54
|
+
saveSession(s, tmp);
|
|
55
|
+
const loaded = loadSession(s.id, tmp);
|
|
56
|
+
assert.equal(loaded.messages.length, 2);
|
|
57
|
+
assert.equal(loaded.messages[0].content, "hello");
|
|
58
|
+
assert.equal(loaded.messages[1].content, "hi there");
|
|
59
|
+
assert.equal(loaded.totalCost, 0.0042);
|
|
60
|
+
});
|
|
61
|
+
test("listSessions returns empty for empty directory", () => {
|
|
62
|
+
const tmp = mkdtempSync(join(tmpdir(), "oh-test-"));
|
|
63
|
+
const list = listSessions(tmp);
|
|
64
|
+
assert.equal(list.length, 0);
|
|
65
|
+
});
|
|
66
|
+
test("session has timestamps set on creation", () => {
|
|
67
|
+
const before = Date.now();
|
|
68
|
+
const s = createSession("mock", "model");
|
|
69
|
+
const after = Date.now();
|
|
70
|
+
assert.ok(s.createdAt >= before && s.createdAt <= after);
|
|
71
|
+
assert.ok(s.updatedAt >= before && s.updatedAt <= after);
|
|
72
|
+
});
|
|
37
73
|
//# sourceMappingURL=session.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.test.js","sourceRoot":"","sources":["../../src/harness/session.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAErF,IAAI,CAAC,oDAAoD,EAAE,GAAG,EAAE;IAC9D,MAAM,CAAC,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC5C,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3B,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yCAAyC,EAAE,GAAG,EAAE;IACnD,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,aAAa,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;IAC1D,WAAW,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpB,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACtC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC3C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;IAC3E,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAClD,WAAW,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACrB,mCAAmC;IACnC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5C,WAAW,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAErB,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7B,oBAAoB;IACpB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"session.test.js","sourceRoot":"","sources":["../../src/harness/session.test.ts"],"names":[],"mappings":"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"}
|