agent-working-memory 0.13.1 → 0.14.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/README.md +200 -238
- package/dist/adapters/common.d.ts +6 -0
- package/dist/adapters/common.d.ts.map +1 -1
- package/dist/adapters/common.js +457 -362
- package/dist/adapters/common.js.map +1 -1
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +24 -8
- package/dist/api/routes.js.map +1 -1
- package/dist/core/alias-map.d.ts +16 -0
- package/dist/core/alias-map.d.ts.map +1 -0
- package/dist/core/alias-map.js +102 -0
- package/dist/core/alias-map.js.map +1 -0
- package/dist/core/embeddings.d.ts +17 -0
- package/dist/core/embeddings.d.ts.map +1 -1
- package/dist/core/embeddings.js +50 -1
- package/dist/core/embeddings.js.map +1 -1
- package/dist/core/recall-config.d.ts +52 -0
- package/dist/core/recall-config.d.ts.map +1 -0
- package/dist/core/recall-config.js +110 -0
- package/dist/core/recall-config.js.map +1 -0
- package/dist/core/rerank-window.d.ts +61 -0
- package/dist/core/rerank-window.d.ts.map +1 -0
- package/dist/core/rerank-window.js +153 -0
- package/dist/core/rerank-window.js.map +1 -0
- package/dist/core/rerank2.d.ts +62 -0
- package/dist/core/rerank2.d.ts.map +1 -0
- package/dist/core/rerank2.js +75 -0
- package/dist/core/rerank2.js.map +1 -0
- package/dist/core/retrieval-text.d.ts +55 -0
- package/dist/core/retrieval-text.d.ts.map +1 -0
- package/dist/core/retrieval-text.js +87 -0
- package/dist/core/retrieval-text.js.map +1 -0
- package/dist/core/temporal-query.d.ts +61 -0
- package/dist/core/temporal-query.d.ts.map +1 -0
- package/dist/core/temporal-query.js +168 -0
- package/dist/core/temporal-query.js.map +1 -0
- package/dist/core/token-budget.d.ts +75 -0
- package/dist/core/token-budget.d.ts.map +1 -0
- package/dist/core/token-budget.js +136 -0
- package/dist/core/token-budget.js.map +1 -0
- package/dist/core/whoami.d.ts +11 -0
- package/dist/core/whoami.d.ts.map +1 -1
- package/dist/core/whoami.js +10 -0
- package/dist/core/whoami.js.map +1 -1
- package/dist/core/write-pipeline.d.ts.map +1 -1
- package/dist/core/write-pipeline.js +6 -3
- package/dist/core/write-pipeline.js.map +1 -1
- package/dist/engine/activation.d.ts.map +1 -1
- package/dist/engine/activation.js +146 -32
- package/dist/engine/activation.js.map +1 -1
- package/dist/hooks/prime.d.ts +77 -0
- package/dist/hooks/prime.d.ts.map +1 -0
- package/dist/hooks/prime.js +92 -0
- package/dist/hooks/prime.js.map +1 -0
- package/dist/hooks/sidecar.d.ts.map +1 -1
- package/dist/hooks/sidecar.js +39 -0
- package/dist/hooks/sidecar.js.map +1 -1
- package/dist/mcp.js +160 -107
- package/dist/mcp.js.map +1 -1
- package/dist/storage/pglite.d.ts.map +1 -1
- package/dist/storage/pglite.js +10 -2
- package/dist/storage/pglite.js.map +1 -1
- package/dist/storage/postgres.d.ts.map +1 -1
- package/dist/storage/postgres.js +10 -2
- package/dist/storage/postgres.js.map +1 -1
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +12 -2
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/types/engram.d.ts +31 -0
- package/dist/types/engram.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/adapters/common.ts +666 -567
- package/src/api/routes.ts +1015 -999
- package/src/core/alias-map.ts +97 -0
- package/src/core/embeddings.ts +172 -115
- package/src/core/recall-config.ts +115 -0
- package/src/core/rerank-window.ts +158 -0
- package/src/core/rerank2.ts +82 -0
- package/src/core/retrieval-text.ts +82 -0
- package/src/core/temporal-query.ts +193 -0
- package/src/core/token-budget.ts +160 -0
- package/src/core/whoami.ts +110 -92
- package/src/core/write-pipeline.ts +6 -3
- package/src/engine/activation.ts +1579 -1468
- package/src/hooks/prime.ts +136 -0
- package/src/hooks/sidecar.ts +43 -0
- package/src/mcp.ts +1443 -1387
- package/src/storage/pglite.ts +10 -2
- package/src/storage/postgres.ts +10 -2
- package/src/storage/sqlite.ts +12 -2
- package/src/types/engram.ts +32 -0
package/src/core/whoami.ts
CHANGED
|
@@ -1,92 +1,110 @@
|
|
|
1
|
-
// Copyright 2026 Robert Winter / Complete Ideas
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Instance identity (D3, 2026-07-30).
|
|
6
|
-
*
|
|
7
|
-
* Answers "which AWM am I talking to?" — the recurring confusion class where
|
|
8
|
-
* sessions mix up the hosted multi-agent connector with the local instance,
|
|
9
|
-
* or run blind to sibling agent spaces in the same store (an evaluation once
|
|
10
|
-
* analyzed this project without seeing the `personal` space that held its
|
|
11
|
-
* design decisions).
|
|
12
|
-
*
|
|
13
|
-
* Exposed as the `memory_whoami` MCP tool and the `GET /whoami` HTTP route.
|
|
14
|
-
* Read-only; additive module.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { dirname, join, resolve } from 'node:path';
|
|
18
|
-
import { fileURLToPath } from 'node:url';
|
|
19
|
-
import { VERSION } from '../version.js';
|
|
20
|
-
import { getConfiguredBackend, getConfiguredPath } from '../storage/factory.js';
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
1
|
+
// Copyright 2026 Robert Winter / Complete Ideas
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Instance identity (D3, 2026-07-30).
|
|
6
|
+
*
|
|
7
|
+
* Answers "which AWM am I talking to?" — the recurring confusion class where
|
|
8
|
+
* sessions mix up the hosted multi-agent connector with the local instance,
|
|
9
|
+
* or run blind to sibling agent spaces in the same store (an evaluation once
|
|
10
|
+
* analyzed this project without seeing the `personal` space that held its
|
|
11
|
+
* design decisions).
|
|
12
|
+
*
|
|
13
|
+
* Exposed as the `memory_whoami` MCP tool and the `GET /whoami` HTTP route.
|
|
14
|
+
* Read-only; additive module.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { dirname, join, resolve } from 'node:path';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
import { VERSION } from '../version.js';
|
|
20
|
+
import { getConfiguredBackend, getConfiguredPath } from '../storage/factory.js';
|
|
21
|
+
import { activeRecallConfig, recallConfigFingerprint } from './recall-config.js';
|
|
22
|
+
import { embeddingHealth } from './embeddings.js';
|
|
23
|
+
|
|
24
|
+
export interface WhoamiInfo {
|
|
25
|
+
agentId: string;
|
|
26
|
+
workspace: string | null;
|
|
27
|
+
surface: 'mcp' | 'http';
|
|
28
|
+
mode: 'standalone' | 'hive';
|
|
29
|
+
backend: string;
|
|
30
|
+
storePath: string;
|
|
31
|
+
version: string;
|
|
32
|
+
codePath: string;
|
|
33
|
+
pid: number;
|
|
34
|
+
ports: { http: number | null; hookSidecar: number | null };
|
|
35
|
+
/**
|
|
36
|
+
* Effective recall configuration. `whoami` is the "what am I actually
|
|
37
|
+
* running" tool, and the version alone does not answer that: a build can be
|
|
38
|
+
* current while the recall flags that change its behaviour are unset, or set
|
|
39
|
+
* to something unintended. GET /health already reports this, but HTTP is off
|
|
40
|
+
* by default, so an MCP-only session had no way to see it.
|
|
41
|
+
*/
|
|
42
|
+
recall: { fingerprint: string; flags: Record<string, string> };
|
|
43
|
+
siblingAgents: string[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Store subset whoami needs — every backend implements listAgentIds. */
|
|
47
|
+
export interface WhoamiStore {
|
|
48
|
+
listAgentIds(): string[] | Promise<string[]>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function packageRoot(): string {
|
|
52
|
+
// src/core/whoami.ts (dev) and dist/core/whoami.js (build) both sit two
|
|
53
|
+
// levels below the package root.
|
|
54
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
55
|
+
return resolve(join(here, '..', '..'));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function buildWhoami(
|
|
59
|
+
store: WhoamiStore,
|
|
60
|
+
agentId: string,
|
|
61
|
+
surface: 'mcp' | 'http',
|
|
62
|
+
): Promise<WhoamiInfo> {
|
|
63
|
+
const coordination = process.env.AWM_COORDINATION === 'true' || process.env.AWM_COORDINATION === '1';
|
|
64
|
+
let siblings: string[] = [];
|
|
65
|
+
try {
|
|
66
|
+
const all = await store.listAgentIds();
|
|
67
|
+
siblings = all.filter(a => a !== agentId).sort();
|
|
68
|
+
} catch { /* identity must never fail on a listing error */ }
|
|
69
|
+
const httpPort = Number(process.env.AWM_PORT ?? '');
|
|
70
|
+
const hookPort = Number(process.env.AWM_HOOK_PORT ?? '');
|
|
71
|
+
return {
|
|
72
|
+
agentId,
|
|
73
|
+
workspace: process.env.AWM_WORKSPACE ?? null,
|
|
74
|
+
surface,
|
|
75
|
+
mode: coordination ? 'hive' : 'standalone',
|
|
76
|
+
backend: getConfiguredBackend(),
|
|
77
|
+
storePath: getConfiguredPath(),
|
|
78
|
+
version: VERSION,
|
|
79
|
+
codePath: packageRoot(),
|
|
80
|
+
pid: process.pid,
|
|
81
|
+
ports: {
|
|
82
|
+
http: Number.isFinite(httpPort) && httpPort > 0 ? httpPort : null,
|
|
83
|
+
hookSidecar: Number.isFinite(hookPort) && hookPort > 0 ? hookPort : null,
|
|
84
|
+
},
|
|
85
|
+
recall: { fingerprint: recallConfigFingerprint(), flags: activeRecallConfig() },
|
|
86
|
+
siblingAgents: siblings,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Human-readable rendering for the MCP tool response. */
|
|
91
|
+
export function formatWhoami(w: WhoamiInfo): string {
|
|
92
|
+
return [
|
|
93
|
+
`Agent: ${w.agentId}${w.workspace ? ` (workspace: ${w.workspace})` : ''}`,
|
|
94
|
+
`Mode: ${w.mode} · Surface: ${w.surface} · Version: ${w.version}`,
|
|
95
|
+
`Backend: ${w.backend}`,
|
|
96
|
+
`Store: ${w.storePath}`,
|
|
97
|
+
`Code: ${w.codePath} (pid ${w.pid})`,
|
|
98
|
+
`Ports: http=${w.ports.http ?? 'off'} hookSidecar=${w.ports.hookSidecar ?? 'off'}`,
|
|
99
|
+
`Recall config: ${w.recall.fingerprint}`,
|
|
100
|
+
...(embeddingHealth().dimensionMismatches > 0
|
|
101
|
+
? [`\u26a0 EMBEDDING INTEGRITY: ${embeddingHealth().dimensionMismatches} dimension mismatches ` +
|
|
102
|
+
`(expected ${embeddingHealth().expectedDimensions}d). Affected memories score 0 on the ` +
|
|
103
|
+
`vector channel — the corpus is probably half-migrated. Re-embed the whole store or ` +
|
|
104
|
+
`revert AWM_EMBED_MODEL/AWM_EMBED_DIMS.`]
|
|
105
|
+
: []),
|
|
106
|
+
w.siblingAgents.length
|
|
107
|
+
? `Sibling agent spaces in this store: ${w.siblingAgents.join(', ')} — recall is scoped to '${w.agentId}'; other spaces need workspace recall, \`awm export --agent <id>\`, or a session configured for that agent.`
|
|
108
|
+
: 'Sibling agent spaces in this store: none',
|
|
109
|
+
].join('\n');
|
|
110
|
+
}
|
|
@@ -51,6 +51,7 @@ import { extractMetaTags } from './auto-tagger.js';
|
|
|
51
51
|
import { extractEntitiesFromTags } from './entity-extract.js';
|
|
52
52
|
import { reportWrite } from './write-telemetry.js';
|
|
53
53
|
import { DEFAULT_AGENT_CONFIG } from '../types/agent.js';
|
|
54
|
+
import { buildRetrievalText } from './retrieval-text.js';
|
|
54
55
|
|
|
55
56
|
/** Confidence floor below which a matched engram is treated as "decaying out". */
|
|
56
57
|
export const HEALTHY_CONFIDENCE_FLOOR = 0.3;
|
|
@@ -195,7 +196,7 @@ export async function performWrite(
|
|
|
195
196
|
let prewriteEmbedding: number[] | null = null;
|
|
196
197
|
if (process.env.AWM_NOVELTY_EMBED !== '0') {
|
|
197
198
|
try {
|
|
198
|
-
prewriteEmbedding = await embed(
|
|
199
|
+
prewriteEmbedding = await embed(buildRetrievalText(input.concept, input.content, input.tags));
|
|
199
200
|
} catch { /* fall through — async embed will retry later */ }
|
|
200
201
|
}
|
|
201
202
|
tEmbed = performance.now() - tStartEmbed;
|
|
@@ -434,7 +435,9 @@ async function reinforceMatched(
|
|
|
434
435
|
// beyond 512 tokens but the topic anchor (early content) drives
|
|
435
436
|
// the vector for retrieval purposes.
|
|
436
437
|
const conceptForEmbed = newConceptHint || matched.concept;
|
|
437
|
-
|
|
438
|
+
// The reinforced engram's OWN tags — `input` is not in scope here, and
|
|
439
|
+
// the stored tags are the right vocabulary for the stored memory anyway.
|
|
440
|
+
const newVec = await embed(buildRetrievalText(conceptForEmbed, mergedContent, matched.tags));
|
|
438
441
|
await store.updateEmbedding(matched.id, newVec);
|
|
439
442
|
} catch { /* merge is best-effort — confidence bump already landed */ }
|
|
440
443
|
}
|
|
@@ -574,7 +577,7 @@ async function createNewEngram(
|
|
|
574
577
|
const alreadyEmbedded = prewriteEmbedding != null && prewriteEmbedding.length > 0;
|
|
575
578
|
const shouldEmbed = (!isStructural || input.embed === true) && !alreadyEmbedded;
|
|
576
579
|
if (shouldEmbed) {
|
|
577
|
-
embed(
|
|
580
|
+
embed(buildRetrievalText(input.concept, input.content, input.tags))
|
|
578
581
|
.then(async vec => {
|
|
579
582
|
try { await store.updateEmbedding(engram.id, vec); } catch { /* engram may be evicted */ }
|
|
580
583
|
})
|