agent-working-memory 0.7.16 → 0.7.17
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/adapters/claude-code.d.ts.map +1 -1
- package/dist/adapters/claude-code.js +2 -16
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adapters/codex.d.ts.map +1 -1
- package/dist/adapters/codex.js +2 -11
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/common.d.ts +18 -0
- package/dist/adapters/common.d.ts.map +1 -1
- package/dist/adapters/common.js +127 -14
- package/dist/adapters/common.js.map +1 -1
- package/dist/adapters/cursor.d.ts.map +1 -1
- package/dist/adapters/cursor.js +2 -15
- package/dist/adapters/cursor.js.map +1 -1
- package/dist/adapters/http.d.ts.map +1 -1
- package/dist/adapters/http.js +6 -12
- package/dist/adapters/http.js.map +1 -1
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +45 -57
- package/dist/api/routes.js.map +1 -1
- package/dist/cli.js +103 -103
- package/dist/core/write-pipeline.d.ts +120 -0
- package/dist/core/write-pipeline.d.ts.map +1 -0
- package/dist/core/write-pipeline.js +236 -0
- package/dist/core/write-pipeline.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/mcp.js +107 -178
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/claude-code.ts +2 -18
- package/src/adapters/codex.ts +2 -12
- package/src/adapters/common.ts +141 -14
- package/src/adapters/cursor.ts +2 -17
- package/src/adapters/http.ts +5 -12
- package/src/api/routes.ts +714 -723
- package/src/cli.ts +719 -719
- package/src/core/write-pipeline.ts +343 -0
- package/src/index.ts +212 -212
- package/src/mcp.ts +1121 -1192
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified write pipeline — shared implementation of the three write-time
|
|
3
|
+
* memory rules (R1/R2/R3) that distinguish AWM as a "memory" system
|
|
4
|
+
* (selective retention) rather than "storage" (retrieve-all-then-dump):
|
|
5
|
+
*
|
|
6
|
+
* R1 — Reinforce on duplicate. Repeat = stronger memory. When a new
|
|
7
|
+
* write shares the EXACT same concept as an existing engram,
|
|
8
|
+
* boost that engram's confidence + access count instead of
|
|
9
|
+
* creating a new near-duplicate. One strong engram beats N weak
|
|
10
|
+
* ones.
|
|
11
|
+
*
|
|
12
|
+
* R2 — Pick the RIGHT match. Skip the match if it's already
|
|
13
|
+
* superseded, unhealthy (confidence < 0.3), or not in active
|
|
14
|
+
* stage. If the match is superseded, reinforce the SUPERSEDER
|
|
15
|
+
* instead (the "we fixed it, now we know better" chain).
|
|
16
|
+
*
|
|
17
|
+
* R3 — Corrections override. When the write's eventType is `surprise`
|
|
18
|
+
* or `friction` AND the matched engram is the same concept, the
|
|
19
|
+
* new write SUPERSEDES the matched engram instead of reinforcing
|
|
20
|
+
* it. Fresh truth beats old habit.
|
|
21
|
+
*
|
|
22
|
+
* Critical implementation detail (lesson from LoCoMo 2026-05-12): the
|
|
23
|
+
* match-vs-create pivot is **concept equality**, not raw novelty.
|
|
24
|
+
* Thresholding on novelty alone collapses distinct facts that happen to
|
|
25
|
+
* share template language (e.g. 419 conversation turns all prefixed
|
|
26
|
+
* "[session_3] Caroline: ..." merged into 7 engrams, recall coverage
|
|
27
|
+
* halved). Concept equality is the sharp signal: same concept means
|
|
28
|
+
* the writer is restating the same topic.
|
|
29
|
+
*
|
|
30
|
+
* Disposition (active/staging/discard) is still set from evaluateSalience
|
|
31
|
+
* for the CREATE path. REINFORCE writes never reach staging — they just
|
|
32
|
+
* touch an existing engram. SUPERSEDE writes follow the disposition of
|
|
33
|
+
* the new engram (typically active because corrections are high-salience).
|
|
34
|
+
*/
|
|
35
|
+
import type { EngramStore } from '../storage/sqlite.js';
|
|
36
|
+
import type { ConnectionEngine } from '../engine/connections.js';
|
|
37
|
+
import type { Engram, MemoryClass, MemoryType } from '../types/engram.js';
|
|
38
|
+
import { type SalienceEventType, type SalienceResult, type NoveltyResult } from './salience.js';
|
|
39
|
+
/** Confidence floor below which a matched engram is treated as "decaying out". */
|
|
40
|
+
export declare const HEALTHY_CONFIDENCE_FLOOR = 0.3;
|
|
41
|
+
/** Confidence delta applied on reinforcement. Bounded by REINFORCE_CONFIDENCE_CEIL. */
|
|
42
|
+
export declare const REINFORCE_CONFIDENCE_DELTA = 0.05;
|
|
43
|
+
export declare const REINFORCE_CONFIDENCE_CEIL = 0.95;
|
|
44
|
+
export type WriteAction = 'create' | 'reinforce' | 'supersede';
|
|
45
|
+
export interface WriteInput {
|
|
46
|
+
agentId: string;
|
|
47
|
+
concept: string;
|
|
48
|
+
content: string;
|
|
49
|
+
/** Tags as the caller wants them stored (already assembled). */
|
|
50
|
+
tags?: string[];
|
|
51
|
+
memoryClass?: MemoryClass;
|
|
52
|
+
memoryType?: MemoryType;
|
|
53
|
+
eventType?: SalienceEventType;
|
|
54
|
+
surprise?: number;
|
|
55
|
+
decisionMade?: boolean;
|
|
56
|
+
causalDepth?: number;
|
|
57
|
+
resolutionEffort?: number;
|
|
58
|
+
/** Confidence override. When unset, defaults from disposition + eventType priors. */
|
|
59
|
+
confidence?: number;
|
|
60
|
+
/** Explicit supersession requested by caller (independent of correction-on-match). */
|
|
61
|
+
supersedes?: string;
|
|
62
|
+
/** Workspace scope for cross-agent novelty (v0.5.4+ stores only). */
|
|
63
|
+
workspace?: string | null;
|
|
64
|
+
/** Set to false to skip the reinforce/supersede branching and always create. */
|
|
65
|
+
enableReinforcement?: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface WriteResult {
|
|
68
|
+
action: WriteAction;
|
|
69
|
+
/**
|
|
70
|
+
* For action='create' or 'supersede': the newly created engram.
|
|
71
|
+
* For action='reinforce': the EXISTING engram that was reinforced
|
|
72
|
+
* (its confidence and access_count have been bumped in place).
|
|
73
|
+
*/
|
|
74
|
+
engram: Engram;
|
|
75
|
+
/** Salience result — present for create/supersede; null for reinforce (no new salience evaluation). */
|
|
76
|
+
salience: SalienceResult | null;
|
|
77
|
+
/** Novelty + match info, useful for caller logging. */
|
|
78
|
+
noveltyResult: NoveltyResult;
|
|
79
|
+
/** Reinforcement detail — present only for action='reinforce'. */
|
|
80
|
+
reinforce?: {
|
|
81
|
+
previousConfidence: number;
|
|
82
|
+
newConfidence: number;
|
|
83
|
+
previousAccessCount: number;
|
|
84
|
+
};
|
|
85
|
+
/** Supersession detail — present only for action='supersede'. */
|
|
86
|
+
supersedeOf?: {
|
|
87
|
+
id: string;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export interface WritePipelineEngines {
|
|
91
|
+
store: EngramStore;
|
|
92
|
+
connectionEngine: ConnectionEngine;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Run a write through the unified pipeline.
|
|
96
|
+
*
|
|
97
|
+
* Side effects (always):
|
|
98
|
+
* - Compute novelty + best match
|
|
99
|
+
* - Evaluate salience for audit
|
|
100
|
+
*
|
|
101
|
+
* Side effects (action-dependent):
|
|
102
|
+
* - REINFORCE: touchEngram + updateConfidence on the matched engram;
|
|
103
|
+
* no new engram is created.
|
|
104
|
+
* - SUPERSEDE: createEngram with supersedes=matched.id, then call
|
|
105
|
+
* supersedeEngram. Async embed + enqueue follow.
|
|
106
|
+
* - CREATE: createEngram, async embed + enqueue. If salience says
|
|
107
|
+
* staging, updateStage to 'staging'.
|
|
108
|
+
*
|
|
109
|
+
* The caller is responsible for:
|
|
110
|
+
* - Tag assembly (callers know their own metadata format)
|
|
111
|
+
* - Temporal adjacency edges
|
|
112
|
+
* - Episode assignment
|
|
113
|
+
* - Auto-checkpoint tracking
|
|
114
|
+
* - Decision propagation
|
|
115
|
+
*
|
|
116
|
+
* Set process.env.AWM_WRITE_PIPELINE=off to revert to legacy create-only
|
|
117
|
+
* behavior (the same write inputs but every write creates a new engram).
|
|
118
|
+
*/
|
|
119
|
+
export declare function performWrite(engines: WritePipelineEngines, input: WriteInput): WriteResult;
|
|
120
|
+
//# sourceMappingURL=write-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-pipeline.d.ts","sourceRoot":"","sources":["../../src/core/write-pipeline.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,eAAe,CAAC;AAIvB,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAE5C,uFAAuF;AACvF,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAC/C,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAY9C,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gFAAgF;IAChF,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,uGAAuG;IACvG,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,uDAAuD;IACvD,aAAa,EAAE,aAAa,CAAC;IAC7B,kEAAkE;IAClE,SAAS,CAAC,EAAE;QACV,kBAAkB,EAAE,MAAM,CAAC;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,iEAAiE;IACjE,WAAW,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,WAAW,CAAC;IACnB,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,oBAAoB,EAC7B,KAAK,EAAE,UAAU,GAChB,WAAW,CAkFb"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
// Copyright 2026 Robert Winter / Complete Ideas
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Unified write pipeline — shared implementation of the three write-time
|
|
5
|
+
* memory rules (R1/R2/R3) that distinguish AWM as a "memory" system
|
|
6
|
+
* (selective retention) rather than "storage" (retrieve-all-then-dump):
|
|
7
|
+
*
|
|
8
|
+
* R1 — Reinforce on duplicate. Repeat = stronger memory. When a new
|
|
9
|
+
* write shares the EXACT same concept as an existing engram,
|
|
10
|
+
* boost that engram's confidence + access count instead of
|
|
11
|
+
* creating a new near-duplicate. One strong engram beats N weak
|
|
12
|
+
* ones.
|
|
13
|
+
*
|
|
14
|
+
* R2 — Pick the RIGHT match. Skip the match if it's already
|
|
15
|
+
* superseded, unhealthy (confidence < 0.3), or not in active
|
|
16
|
+
* stage. If the match is superseded, reinforce the SUPERSEDER
|
|
17
|
+
* instead (the "we fixed it, now we know better" chain).
|
|
18
|
+
*
|
|
19
|
+
* R3 — Corrections override. When the write's eventType is `surprise`
|
|
20
|
+
* or `friction` AND the matched engram is the same concept, the
|
|
21
|
+
* new write SUPERSEDES the matched engram instead of reinforcing
|
|
22
|
+
* it. Fresh truth beats old habit.
|
|
23
|
+
*
|
|
24
|
+
* Critical implementation detail (lesson from LoCoMo 2026-05-12): the
|
|
25
|
+
* match-vs-create pivot is **concept equality**, not raw novelty.
|
|
26
|
+
* Thresholding on novelty alone collapses distinct facts that happen to
|
|
27
|
+
* share template language (e.g. 419 conversation turns all prefixed
|
|
28
|
+
* "[session_3] Caroline: ..." merged into 7 engrams, recall coverage
|
|
29
|
+
* halved). Concept equality is the sharp signal: same concept means
|
|
30
|
+
* the writer is restating the same topic.
|
|
31
|
+
*
|
|
32
|
+
* Disposition (active/staging/discard) is still set from evaluateSalience
|
|
33
|
+
* for the CREATE path. REINFORCE writes never reach staging — they just
|
|
34
|
+
* touch an existing engram. SUPERSEDE writes follow the disposition of
|
|
35
|
+
* the new engram (typically active because corrections are high-salience).
|
|
36
|
+
*/
|
|
37
|
+
import { evaluateSalience, computeNoveltyWithMatch, detectUserFeedback, } from './salience.js';
|
|
38
|
+
import { embed } from './embeddings.js';
|
|
39
|
+
import { DEFAULT_AGENT_CONFIG } from '../types/agent.js';
|
|
40
|
+
/** Confidence floor below which a matched engram is treated as "decaying out". */
|
|
41
|
+
export const HEALTHY_CONFIDENCE_FLOOR = 0.3;
|
|
42
|
+
/** Confidence delta applied on reinforcement. Bounded by REINFORCE_CONFIDENCE_CEIL. */
|
|
43
|
+
export const REINFORCE_CONFIDENCE_DELTA = 0.05;
|
|
44
|
+
export const REINFORCE_CONFIDENCE_CEIL = 0.95;
|
|
45
|
+
/** Default disposition-confidence priors when the caller doesn't supply one. */
|
|
46
|
+
const CONFIDENCE_PRIORS = {
|
|
47
|
+
decision: 0.65,
|
|
48
|
+
friction: 0.60,
|
|
49
|
+
causal: 0.60,
|
|
50
|
+
surprise: 0.55,
|
|
51
|
+
user_feedback: 0.70,
|
|
52
|
+
observation: 0.45,
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Run a write through the unified pipeline.
|
|
56
|
+
*
|
|
57
|
+
* Side effects (always):
|
|
58
|
+
* - Compute novelty + best match
|
|
59
|
+
* - Evaluate salience for audit
|
|
60
|
+
*
|
|
61
|
+
* Side effects (action-dependent):
|
|
62
|
+
* - REINFORCE: touchEngram + updateConfidence on the matched engram;
|
|
63
|
+
* no new engram is created.
|
|
64
|
+
* - SUPERSEDE: createEngram with supersedes=matched.id, then call
|
|
65
|
+
* supersedeEngram. Async embed + enqueue follow.
|
|
66
|
+
* - CREATE: createEngram, async embed + enqueue. If salience says
|
|
67
|
+
* staging, updateStage to 'staging'.
|
|
68
|
+
*
|
|
69
|
+
* The caller is responsible for:
|
|
70
|
+
* - Tag assembly (callers know their own metadata format)
|
|
71
|
+
* - Temporal adjacency edges
|
|
72
|
+
* - Episode assignment
|
|
73
|
+
* - Auto-checkpoint tracking
|
|
74
|
+
* - Decision propagation
|
|
75
|
+
*
|
|
76
|
+
* Set process.env.AWM_WRITE_PIPELINE=off to revert to legacy create-only
|
|
77
|
+
* behavior (the same write inputs but every write creates a new engram).
|
|
78
|
+
*/
|
|
79
|
+
export function performWrite(engines, input) {
|
|
80
|
+
const { store, connectionEngine } = engines;
|
|
81
|
+
const enableReinforcement = input.enableReinforcement !== false
|
|
82
|
+
&& process.env.AWM_WRITE_PIPELINE !== 'off';
|
|
83
|
+
const noveltyResult = computeNoveltyWithMatch(store, input.agentId, input.concept, input.content, input.workspace ?? null);
|
|
84
|
+
// Effective event type — auto-promote user-feedback content.
|
|
85
|
+
const effectiveEventType = input.eventType ?? (detectUserFeedback(input.content) ? 'user_feedback' : 'observation');
|
|
86
|
+
// Effective memory class — auto-canonical for user-feedback and verified findings.
|
|
87
|
+
let effectiveMemoryClass = input.memoryClass;
|
|
88
|
+
if (!effectiveMemoryClass && effectiveEventType === 'user_feedback') {
|
|
89
|
+
effectiveMemoryClass = 'canonical';
|
|
90
|
+
}
|
|
91
|
+
const salience = evaluateSalience({
|
|
92
|
+
content: input.content,
|
|
93
|
+
eventType: effectiveEventType,
|
|
94
|
+
surprise: input.surprise,
|
|
95
|
+
decisionMade: input.decisionMade,
|
|
96
|
+
causalDepth: input.causalDepth,
|
|
97
|
+
resolutionEffort: input.resolutionEffort,
|
|
98
|
+
novelty: noveltyResult.novelty,
|
|
99
|
+
memoryClass: effectiveMemoryClass,
|
|
100
|
+
});
|
|
101
|
+
// -- Reinforce / Supersede branching --
|
|
102
|
+
if (enableReinforcement && noveltyResult.matchedEngramId) {
|
|
103
|
+
const matched = store.getEngram(noveltyResult.matchedEngramId);
|
|
104
|
+
if (matched) {
|
|
105
|
+
const newConcept = (input.concept ?? '').toLowerCase().trim();
|
|
106
|
+
const matchedConcept = (matched.concept ?? '').toLowerCase().trim();
|
|
107
|
+
const sameConcept = newConcept === matchedConcept && newConcept.length > 0;
|
|
108
|
+
if (sameConcept) {
|
|
109
|
+
const isCorrectionSignal = effectiveEventType === 'surprise'
|
|
110
|
+
|| effectiveEventType === 'friction';
|
|
111
|
+
if (isCorrectionSignal) {
|
|
112
|
+
// R3 — supersede the matched engram with the new write
|
|
113
|
+
return createNewEngram(engines, input, salience, noveltyResult, {
|
|
114
|
+
effectiveEventType,
|
|
115
|
+
effectiveMemoryClass,
|
|
116
|
+
supersedesId: matched.id,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
// R2 — health check on the matched engram
|
|
120
|
+
const isHealthy = matched.stage === 'active'
|
|
121
|
+
&& matched.confidence >= HEALTHY_CONFIDENCE_FLOOR
|
|
122
|
+
&& matched.supersededBy == null;
|
|
123
|
+
if (isHealthy) {
|
|
124
|
+
// R1 — reinforce
|
|
125
|
+
return reinforceMatched(store, matched, noveltyResult, salience);
|
|
126
|
+
}
|
|
127
|
+
// Unhealthy match but it was superseded — try to reinforce the superseder
|
|
128
|
+
if (matched.supersededBy) {
|
|
129
|
+
const superseder = store.getEngram(matched.supersededBy);
|
|
130
|
+
if (superseder && superseder.stage === 'active'
|
|
131
|
+
&& superseder.confidence >= HEALTHY_CONFIDENCE_FLOOR
|
|
132
|
+
&& superseder.supersededBy == null) {
|
|
133
|
+
return reinforceMatched(store, superseder, noveltyResult, salience);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Otherwise fall through to create new
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// -- Default: create new engram --
|
|
141
|
+
return createNewEngram(engines, input, salience, noveltyResult, {
|
|
142
|
+
effectiveEventType,
|
|
143
|
+
effectiveMemoryClass,
|
|
144
|
+
supersedesId: input.supersedes,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function reinforceMatched(store, matched, noveltyResult, salience) {
|
|
148
|
+
const previousConfidence = matched.confidence;
|
|
149
|
+
const previousAccessCount = matched.accessCount;
|
|
150
|
+
const newConfidence = Math.min(REINFORCE_CONFIDENCE_CEIL, previousConfidence + REINFORCE_CONFIDENCE_DELTA);
|
|
151
|
+
store.updateConfidence(matched.id, newConfidence);
|
|
152
|
+
store.touchEngram(matched.id);
|
|
153
|
+
// Return the engram with the updated values reflected (the DB write
|
|
154
|
+
// happened above; the in-memory object is one snapshot behind).
|
|
155
|
+
const refreshed = {
|
|
156
|
+
...matched,
|
|
157
|
+
confidence: newConfidence,
|
|
158
|
+
accessCount: previousAccessCount + 1,
|
|
159
|
+
lastAccessed: new Date(),
|
|
160
|
+
};
|
|
161
|
+
return {
|
|
162
|
+
action: 'reinforce',
|
|
163
|
+
engram: refreshed,
|
|
164
|
+
salience: null,
|
|
165
|
+
noveltyResult,
|
|
166
|
+
reinforce: { previousConfidence, newConfidence, previousAccessCount },
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function createNewEngram(engines, input, salience, noveltyResult, meta) {
|
|
170
|
+
const { store, connectionEngine } = engines;
|
|
171
|
+
const isLowSalience = salience.disposition === 'discard';
|
|
172
|
+
// Confidence: caller wins, then disposition-aware prior, then fall back
|
|
173
|
+
// to eventType prior.
|
|
174
|
+
const confidence = input.confidence
|
|
175
|
+
?? (isLowSalience
|
|
176
|
+
? 0.25
|
|
177
|
+
: salience.disposition === 'staging'
|
|
178
|
+
? 0.40
|
|
179
|
+
: CONFIDENCE_PRIORS[meta.effectiveEventType] ?? 0.45);
|
|
180
|
+
const tags = [...(input.tags ?? [])];
|
|
181
|
+
if (isLowSalience && !tags.includes('low-salience'))
|
|
182
|
+
tags.push('low-salience');
|
|
183
|
+
const engram = store.createEngram({
|
|
184
|
+
agentId: input.agentId,
|
|
185
|
+
concept: input.concept,
|
|
186
|
+
content: input.content,
|
|
187
|
+
tags,
|
|
188
|
+
salience: salience.score,
|
|
189
|
+
confidence,
|
|
190
|
+
salienceFeatures: salience.features,
|
|
191
|
+
reasonCodes: salience.reasonCodes,
|
|
192
|
+
memoryClass: meta.effectiveMemoryClass,
|
|
193
|
+
memoryType: input.memoryType,
|
|
194
|
+
ttl: salience.disposition === 'staging' ? DEFAULT_AGENT_CONFIG.stagingTtlMs : undefined,
|
|
195
|
+
supersedes: meta.supersedesId,
|
|
196
|
+
});
|
|
197
|
+
if (salience.disposition === 'staging') {
|
|
198
|
+
store.updateStage(engram.id, 'staging');
|
|
199
|
+
}
|
|
200
|
+
// Supersession side-effects: mark the old engram, add causal edge.
|
|
201
|
+
if (meta.supersedesId) {
|
|
202
|
+
try {
|
|
203
|
+
const oldEngram = store.getEngram(meta.supersedesId);
|
|
204
|
+
if (oldEngram) {
|
|
205
|
+
store.supersedeEngram(meta.supersedesId, engram.id);
|
|
206
|
+
store.upsertAssociation(engram.id, oldEngram.id, 0.8, 'causal', 0.9);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch { /* supersession is best-effort */ }
|
|
210
|
+
}
|
|
211
|
+
// Connection discovery — only for non-staged writes (active or low-salience)
|
|
212
|
+
if (salience.disposition === 'active' || isLowSalience) {
|
|
213
|
+
try {
|
|
214
|
+
connectionEngine.enqueue(engram.id);
|
|
215
|
+
}
|
|
216
|
+
catch { /* non-fatal */ }
|
|
217
|
+
}
|
|
218
|
+
// Async embed — never blocks the response, failure non-fatal
|
|
219
|
+
embed(`${input.concept} ${input.content}`)
|
|
220
|
+
.then(vec => {
|
|
221
|
+
try {
|
|
222
|
+
store.updateEmbedding(engram.id, vec);
|
|
223
|
+
}
|
|
224
|
+
catch { /* engram may be evicted */ }
|
|
225
|
+
})
|
|
226
|
+
.catch(() => { });
|
|
227
|
+
const action = meta.supersedesId ? 'supersede' : 'create';
|
|
228
|
+
return {
|
|
229
|
+
action,
|
|
230
|
+
engram,
|
|
231
|
+
salience,
|
|
232
|
+
noveltyResult,
|
|
233
|
+
supersedeOf: meta.supersedesId ? { id: meta.supersedesId } : undefined,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=write-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-pipeline.js","sourceRoot":"","sources":["../../src/core/write-pipeline.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -188,7 +188,7 @@ async function main() {
|
|
|
188
188
|
});
|
|
189
189
|
// Start server
|
|
190
190
|
await app.listen({ port: PORT, host: '0.0.0.0' });
|
|
191
|
-
console.log(`AgentWorkingMemory v0.7.
|
|
191
|
+
console.log(`AgentWorkingMemory v0.7.17 listening on port ${PORT}`);
|
|
192
192
|
// Graceful shutdown
|
|
193
193
|
const shutdown = async () => {
|
|
194
194
|
clearInterval(backupTimer);
|