nlm-memory 0.13.1 → 0.14.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 +11 -0
- package/dist/core/storage/pg-code-exemplar-store.d.ts +31 -0
- package/dist/core/storage/pg-code-exemplar-store.js +183 -0
- package/dist/core/storage/pg-code-exemplar-store.js.map +1 -0
- package/dist/core/storage/pg-storage.d.ts +2 -2
- package/dist/core/storage/pg-storage.js +2 -2
- package/dist/core/storage/pg-storage.js.map +1 -1
- package/dist/ui/assets/index-CMpQkbQy.js +11 -0
- package/dist/ui/assets/{index-DCuQrzJH.css → index-DSzo1eTD.css} +1 -1
- package/dist/ui/index.html +2 -2
- package/migrations/pg/001_initial.sql +37 -0
- package/package.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/dist/core/storage/null-code-exemplar-store.d.ts +0 -21
- package/dist/core/storage/null-code-exemplar-store.js +0 -19
- package/dist/core/storage/null-code-exemplar-store.js.map +0 -1
- package/dist/ui/assets/index-CVo7KKw2.js +0 -11
package/README.md
CHANGED
|
@@ -216,6 +216,12 @@ Signals are local-only. They are stamped with a per-install ID from `~/.nlm/inst
|
|
|
216
216
|
|
|
217
217
|
The pi `quality-gate` extension (in the `pi-sandbox` repo) is a ~10-line integration that emits `nlm.signal` per gate step and again on retry exhaustion. It is the canonical example of the session-embedded transport.
|
|
218
218
|
|
|
219
|
+
### Code exemplar recall
|
|
220
|
+
|
|
221
|
+
Built on the signals lane: a code-bearing signal — one carrying a `git_sha` or `detail.code` with a `pass`/`fail`/`fix` outcome — is captured as a **code exemplar**, a concrete chunk that worked (or didn't) for a task. At implementation time an agent calls `recall_code` to pull "code that passed a gate like this," with positives ranked first and labeled negatives surfaced as anti-patterns.
|
|
222
|
+
|
|
223
|
+
Off by default — enable with `NLM_CODE_EXEMPLARS_ENABLED=1`. Capture rides the existing `/api/signal` path (no separate producer wiring); retrieval is exposed on every transport: the `recall_code` MCP tool (stdio and `/mcp`), `GET /api/recall-code`, and the `nlm recall-code "<task>"` CLI. Code embeddings use CodeRankEmbed (`hf.co/awhiteside/CodeRankEmbed-Q8_0-GGUF` via Ollama, 768-dim; override with `NLM_CODE_EMBED_MODEL`). Works on both the SQLite and Postgres+pgvector backends.
|
|
224
|
+
|
|
219
225
|
---
|
|
220
226
|
|
|
221
227
|
## MCP Tools
|
|
@@ -231,6 +237,7 @@ The pi `quality-gate` extension (in the `pi-sandbox` repo) is a ~10-line integra
|
|
|
231
237
|
**When to call `cite_session`:** Call it when a surfaced session actually changes what you say — you referenced it explicitly, it corrected a decision, or you called `get_session` to read the full body. Do not call it for sessions you scanned and discarded. The Stop hook auto-detects citation when a session ID appears verbatim in your response; `cite_session` covers the deliberate case where the session influenced your reasoning without being quoted directly. Both paths feed the same signal loop.
|
|
232
238
|
|
|
233
239
|
| `mark_superseded` | Retroactively retire a stale session and point it at the newer one that replaces it. The editable-timeline write path — see [docs/supersedence.md](docs/supersedence.md). |
|
|
240
|
+
| `recall_code` | Semantic search over captured code exemplars — "code that passed/failed a gate like this task." Returns positives plus labeled negatives. Registered only when `NLM_CODE_EXEMPLARS_ENABLED=1`. |
|
|
234
241
|
|
|
235
242
|
---
|
|
236
243
|
|
|
@@ -255,6 +262,8 @@ Daemon binds `127.0.0.1:3940` (override with `NLM_PORT`). Selected endpoints:
|
|
|
255
262
|
| POST | `/api/citation/explicit` | Bearer/Origin | Log an explicit session citation (the route backing the `cite_session` MCP tool; payload `{id, conversation_id?, reason?}`) |
|
|
256
263
|
| POST | `/api/hook/pre-compact` | Bearer/Origin | Hook endpoint; flushes the surfaced-IDs memo |
|
|
257
264
|
| ALL | `/mcp` | Bearer required | Streamable-HTTP MCP transport for container agents |
|
|
265
|
+
| GET | `/api/recall-code` | Bearer/Origin | Semantic code-exemplar search — `?q=`, `?repo=`, `?lang=`, `?k=`, `?negatives=0`. Requires `NLM_CODE_EXEMPLARS_ENABLED=1`. |
|
|
266
|
+
| POST | `/api/exemplar` | Bearer/Origin | Direct code-exemplar push (capture also happens automatically from code-bearing signals). Requires the flag. |
|
|
258
267
|
|
|
259
268
|
`/api/*` is gated by three layers: 127.0.0.1 Host check (defeats DNS rebinding), Origin check when the browser sends one (defeats cross-origin drive-by), Bearer fallback when Origin is absent (server-to-server clients).
|
|
260
269
|
|
|
@@ -337,6 +346,8 @@ recall: prompt / query
|
|
|
337
346
|
| `NLM_CLASSIFIER` | `ollama` | `ollama` (local, default), `deepseek`, `openai`, `anthropic`, `openrouter`, or `openai-compatible` |
|
|
338
347
|
| `NLM_CLASSIFIER_MODEL` | `qwen3.5:4b` | Model id for the chosen provider. `qwen3.5:4b` (Q4_K_M, 4.7B) is the recommended local default — scored 74.4% decision-precision vs 58.7% for `qwen3:4b-instruct-2507-q4_K_M` (task #320, 2026-06-12). |
|
|
339
348
|
| `NLM_OLLAMA_URL` | `http://localhost:11434` | Override Ollama endpoint |
|
|
349
|
+
| `NLM_CODE_EXEMPLARS_ENABLED` | — | Set to `1` to enable the code-exemplar lane (capture from code-bearing signals + the `recall_code` tool/routes). Off by default. |
|
|
350
|
+
| `NLM_CODE_EMBED_MODEL` | `hf.co/awhiteside/CodeRankEmbed-Q8_0-GGUF` | Ollama model for code-exemplar embeddings (768-dim). Only used when the exemplar lane is enabled. |
|
|
340
351
|
| `NLM_ADAPTERS` | all | Comma-separated allowlist of adapters to enable |
|
|
341
352
|
| `DEEPSEEK_API_KEY` | — | Required only when classifier=deepseek |
|
|
342
353
|
| `NLM_DISABLE_UPDATE_CHECK` | — | Set to `1` to disable the daily npm-registry update check |
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PgCodeExemplarStore — CodeExemplarStore over pg.Pool + pgvector.
|
|
3
|
+
*
|
|
4
|
+
* Behavioural mirror of SqliteCodeExemplarStore: insert is idempotent on the
|
|
5
|
+
* deterministic id (sha256(install_scope|repo|code_hash|outcome)[:16]), the
|
|
6
|
+
* vec lane is managed via upsertEmbedding, and search over-fetches by L2
|
|
7
|
+
* distance then reranks in JS (negatives + reverted rows downranked).
|
|
8
|
+
*
|
|
9
|
+
* Embeddings live in code_exemplar_embeddings with ON DELETE CASCADE, so the
|
|
10
|
+
* prune/cap deletes here don't need separate vec bookkeeping (unlike the
|
|
11
|
+
* SQLite store, which deletes from code_exemplars_vec explicitly).
|
|
12
|
+
*/
|
|
13
|
+
import type { Pool } from "pg";
|
|
14
|
+
import type { CodeExemplarSearchFilter, CodeExemplarStore } from "../../ports/code-exemplar-store.js";
|
|
15
|
+
import type { CodeExemplar, CodeExemplarHit, CodeExemplarInput } from "../../shared/types.js";
|
|
16
|
+
export declare class PgCodeExemplarStore implements CodeExemplarStore {
|
|
17
|
+
private readonly pool;
|
|
18
|
+
constructor(pool: Pool);
|
|
19
|
+
insert(input: CodeExemplarInput): Promise<{
|
|
20
|
+
id: string;
|
|
21
|
+
skipped: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
insertMany(inputs: ReadonlyArray<CodeExemplarInput>): Promise<number>;
|
|
24
|
+
upsertEmbedding(exemplarId: string, vector: Float32Array): Promise<void>;
|
|
25
|
+
searchByVector(queryVector: Float32Array, filter: CodeExemplarSearchFilter): Promise<ReadonlyArray<CodeExemplarHit>>;
|
|
26
|
+
getById(id: string): Promise<CodeExemplar | null>;
|
|
27
|
+
applyBucketCap(installScope: string, maxPerBucket: number): Promise<number>;
|
|
28
|
+
pruneReverted(installScope: string): Promise<number>;
|
|
29
|
+
pruneOlderThan(olderThanTs: string): Promise<number>;
|
|
30
|
+
private rowToExemplar;
|
|
31
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PgCodeExemplarStore — CodeExemplarStore over pg.Pool + pgvector.
|
|
3
|
+
*
|
|
4
|
+
* Behavioural mirror of SqliteCodeExemplarStore: insert is idempotent on the
|
|
5
|
+
* deterministic id (sha256(install_scope|repo|code_hash|outcome)[:16]), the
|
|
6
|
+
* vec lane is managed via upsertEmbedding, and search over-fetches by L2
|
|
7
|
+
* distance then reranks in JS (negatives + reverted rows downranked).
|
|
8
|
+
*
|
|
9
|
+
* Embeddings live in code_exemplar_embeddings with ON DELETE CASCADE, so the
|
|
10
|
+
* prune/cap deletes here don't need separate vec bookkeeping (unlike the
|
|
11
|
+
* SQLite store, which deletes from code_exemplars_vec explicitly).
|
|
12
|
+
*/
|
|
13
|
+
import { exemplarId } from "./sqlite-code-exemplar-store.js";
|
|
14
|
+
const VEC_DIM = 768;
|
|
15
|
+
const COLUMNS = "id, install_scope, signal_id, session_id, repo, model, lang, " +
|
|
16
|
+
"task_context, code, code_hash, outcome, git_sha, survived, ts, created_at";
|
|
17
|
+
function insertParams(input) {
|
|
18
|
+
const id = exemplarId({
|
|
19
|
+
installScope: input.installScope,
|
|
20
|
+
repo: input.repo,
|
|
21
|
+
codeHash: input.codeHash,
|
|
22
|
+
outcome: input.outcome,
|
|
23
|
+
});
|
|
24
|
+
return [
|
|
25
|
+
id,
|
|
26
|
+
input.installScope,
|
|
27
|
+
input.signalId,
|
|
28
|
+
input.sessionId,
|
|
29
|
+
input.repo,
|
|
30
|
+
input.model,
|
|
31
|
+
input.lang,
|
|
32
|
+
input.taskContext,
|
|
33
|
+
input.code,
|
|
34
|
+
input.codeHash,
|
|
35
|
+
input.outcome,
|
|
36
|
+
input.gitSha,
|
|
37
|
+
input.survived,
|
|
38
|
+
input.ts,
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
const INSERT_SQL = `
|
|
42
|
+
INSERT INTO code_exemplars
|
|
43
|
+
(id, install_scope, signal_id, session_id, repo, model, lang,
|
|
44
|
+
task_context, code, code_hash, outcome, git_sha, survived, ts)
|
|
45
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
|
|
46
|
+
ON CONFLICT (id) DO NOTHING
|
|
47
|
+
`;
|
|
48
|
+
export class PgCodeExemplarStore {
|
|
49
|
+
pool;
|
|
50
|
+
constructor(pool) {
|
|
51
|
+
this.pool = pool;
|
|
52
|
+
}
|
|
53
|
+
async insert(input) {
|
|
54
|
+
const params = insertParams(input);
|
|
55
|
+
const res = await this.pool.query(INSERT_SQL, params);
|
|
56
|
+
return { id: params[0], skipped: res.rowCount === 0 };
|
|
57
|
+
}
|
|
58
|
+
async insertMany(inputs) {
|
|
59
|
+
if (inputs.length === 0)
|
|
60
|
+
return 0;
|
|
61
|
+
const client = await this.pool.connect();
|
|
62
|
+
let inserted = 0;
|
|
63
|
+
try {
|
|
64
|
+
await client.query("BEGIN");
|
|
65
|
+
for (const input of inputs) {
|
|
66
|
+
const res = await client.query(INSERT_SQL, insertParams(input));
|
|
67
|
+
if (res.rowCount && res.rowCount > 0)
|
|
68
|
+
inserted++;
|
|
69
|
+
}
|
|
70
|
+
await client.query("COMMIT");
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
await client.query("ROLLBACK");
|
|
74
|
+
throw err;
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
client.release();
|
|
78
|
+
}
|
|
79
|
+
return inserted;
|
|
80
|
+
}
|
|
81
|
+
async upsertEmbedding(exemplarId, vector) {
|
|
82
|
+
if (vector.length !== VEC_DIM) {
|
|
83
|
+
throw new Error(`code exemplar embeddings must be ${VEC_DIM}-dim (got ${vector.length})`);
|
|
84
|
+
}
|
|
85
|
+
const vecStr = `[${Array.from(vector).join(",")}]`;
|
|
86
|
+
await this.pool.query(`INSERT INTO code_exemplar_embeddings (exemplar_id, embedding)
|
|
87
|
+
VALUES ($1, $2::vector)
|
|
88
|
+
ON CONFLICT (exemplar_id) DO UPDATE SET embedding = EXCLUDED.embedding`, [exemplarId, vecStr]);
|
|
89
|
+
}
|
|
90
|
+
async searchByVector(queryVector, filter) {
|
|
91
|
+
const k = Math.max(1, Math.min(50, filter.k ?? 5));
|
|
92
|
+
const includeNegatives = filter.includeNegatives ?? true;
|
|
93
|
+
const overFetch = k * 4;
|
|
94
|
+
const vecStr = `[${Array.from(queryVector).join(",")}]`;
|
|
95
|
+
// pgvector <-> is L2 distance; OllamaCodeEmbedder L2-normalises vectors,
|
|
96
|
+
// so this orders identically to cosine and matches the SQLite vec0 lane.
|
|
97
|
+
const res = await this.pool.query(`SELECT ${COLUMNS.split(", ").map((c) => `ce.${c}`).join(", ")},
|
|
98
|
+
e.embedding <-> $1::vector AS distance
|
|
99
|
+
FROM code_exemplar_embeddings e
|
|
100
|
+
JOIN code_exemplars ce ON ce.id = e.exemplar_id
|
|
101
|
+
WHERE ce.install_scope = $2
|
|
102
|
+
ORDER BY e.embedding <-> $1::vector
|
|
103
|
+
LIMIT $3`, [vecStr, filter.installScope, overFetch]);
|
|
104
|
+
let hits = res.rows.map((r) => ({
|
|
105
|
+
id: r.id,
|
|
106
|
+
code: r.code,
|
|
107
|
+
taskContext: r.task_context,
|
|
108
|
+
outcome: r.outcome,
|
|
109
|
+
repo: r.repo,
|
|
110
|
+
model: r.model,
|
|
111
|
+
lang: r.lang,
|
|
112
|
+
survived: r.survived,
|
|
113
|
+
gitSha: r.git_sha,
|
|
114
|
+
distance: Number(r.distance),
|
|
115
|
+
}));
|
|
116
|
+
if (filter.repo !== undefined)
|
|
117
|
+
hits = hits.filter((h) => h.repo === filter.repo);
|
|
118
|
+
if (filter.lang !== undefined)
|
|
119
|
+
hits = hits.filter((h) => h.lang === filter.lang);
|
|
120
|
+
if (filter.model !== undefined)
|
|
121
|
+
hits = hits.filter((h) => h.model === filter.model);
|
|
122
|
+
if (!includeNegatives)
|
|
123
|
+
hits = hits.filter((h) => h.outcome === "pass" || h.outcome === "fix");
|
|
124
|
+
// Rerank: survived=0 is downranked; negatives sorted after positives at same distance.
|
|
125
|
+
hits.sort((a, b) => {
|
|
126
|
+
const aIsNeg = a.outcome === "fail" || a.outcome === "exhausted" ? 1 : 0;
|
|
127
|
+
const bIsNeg = b.outcome === "fail" || b.outcome === "exhausted" ? 1 : 0;
|
|
128
|
+
const aSurvPenalty = a.survived === 0 ? 0.05 : 0;
|
|
129
|
+
const bSurvPenalty = b.survived === 0 ? 0.05 : 0;
|
|
130
|
+
return (a.distance + aSurvPenalty + aIsNeg * 0.1) - (b.distance + bSurvPenalty + bIsNeg * 0.1);
|
|
131
|
+
});
|
|
132
|
+
return hits.slice(0, k);
|
|
133
|
+
}
|
|
134
|
+
async getById(id) {
|
|
135
|
+
const res = await this.pool.query(`SELECT ${COLUMNS} FROM code_exemplars WHERE id = $1`, [id]);
|
|
136
|
+
const row = res.rows[0];
|
|
137
|
+
return row ? this.rowToExemplar(row) : null;
|
|
138
|
+
}
|
|
139
|
+
async applyBucketCap(installScope, maxPerBucket) {
|
|
140
|
+
// Window-rank within each (repo, lang, outcome-class) bucket newest-first,
|
|
141
|
+
// delete everything past the cap. Cascade clears the embeddings.
|
|
142
|
+
const res = await this.pool.query(`WITH ranked AS (
|
|
143
|
+
SELECT id, ROW_NUMBER() OVER (
|
|
144
|
+
PARTITION BY repo, lang,
|
|
145
|
+
CASE WHEN outcome IN ('pass', 'fix') THEN 'positive' ELSE 'negative' END
|
|
146
|
+
ORDER BY ts DESC
|
|
147
|
+
) AS rn
|
|
148
|
+
FROM code_exemplars
|
|
149
|
+
WHERE install_scope = $1
|
|
150
|
+
)
|
|
151
|
+
DELETE FROM code_exemplars
|
|
152
|
+
WHERE id IN (SELECT id FROM ranked WHERE rn > $2)`, [installScope, maxPerBucket]);
|
|
153
|
+
return res.rowCount ?? 0;
|
|
154
|
+
}
|
|
155
|
+
async pruneReverted(installScope) {
|
|
156
|
+
const res = await this.pool.query("DELETE FROM code_exemplars WHERE install_scope = $1 AND survived = 0", [installScope]);
|
|
157
|
+
return res.rowCount ?? 0;
|
|
158
|
+
}
|
|
159
|
+
async pruneOlderThan(olderThanTs) {
|
|
160
|
+
const res = await this.pool.query("DELETE FROM code_exemplars WHERE ts < $1", [olderThanTs]);
|
|
161
|
+
return res.rowCount ?? 0;
|
|
162
|
+
}
|
|
163
|
+
rowToExemplar(row) {
|
|
164
|
+
return {
|
|
165
|
+
id: row.id,
|
|
166
|
+
installScope: row.install_scope,
|
|
167
|
+
signalId: row.signal_id,
|
|
168
|
+
sessionId: row.session_id,
|
|
169
|
+
repo: row.repo,
|
|
170
|
+
model: row.model,
|
|
171
|
+
lang: row.lang,
|
|
172
|
+
taskContext: row.task_context,
|
|
173
|
+
code: row.code,
|
|
174
|
+
codeHash: row.code_hash,
|
|
175
|
+
outcome: row.outcome,
|
|
176
|
+
gitSha: row.git_sha,
|
|
177
|
+
survived: row.survived,
|
|
178
|
+
ts: row.ts,
|
|
179
|
+
createdAt: row.created_at,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=pg-code-exemplar-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-code-exemplar-store.js","sourceRoot":"","sources":["../../../src/core/storage/pg-code-exemplar-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@ import type { Storage, StorageContext } from "../../ports/storage.js";
|
|
|
14
14
|
import { PgFactStore } from "./pg-fact-store.js";
|
|
15
15
|
import { PgSessionStore } from "./pg-session-store.js";
|
|
16
16
|
import { PgSignalStore } from "./pg-signal-store.js";
|
|
17
|
-
import {
|
|
17
|
+
import { PgCodeExemplarStore } from "./pg-code-exemplar-store.js";
|
|
18
18
|
import { PgSourceRegistry } from "../sources/source-registry.js";
|
|
19
19
|
import { PgProviderRegistry } from "../providers/provider-registry.js";
|
|
20
20
|
export interface PgStorageOptions {
|
|
@@ -25,7 +25,7 @@ export declare class PgStorage implements Storage {
|
|
|
25
25
|
readonly facts: PgFactStore;
|
|
26
26
|
readonly sessions: PgSessionStore;
|
|
27
27
|
readonly signals: PgSignalStore;
|
|
28
|
-
readonly exemplars:
|
|
28
|
+
readonly exemplars: PgCodeExemplarStore;
|
|
29
29
|
readonly sources: PgSourceRegistry;
|
|
30
30
|
readonly providers: PgProviderRegistry;
|
|
31
31
|
private readonly _pool;
|
|
@@ -15,7 +15,7 @@ import { join } from "node:path";
|
|
|
15
15
|
import { PgFactStore } from "./pg-fact-store.js";
|
|
16
16
|
import { PgSessionStore } from "./pg-session-store.js";
|
|
17
17
|
import { PgSignalStore } from "./pg-signal-store.js";
|
|
18
|
-
import {
|
|
18
|
+
import { PgCodeExemplarStore } from "./pg-code-exemplar-store.js";
|
|
19
19
|
import { PgTxBoundFactStore, PgTxBoundSessionStore } from "./pg-tx-context.js";
|
|
20
20
|
import { PgSourceRegistry } from "../sources/source-registry.js";
|
|
21
21
|
import { PgProviderRegistry } from "../providers/provider-registry.js";
|
|
@@ -36,7 +36,7 @@ export class PgStorage {
|
|
|
36
36
|
this.facts = new PgFactStore(pool);
|
|
37
37
|
this.sessions = new PgSessionStore(pool);
|
|
38
38
|
this.signals = new PgSignalStore(pool);
|
|
39
|
-
this.exemplars = new
|
|
39
|
+
this.exemplars = new PgCodeExemplarStore(pool);
|
|
40
40
|
this.sources = new PgSourceRegistry(pool);
|
|
41
41
|
this.providers = new PgProviderRegistry(pool);
|
|
42
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pg-storage.js","sourceRoot":"","sources":["../../../src/core/storage/pg-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"pg-storage.js","sourceRoot":"","sources":["../../../src/core/storage/pg-storage.ts"],"names":[],"mappings":"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"}
|