agent-working-memory 0.16.1 → 0.18.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 +321 -318
- package/dist/adapters/common.d.ts +34 -0
- package/dist/adapters/common.d.ts.map +1 -1
- package/dist/adapters/common.js +528 -444
- package/dist/adapters/common.js.map +1 -1
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +19 -0
- package/dist/api/routes.js.map +1 -1
- package/dist/cli/migrate.d.ts.map +1 -1
- package/dist/cli/migrate.js +31 -29
- package/dist/cli/migrate.js.map +1 -1
- package/dist/core/asked-value.d.ts +37 -0
- package/dist/core/asked-value.d.ts.map +1 -0
- package/dist/core/asked-value.js +77 -0
- package/dist/core/asked-value.js.map +1 -0
- package/dist/core/conflicts.d.ts +89 -0
- package/dist/core/conflicts.d.ts.map +1 -0
- package/dist/core/conflicts.js +267 -0
- package/dist/core/conflicts.js.map +1 -0
- package/dist/core/embeddings.d.ts +14 -2
- package/dist/core/embeddings.d.ts.map +1 -1
- package/dist/core/embeddings.js +32 -10
- package/dist/core/embeddings.js.map +1 -1
- package/dist/core/format-recall.d.ts +21 -1
- package/dist/core/format-recall.d.ts.map +1 -1
- package/dist/core/format-recall.js +60 -5
- package/dist/core/format-recall.js.map +1 -1
- package/dist/core/ml-worker.d.ts +24 -1
- package/dist/core/ml-worker.d.ts.map +1 -1
- package/dist/core/ml-worker.js +165 -4
- package/dist/core/ml-worker.js.map +1 -1
- package/dist/core/model-daemon-client.d.ts +77 -0
- package/dist/core/model-daemon-client.d.ts.map +1 -0
- package/dist/core/model-daemon-client.js +383 -0
- package/dist/core/model-daemon-client.js.map +1 -0
- package/dist/core/model-daemon-server.d.ts +71 -0
- package/dist/core/model-daemon-server.d.ts.map +1 -0
- package/dist/core/model-daemon-server.js +363 -0
- package/dist/core/model-daemon-server.js.map +1 -0
- package/dist/core/model-daemon.d.ts +137 -0
- package/dist/core/model-daemon.d.ts.map +1 -0
- package/dist/core/model-daemon.js +231 -0
- package/dist/core/model-daemon.js.map +1 -0
- package/dist/core/query-expander.d.ts +5 -0
- package/dist/core/query-expander.d.ts.map +1 -1
- package/dist/core/query-expander.js +3 -2
- package/dist/core/query-expander.js.map +1 -1
- package/dist/core/recall-config.d.ts +1 -1
- package/dist/core/recall-config.d.ts.map +1 -1
- package/dist/core/recall-config.js +5 -0
- package/dist/core/recall-config.js.map +1 -1
- package/dist/core/rerank-window.d.ts +7 -2
- package/dist/core/rerank-window.d.ts.map +1 -1
- package/dist/core/rerank-window.js +9 -4
- package/dist/core/rerank-window.js.map +1 -1
- package/dist/core/rerank2.d.ts +52 -2
- package/dist/core/rerank2.d.ts.map +1 -1
- package/dist/core/rerank2.js +60 -3
- package/dist/core/rerank2.js.map +1 -1
- package/dist/core/reranker.d.ts +19 -0
- package/dist/core/reranker.d.ts.map +1 -1
- package/dist/core/reranker.js +76 -12
- package/dist/core/reranker.js.map +1 -1
- package/dist/core/salience.d.ts +2 -0
- package/dist/core/salience.d.ts.map +1 -1
- package/dist/core/salience.js +45 -18
- package/dist/core/salience.js.map +1 -1
- package/dist/core/trust.d.ts +32 -0
- package/dist/core/trust.d.ts.map +1 -0
- package/dist/core/trust.js +66 -0
- package/dist/core/trust.js.map +1 -0
- package/dist/core/validity.d.ts +21 -0
- package/dist/core/validity.d.ts.map +1 -0
- package/dist/core/validity.js +41 -0
- package/dist/core/validity.js.map +1 -0
- package/dist/core/whoami.d.ts +3 -0
- package/dist/core/whoami.d.ts.map +1 -1
- package/dist/core/whoami.js +14 -0
- package/dist/core/whoami.js.map +1 -1
- package/dist/core/write-pipeline.d.ts +48 -0
- package/dist/core/write-pipeline.d.ts.map +1 -1
- package/dist/core/write-pipeline.js +104 -4
- package/dist/core/write-pipeline.js.map +1 -1
- package/dist/engine/activation.d.ts.map +1 -1
- package/dist/engine/activation.js +27 -4
- package/dist/engine/activation.js.map +1 -1
- package/dist/engine/consolidation.d.ts.map +1 -1
- package/dist/engine/consolidation.js +67 -5
- package/dist/engine/consolidation.js.map +1 -1
- package/dist/hooks/prime-query.d.ts +57 -0
- package/dist/hooks/prime-query.d.ts.map +1 -0
- package/dist/hooks/prime-query.js +388 -0
- package/dist/hooks/prime-query.js.map +1 -0
- package/dist/hooks/prime.d.ts +8 -0
- package/dist/hooks/prime.d.ts.map +1 -1
- package/dist/hooks/prime.js +21 -2
- package/dist/hooks/prime.js.map +1 -1
- package/dist/hooks/sidecar.d.ts +7 -0
- package/dist/hooks/sidecar.d.ts.map +1 -1
- package/dist/hooks/sidecar.js +10 -2
- package/dist/hooks/sidecar.js.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +148 -103
- package/dist/mcp.js.map +1 -1
- package/dist/model-daemon.d.ts +8 -0
- package/dist/model-daemon.d.ts.map +1 -0
- package/dist/model-daemon.js +45 -0
- package/dist/model-daemon.js.map +1 -0
- package/dist/storage/factory.d.ts.map +1 -1
- package/dist/storage/factory.js +5 -0
- package/dist/storage/factory.js.map +1 -1
- package/dist/storage/pglite-schema.d.ts.map +1 -1
- package/dist/storage/pglite-schema.js +176 -170
- package/dist/storage/pglite-schema.js.map +1 -1
- package/dist/storage/pglite.d.ts +5 -0
- package/dist/storage/pglite.d.ts.map +1 -1
- package/dist/storage/pglite.js +165 -153
- package/dist/storage/pglite.js.map +1 -1
- package/dist/storage/postgres.d.ts +5 -0
- package/dist/storage/postgres.d.ts.map +1 -1
- package/dist/storage/postgres.js +165 -153
- package/dist/storage/postgres.js.map +1 -1
- package/dist/storage/sqlite.d.ts +22 -0
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +400 -363
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/types/engram.d.ts +33 -0
- package/dist/types/engram.d.ts.map +1 -1
- package/dist/types/engram.js.map +1 -1
- package/package.json +106 -106
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/README.md +1 -1
- package/plugin/bin/awm-mcp-launcher.cjs +2 -2
- package/plugin/skills/awm-memory/SKILL.md +16 -5
- package/src/adapters/common.ts +881 -800
- package/src/api/routes.ts +20 -0
- package/src/cli/migrate.ts +309 -307
- package/src/core/asked-value.ts +74 -0
- package/src/core/conflicts.ts +280 -0
- package/src/core/embeddings.ts +35 -10
- package/src/core/format-recall.ts +83 -25
- package/src/core/ml-worker.ts +458 -281
- package/src/core/model-daemon-client.ts +374 -0
- package/src/core/model-daemon-server.ts +344 -0
- package/src/core/model-daemon.ts +243 -0
- package/src/core/query-expander.ts +127 -126
- package/src/core/recall-config.ts +5 -0
- package/src/core/rerank-window.ts +164 -159
- package/src/core/rerank2.ts +143 -82
- package/src/core/reranker.ts +78 -11
- package/src/core/salience.ts +45 -18
- package/src/core/trust.ts +65 -0
- package/src/core/validity.ts +47 -0
- package/src/core/whoami.ts +136 -120
- package/src/core/write-pipeline.ts +143 -4
- package/src/engine/activation.ts +27 -4
- package/src/engine/consolidation.ts +950 -887
- package/src/hooks/prime-query.ts +375 -0
- package/src/hooks/prime.ts +25 -2
- package/src/hooks/sidecar.ts +13 -3
- package/src/index.ts +255 -248
- package/src/mcp.ts +1521 -1475
- package/src/model-daemon.ts +48 -0
- package/src/storage/factory.ts +25 -19
- package/src/storage/pglite-schema.ts +199 -193
- package/src/storage/pglite.ts +1513 -1498
- package/src/storage/postgres.ts +1613 -1598
- package/src/storage/sqlite.ts +2056 -2019
- package/src/types/engram.ts +30 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt-to-query shaping for the prime hook (2026-10-16).
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS
|
|
5
|
+
* ---------------
|
|
6
|
+
* /hooks/prime used to recall against the WHOLE prompt. A prompt that carries a
|
|
7
|
+
* pasted log, a block of code or a background-task report is mostly paste, and
|
|
8
|
+
* every retrieval signal then reads the paste instead of the question: BM25 scores
|
|
9
|
+
* the paste's terms, the embedding becomes the paste's vector, and the cross-encoder
|
|
10
|
+
* sees mostly paste even after its 128-token query cap (reranker.ts). Measured on
|
|
11
|
+
* 100 real-store fixture queries wrapped in ~600 tokens of paste, success@1 was 49%
|
|
12
|
+
* with the question before the paste and 26% with it after, against 93% for the
|
|
13
|
+
* bare query, and each recall took 5-8 s.
|
|
14
|
+
*
|
|
15
|
+
* WHAT IT DOES
|
|
16
|
+
* ------------
|
|
17
|
+
* A prompt at or under the budget is returned unchanged, which is most typed
|
|
18
|
+
* prompts. A longer one is cut down in four steps:
|
|
19
|
+
*
|
|
20
|
+
* 1. Envelope lines that only carry an id, a path or a status
|
|
21
|
+
* (`<task-id>b43drliev</task-id>`) are dropped, and lowercase tags are stripped
|
|
22
|
+
* to their text. Background-task notifications arrive this way; their harness
|
|
23
|
+
* note, token counts and attribution trailers are dropped as boilerplate.
|
|
24
|
+
* 2. Lines that read as machine output are dropped: fenced code, timestamped or
|
|
25
|
+
* levelled log lines, stack frames, code statements, SQL, JSON, YAML, CSV,
|
|
26
|
+
* tables, diffs, key=value runs and symbol-dense lines. Up to two of them that
|
|
27
|
+
* name an error are kept, in a reserved share of the budget, because
|
|
28
|
+
* "fix this: <trace>" is answered by the error, not by the prose around it.
|
|
29
|
+
* 3. The likeliest question is moved to the front (see shapePrimeQuery: the
|
|
30
|
+
* cross-encoder reads the start of the query).
|
|
31
|
+
* 4. If the prose is still over budget, the query is its head and its tail.
|
|
32
|
+
*
|
|
33
|
+
* When the prose is only a pointer ("explain this:"), the pointer leads and the
|
|
34
|
+
* paste's own head and tail fill the budget, because the paste is the subject.
|
|
35
|
+
*
|
|
36
|
+
* The shaped text is used for RECALL ONLY. Nothing here changes what the agent sees.
|
|
37
|
+
* Explicit memory_recall queries are not shaped: an agent's query is written to be
|
|
38
|
+
* a query.
|
|
39
|
+
*/
|
|
40
|
+
/** Characters of query the prime hook recalls with. 0 disables shaping. */
|
|
41
|
+
export declare const PRIME_QUERY_CHARS: number;
|
|
42
|
+
/** True when a line reads as machine output rather than something a person wrote. */
|
|
43
|
+
export declare function isMachineLine(line: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* The query the prime hook recalls with. Pure and synchronous; never throws on a
|
|
46
|
+
* string. `budget` defaults to AWM_PRIME_QUERY_CHARS (400); 0 returns the prompt.
|
|
47
|
+
* Returns '' for a prompt that is nothing but envelope; the caller then skips recall.
|
|
48
|
+
*
|
|
49
|
+
* ORDER MATTERS. The cross-encoder reads the start of the query: the same question and
|
|
50
|
+
* the same memory scored 0.996 with the question in front of 300 chars of notes and
|
|
51
|
+
* 0.007 behind them, and every other memory scored ~0 too, so ranking collapsed. The
|
|
52
|
+
* query therefore leads with the likeliest question: a task's <summary>, then lines
|
|
53
|
+
* that ask something, then the end block of the prompt that reads as a typed request
|
|
54
|
+
* (steps 1-3 below).
|
|
55
|
+
*/
|
|
56
|
+
export declare function shapePrimeQuery(prompt: string, budget?: number): string;
|
|
57
|
+
//# sourceMappingURL=prime-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prime-query.d.ts","sourceRoot":"","sources":["../../src/hooks/prime-query.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,QAK1B,CAAC;AAiGL,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA0BnD;AAqED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAA0B,GAAG,MAAM,CAyH1F"}
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
// Copyright 2026 Robert Winter / Complete Ideas
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Prompt-to-query shaping for the prime hook (2026-10-16).
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS EXISTS
|
|
7
|
+
* ---------------
|
|
8
|
+
* /hooks/prime used to recall against the WHOLE prompt. A prompt that carries a
|
|
9
|
+
* pasted log, a block of code or a background-task report is mostly paste, and
|
|
10
|
+
* every retrieval signal then reads the paste instead of the question: BM25 scores
|
|
11
|
+
* the paste's terms, the embedding becomes the paste's vector, and the cross-encoder
|
|
12
|
+
* sees mostly paste even after its 128-token query cap (reranker.ts). Measured on
|
|
13
|
+
* 100 real-store fixture queries wrapped in ~600 tokens of paste, success@1 was 49%
|
|
14
|
+
* with the question before the paste and 26% with it after, against 93% for the
|
|
15
|
+
* bare query, and each recall took 5-8 s.
|
|
16
|
+
*
|
|
17
|
+
* WHAT IT DOES
|
|
18
|
+
* ------------
|
|
19
|
+
* A prompt at or under the budget is returned unchanged, which is most typed
|
|
20
|
+
* prompts. A longer one is cut down in four steps:
|
|
21
|
+
*
|
|
22
|
+
* 1. Envelope lines that only carry an id, a path or a status
|
|
23
|
+
* (`<task-id>b43drliev</task-id>`) are dropped, and lowercase tags are stripped
|
|
24
|
+
* to their text. Background-task notifications arrive this way; their harness
|
|
25
|
+
* note, token counts and attribution trailers are dropped as boilerplate.
|
|
26
|
+
* 2. Lines that read as machine output are dropped: fenced code, timestamped or
|
|
27
|
+
* levelled log lines, stack frames, code statements, SQL, JSON, YAML, CSV,
|
|
28
|
+
* tables, diffs, key=value runs and symbol-dense lines. Up to two of them that
|
|
29
|
+
* name an error are kept, in a reserved share of the budget, because
|
|
30
|
+
* "fix this: <trace>" is answered by the error, not by the prose around it.
|
|
31
|
+
* 3. The likeliest question is moved to the front (see shapePrimeQuery: the
|
|
32
|
+
* cross-encoder reads the start of the query).
|
|
33
|
+
* 4. If the prose is still over budget, the query is its head and its tail.
|
|
34
|
+
*
|
|
35
|
+
* When the prose is only a pointer ("explain this:"), the pointer leads and the
|
|
36
|
+
* paste's own head and tail fill the budget, because the paste is the subject.
|
|
37
|
+
*
|
|
38
|
+
* The shaped text is used for RECALL ONLY. Nothing here changes what the agent sees.
|
|
39
|
+
* Explicit memory_recall queries are not shaped: an agent's query is written to be
|
|
40
|
+
* a query.
|
|
41
|
+
*/
|
|
42
|
+
/** Characters of query the prime hook recalls with. 0 disables shaping. */
|
|
43
|
+
export const PRIME_QUERY_CHARS = (() => {
|
|
44
|
+
// An explicit 0 disables; anything else invalid falls back to the default (see
|
|
45
|
+
// reranker.ts shapeCap): a typo must not quietly restore whole-prompt recall.
|
|
46
|
+
const v = Number(process.env.AWM_PRIME_QUERY_CHARS?.trim() || NaN);
|
|
47
|
+
return Number.isInteger(v) && v >= 0 ? v : 400;
|
|
48
|
+
})();
|
|
49
|
+
/** Error-bearing machine lines kept, and the share of the budget they may take. */
|
|
50
|
+
const MAX_SALIENT = 2;
|
|
51
|
+
const SALIENT_SHARE = 0.3;
|
|
52
|
+
/** Lines longer than this are classified on their first CLASSIFY_LEN chars. */
|
|
53
|
+
const CLASSIFY_LEN = 400;
|
|
54
|
+
// Seconds are required: "2026-10-15 10:30 call with the client" is a person's note.
|
|
55
|
+
const TIMESTAMP = /^\[?\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}|^\[?\d{2}:\d{2}:\d{2}[.,\]\s]/;
|
|
56
|
+
const LOG_LEVEL = /^\[?(TRACE|DEBUG|INFO|NOTICE|WARN|WARNING|ERROR|ERR|FATAL|CRITICAL)\]?[\s:|-]/;
|
|
57
|
+
// A frame names a source location (a path or file with :line), so "at 10:30 tomorrow"
|
|
58
|
+
// is not one. PowerShell error records are frames too.
|
|
59
|
+
// The error header a trace starts or ends with (TypeError: …, requests.exceptions.
|
|
60
|
+
// ConnectionError: …) belongs to the trace; it is kept as an error line, below.
|
|
61
|
+
const STACK_FRAME = /^(at\s+(async\s+)?(\S+\s+){0,4}\(?\S*[/\\.]\S*:\d+(:\d+)?\)?$|File ".*", line \d+|Traceback \(most recent call last\):|During handling of the above exception|The above exception was the direct cause|[\w.]*(Error|Exception):\s|#\d+\s+0x[0-9a-f]+|\.\.\. \d+ more|At line:\d+ char:\d+|\+ (CategoryInfo|FullyQualifiedErrorId)\s*:)/;
|
|
62
|
+
// Keyword AND code syntax: "for the record (see above)", "let me know if x = y" and
|
|
63
|
+
// "import members from the 2025 sheet" are prose; the code forms are not.
|
|
64
|
+
const CODE_KEYWORD = new RegExp([
|
|
65
|
+
String.raw `^(const|let|var)\s+([\w$]+|\{[^}]*\}|\[[^\]]*\])\s*(:\s*[\w<>[\]|. ]+)?=(?!=)`,
|
|
66
|
+
String.raw `^(async\s+)?function\b\s*\*?\s*[\w$]*\s*\(`,
|
|
67
|
+
String.raw `^import\s+(['"]|.*\s+from\s+['"])`,
|
|
68
|
+
// "export type information to the CSV" is prose; `export type Foo =` is not.
|
|
69
|
+
String.raw `^export\s+(\{|\*|default\b|type\s+\w+\s*[=<{]|interface\b|const\b|let\b|function\b|class\b|async\b)`,
|
|
70
|
+
// One parenthesised condition and nothing after it: "for (most of) the team…" is prose.
|
|
71
|
+
String.raw `^(if|for|while|switch|catch)\s*\([^)]*\)\s*\{?$`,
|
|
72
|
+
String.raw `^def\s+\w+\s*\(`,
|
|
73
|
+
String.raw `^class\s+\w+\s*(\(.*\)\s*:|:$|\{|(extends|implements)\b)`,
|
|
74
|
+
String.raw `^(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|WITH)\s.*\b(FROM|INTO|SET|TABLE|WHERE|AS)\b`,
|
|
75
|
+
String.raw `^(FROM|WHERE|JOIN|LEFT JOIN|INNER JOIN|GROUP BY|ORDER BY|HAVING|LIMIT|UNION)\s`,
|
|
76
|
+
String.raw `^SELECT\s+(DISTINCT\s+)?[\w.*]+(\s*,\s*[\w.*]+)*,?$`,
|
|
77
|
+
// Python-style assignment, spaced: `result = self.fetch(x)`. Unspaced `AWM_X=1 didn't
|
|
78
|
+
// help (I checked)` is a person starting a sentence with a flag.
|
|
79
|
+
String.raw `^[\w.]+(\[[^\]]*\])?\s+[-+*/]?=\s+\S.*[(\[{'"]`,
|
|
80
|
+
].join('|'));
|
|
81
|
+
// An opening brace at the end, or a closing bracket at the start. A line ENDING in '}'
|
|
82
|
+
// is often a person's template ("the template uses {name}"), so that alone is not code.
|
|
83
|
+
const CODE_END = /\{\s*$|^\s*[}\])]/;
|
|
84
|
+
// A trailing ';' is code only with code syntax beside it: "- raise the cap to $30;" is
|
|
85
|
+
// a person's list, `return service.load(id);` is not.
|
|
86
|
+
const SEMICOLON_END = /;\s*$/;
|
|
87
|
+
const CODE_SYNTAX = /\w\(|[=!<>]=|=>|\s=\s|^\s*(return|throw|break|continue)\b/;
|
|
88
|
+
// A key line, a bare bracket, or a bare array value ("beta", "alpha", 42, null). A
|
|
89
|
+
// quoted sentence on its own line is a person quoting, so a string with spaces needs
|
|
90
|
+
// the trailing comma.
|
|
91
|
+
const JSON_LINE = /^"[^"]+"\s*:|^[[{]\s*$|^[\]}],?\s*$|^("[^"\s]*",?|"[^"]*",|-?\d[\d.eE+-]*,?|true,?|false,?|null,?)$/;
|
|
92
|
+
// Compiler and tool output: lowercase `error[E0308]: …` / `warning: …` headers (a typed
|
|
93
|
+
// "Note: …" is prose), Go `panic:` / `goroutine 1 [running]:` lines, `--> src/x.rs:41:10`
|
|
94
|
+
// locations, ` |` / `41 |` source gutters, a bare path:line (nothing after it but an
|
|
95
|
+
// offset — "src/x.ts:42 throws when…" is a person), and frames whose arguments are hex
|
|
96
|
+
// addresses (Go, C).
|
|
97
|
+
const TOOL_OUTPUT = /^((error|warning)(\[[\w-]+\])?:\s|panic:\s|goroutine \d+ \[|Process finished with exit code \d+|npm (ERR!|WARN|notice)\s|-->\s*\S+:\d+|\d*\s*\|(\s|$)|[.~]?[\w.-]*[/\\][^\s:]+:\d+(:\d+)?(\s+[+(]\S*)?$)|(0x[0-9a-fA-F]{4,}.*){2}/;
|
|
98
|
+
const DIFF_HEADER = /^(diff --git |index [0-9a-f]+\.\.[0-9a-f]+|--- (a\/|\/dev\/null)|\+\+\+ (b\/|\/dev\/null)|@@ .* @@)/;
|
|
99
|
+
// One-token key, then one token or nothing (YAML, headers). "Note: fix it" is prose.
|
|
100
|
+
// A quoted value must be one token too: `- Sweep: "LOCAL ONLY. Never touch prod"` is a
|
|
101
|
+
// person's note. A bare label ("Summary:") is dropped, which costs nothing.
|
|
102
|
+
const YAML_LINE = /^(-\s+)?[\w.-]+:(\s+("[^"\s]*"|'[^'\s]*'|\S+))?\s*$/;
|
|
103
|
+
// Delimited rows: CSV with no comma-space (a person's list has them), or 2+ table pipes.
|
|
104
|
+
const CSV_LINE = /^[^\s,]+(,[^,\s]*){3,}$/;
|
|
105
|
+
const TABLE_LINE = /^\|?[^|]*(\s\|\s[^|]*){2,}\|?$|^[-+|: ]{5,}$|^\(\d+ rows?\)$/;
|
|
106
|
+
// The lookbehind keeps this linear: \b[\w.-]+ restarts at every '.' and '-' otherwise,
|
|
107
|
+
// which took 10 s on a 100 KB run of 'a.a.a.'.
|
|
108
|
+
const KEY_VALUE = /(?<![\w.-])[\w.-]+=\S+/g;
|
|
109
|
+
// Error words, plus HTTP 4xx/5xx statuses.
|
|
110
|
+
const ERROR_WORD = /\b(error|exception|fail(ed|ure)?|fatal|panic|denied|refused|cannot|can't|unable|not found|timed? ?out|undefined|traceback|segfault|abort(ed)?)\b|\b(HTTP\/\S+\s+|status\s*)[45]\d\d\b/i;
|
|
111
|
+
// Errno names (ECONNREFUSED, EPIPE) and compiler/vendor codes (TS2304, ORA-00942).
|
|
112
|
+
// Case-sensitive: with /i, E[A-Z]{3,} would match "every".
|
|
113
|
+
const ERROR_CODE = /\bE[A-Z]{3,}\b|\b[A-Z]{2,4}-?\d{3,5}\b/;
|
|
114
|
+
// A block that cannot be the typed request even though it reads as prose: a markdown
|
|
115
|
+
// heading, a line that introduces what follows ("Terraform will perform the following
|
|
116
|
+
// actions:", "Here is the log:"), a sign-off, or a signature / title line.
|
|
117
|
+
const HEADING = /^#{1,6}\s/;
|
|
118
|
+
const INTRODUCER = /:\s*$/;
|
|
119
|
+
const SIGN_OFF = /^(thanks|thank you|many thanks|cheers|regards|best( regards| wishes)?|sincerely|kind regards|let me know( what you think)?|hope this helps)\b/i;
|
|
120
|
+
const SIGNATURE = /^([A-Z][\w&.'’-]*|of|and|the|for|at|&)(\s+([A-Z][\w&.'’-]*|of|and|the|for|at|&)){0,5}$/;
|
|
121
|
+
/** Prose shorter than this many words is a pointer ("explain this:"): the paste is the subject. */
|
|
122
|
+
const POINTER_WORDS = 3;
|
|
123
|
+
const QUESTION = /\?(\s|$)/;
|
|
124
|
+
const MAX_QUESTIONS = 2;
|
|
125
|
+
const QUESTION_LEN = 150;
|
|
126
|
+
const CJK = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u;
|
|
127
|
+
const CJK_ALL = new RegExp(CJK.source, 'gu');
|
|
128
|
+
/** A whole-line tag whose value is one token: an id, a path, a status, a number. */
|
|
129
|
+
const ID_TAG_LINE = /^<([\w-]+)>\s*\S*\s*<\/\1>$/;
|
|
130
|
+
// Lowercase names only: envelope and markup tags. `Map<String, List<Integer>>` is code
|
|
131
|
+
// a person typed into a sentence.
|
|
132
|
+
const TAG = /<\/?[a-z][a-z0-9_-]*(\s[^<>]*)?>/g;
|
|
133
|
+
// A fence marker starts a line and is not closed on it: "```js", "``` js title=x" and a
|
|
134
|
+
// bare "```" are markers; "```npm run build``` fails" is inline code in prose.
|
|
135
|
+
const FENCE = /^(```|~~~)(?!.*(```|~~~))/;
|
|
136
|
+
// Claude Code's task notifications carry the same harness note on every one ("A
|
|
137
|
+
// task-notification fires each time this agent stops…") and token counts. Both say
|
|
138
|
+
// nothing about the task, and the note alone took ~150 chars of a 400-char head.
|
|
139
|
+
const BOILERPLATE_ELEMENTS = ['note', 'usage', 'subagent_tokens'];
|
|
140
|
+
// Attribution trailers an agent's report ends with: they would fill the tail.
|
|
141
|
+
const BOILERPLATE_LINE = /^(🤖\s*)?Generated with \[?Claude Code\]?|^Co-Authored-By:|^Claude-Session:|^https:\/\/claude\.ai\/code\/session_/i;
|
|
142
|
+
/** True when a line reads as machine output rather than something a person wrote. */
|
|
143
|
+
export function isMachineLine(line) {
|
|
144
|
+
// Bounded, so every check below is linear in a fixed length whatever was pasted.
|
|
145
|
+
const t = line.trim().slice(0, CLASSIFY_LEN);
|
|
146
|
+
if (!t)
|
|
147
|
+
return false;
|
|
148
|
+
if (TIMESTAMP.test(t) || LOG_LEVEL.test(t) || STACK_FRAME.test(t) || DIFF_HEADER.test(t) || TOOL_OUTPUT.test(t))
|
|
149
|
+
return true;
|
|
150
|
+
// A diff body line is a marker plus code. "- item" (a markdown bullet) and "+1" are
|
|
151
|
+
// not: the rest of the line must itself read as machine output.
|
|
152
|
+
if (/^[+-](?=\S|\s{2})/.test(t) && !/^[+-]\d/.test(t) && isMachineLine(t.slice(1)))
|
|
153
|
+
return true;
|
|
154
|
+
if (CODE_KEYWORD.test(t) || CODE_END.test(t) || JSON_LINE.test(t))
|
|
155
|
+
return true;
|
|
156
|
+
if (YAML_LINE.test(t) || CSV_LINE.test(t) || TABLE_LINE.test(t))
|
|
157
|
+
return true;
|
|
158
|
+
if (SEMICOLON_END.test(t) && CODE_SYNTAX.test(t))
|
|
159
|
+
return true;
|
|
160
|
+
// Three, and most of the line: "set AWM_RERANK2=1 and AWM_RERANK_TAGS=1" is a person
|
|
161
|
+
// typing; `host=a port=5432 user=b` is not. Pairs inside backticks are a person
|
|
162
|
+
// quoting them, so they do not count.
|
|
163
|
+
const kv = t.replace(/`[^`]*`/g, ' ').match(KEY_VALUE)?.length ?? 0;
|
|
164
|
+
if (kv >= 3 && kv / t.split(/\s+/).length >= 0.4)
|
|
165
|
+
return true;
|
|
166
|
+
if (t.length >= 8) {
|
|
167
|
+
// Identifiers like d.requires_horse or cleanup2.py are fine in prose; a line that
|
|
168
|
+
// is a quarter punctuation is not. Markdown emphasis and code ticks, path slashes,
|
|
169
|
+
// sentence punctuation and emoji are a person's, so they do not count.
|
|
170
|
+
const symbols = t.replace(/[\p{L}\p{N}\p{M}\p{Extended_Pictographic}\s_.'’,*`/\\!?-]/gu, '').length;
|
|
171
|
+
if (symbols / t.length > (t.length >= 24 ? 0.25 : 0.5))
|
|
172
|
+
return true;
|
|
173
|
+
// Minified or base64: long and almost no spaces. CJK prose has no spaces either.
|
|
174
|
+
if (t.length >= 200 && !CJK.test(t) && (t.match(/\s/g)?.length ?? 0) / t.length < 0.03)
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
const ANY_TAG = /<\/?[A-Za-z][^<>]*>/g;
|
|
180
|
+
/**
|
|
181
|
+
* Checks that need the raw line, before tags are stripped and spaces collapsed: a line
|
|
182
|
+
* that is mostly markup (HTML, XML) or laid out in columns (`kubectl get pods`, `ps`,
|
|
183
|
+
* aligned tables) is machine output, though its words would read as prose afterwards.
|
|
184
|
+
*/
|
|
185
|
+
function isMarkupOrColumns(raw) {
|
|
186
|
+
const t = raw.slice(0, CLASSIFY_LEN);
|
|
187
|
+
// Several tags, or tags that are most of the line. "What does <summary> do vs
|
|
188
|
+
// <details>?" mentions two tags; an HTML line is built of them.
|
|
189
|
+
const found = t.match(ANY_TAG) ?? [];
|
|
190
|
+
const share = found.join('').length / t.length;
|
|
191
|
+
if ((share > 0.6 || (share > 0.4 && found.length >= 3)) && !/^<(summary|result)>/.test(t))
|
|
192
|
+
return true;
|
|
193
|
+
return /\S(\s{3,}\S+){2,}/.test(t);
|
|
194
|
+
}
|
|
195
|
+
/** `i` moved off the low half of a surrogate pair, so a cut never splits an emoji. */
|
|
196
|
+
function safe(s, i) {
|
|
197
|
+
const c = s.charCodeAt(i);
|
|
198
|
+
return c >= 0xdc00 && c <= 0xdfff ? i - 1 : i;
|
|
199
|
+
}
|
|
200
|
+
/** First `n` chars, cut back to a word boundary when one is near. */
|
|
201
|
+
function head(s, n) {
|
|
202
|
+
if (s.length <= n)
|
|
203
|
+
return s;
|
|
204
|
+
const cut = s.slice(0, safe(s, n));
|
|
205
|
+
const sp = cut.lastIndexOf(' ');
|
|
206
|
+
return (sp > n * 0.6 ? cut.slice(0, sp) : cut).trimEnd();
|
|
207
|
+
}
|
|
208
|
+
/** Last `n` chars, cut forward to a word boundary when one is near. */
|
|
209
|
+
function tail(s, n) {
|
|
210
|
+
if (s.length <= n)
|
|
211
|
+
return s;
|
|
212
|
+
const from = s.length - n;
|
|
213
|
+
const cut = s.slice(safe(s, from) === from ? from : from + 1);
|
|
214
|
+
const sp = cut.indexOf(' ');
|
|
215
|
+
return (sp >= 0 && sp < n * 0.4 ? cut.slice(sp + 1) : cut).trimStart();
|
|
216
|
+
}
|
|
217
|
+
const ELLIPSIS = ' … ';
|
|
218
|
+
/** Head and tail of `s` in at most `budget` chars. */
|
|
219
|
+
function headAndTail(s, budget) {
|
|
220
|
+
if (s.length <= budget)
|
|
221
|
+
return s;
|
|
222
|
+
if (budget < 4 * ELLIPSIS.length)
|
|
223
|
+
return head(s, budget);
|
|
224
|
+
const room = budget - ELLIPSIS.length;
|
|
225
|
+
const h = Math.ceil(room / 2);
|
|
226
|
+
return `${head(s, h)}${ELLIPSIS}${tail(s, room - h)}`;
|
|
227
|
+
}
|
|
228
|
+
/** Remove `<name>…</name>` elements in one linear pass; an unclosed one is left alone. */
|
|
229
|
+
function dropElements(s, names) {
|
|
230
|
+
for (const name of names) {
|
|
231
|
+
const open = `<${name}>`, close = `</${name}>`;
|
|
232
|
+
let out = '', at = 0;
|
|
233
|
+
for (let i = s.indexOf(open); i >= 0; i = s.indexOf(open, at)) {
|
|
234
|
+
const j = s.indexOf(close, i + open.length);
|
|
235
|
+
if (j < 0)
|
|
236
|
+
break;
|
|
237
|
+
out += `${s.slice(at, i)}\n`;
|
|
238
|
+
at = j + close.length;
|
|
239
|
+
}
|
|
240
|
+
s = out + s.slice(at);
|
|
241
|
+
}
|
|
242
|
+
return s;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* The query the prime hook recalls with. Pure and synchronous; never throws on a
|
|
246
|
+
* string. `budget` defaults to AWM_PRIME_QUERY_CHARS (400); 0 returns the prompt.
|
|
247
|
+
* Returns '' for a prompt that is nothing but envelope; the caller then skips recall.
|
|
248
|
+
*
|
|
249
|
+
* ORDER MATTERS. The cross-encoder reads the start of the query: the same question and
|
|
250
|
+
* the same memory scored 0.996 with the question in front of 300 chars of notes and
|
|
251
|
+
* 0.007 behind them, and every other memory scored ~0 too, so ranking collapsed. The
|
|
252
|
+
* query therefore leads with the likeliest question: a task's <summary>, then lines
|
|
253
|
+
* that ask something, then the end block of the prompt that reads as a typed request
|
|
254
|
+
* (steps 1-3 below).
|
|
255
|
+
*/
|
|
256
|
+
export function shapePrimeQuery(prompt, budget = PRIME_QUERY_CHARS) {
|
|
257
|
+
if (budget <= 0 || prompt.length <= budget)
|
|
258
|
+
return prompt;
|
|
259
|
+
let text = prompt.replace(/\r\n?/g, '\n');
|
|
260
|
+
// Envelope handling (boilerplate, tag stripping) applies to task notifications only,
|
|
261
|
+
// never to typed text: "What does <summary> do vs <details>?" keeps its subject.
|
|
262
|
+
const envelope = text.trimStart().startsWith('<task-notification>');
|
|
263
|
+
if (envelope)
|
|
264
|
+
text = dropElements(text, BOILERPLATE_ELEMENTS);
|
|
265
|
+
const rawLines = text.split('\n');
|
|
266
|
+
// An unclosed fence would turn everything typed after it into machine output, so the
|
|
267
|
+
// last marker of an odd count does not open a block.
|
|
268
|
+
const fences = rawLines.reduce((a, l, k) => (FENCE.test(l.trim()) ? [...a, k] : a), []);
|
|
269
|
+
const ignoredFence = fences.length % 2 ? fences[fences.length - 1] : -1;
|
|
270
|
+
const lead = []; // <summary> lines
|
|
271
|
+
const prose = []; // unique prose lines, in order
|
|
272
|
+
const blocks = [{ lines: 0, prose: [], size: 0 }];
|
|
273
|
+
const seen = new Set(); // a line repeated verbatim is paste; keep it once
|
|
274
|
+
const machine = [];
|
|
275
|
+
const salient = [];
|
|
276
|
+
let fenced = false;
|
|
277
|
+
for (let k = 0; k < rawLines.length; k++) {
|
|
278
|
+
const trimmed = rawLines[k].trim();
|
|
279
|
+
let b = blocks[blocks.length - 1];
|
|
280
|
+
if (!trimmed) {
|
|
281
|
+
if (b.lines)
|
|
282
|
+
blocks.push({ lines: 0, prose: [], size: 0 });
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
if (FENCE.test(trimmed) && k !== ignoredFence) {
|
|
286
|
+
fenced = !fenced;
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
if (trimmed.length <= CLASSIFY_LEN && ID_TAG_LINE.test(trimmed))
|
|
290
|
+
continue;
|
|
291
|
+
const line = (envelope ? trimmed.replace(TAG, ' ') : trimmed).replace(/\s+/g, ' ').trim();
|
|
292
|
+
if (!line || BOILERPLATE_LINE.test(line))
|
|
293
|
+
continue;
|
|
294
|
+
b.lines++;
|
|
295
|
+
if (fenced || isMarkupOrColumns(trimmed) || isMachineLine(line)) {
|
|
296
|
+
machine.push(line);
|
|
297
|
+
const head400 = line.slice(0, CLASSIFY_LEN);
|
|
298
|
+
if (salient.length < MAX_SALIENT && !salient.includes(line) && (ERROR_WORD.test(head400) || ERROR_CODE.test(head400))) {
|
|
299
|
+
salient.push(line);
|
|
300
|
+
}
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
if (envelope && trimmed.startsWith('<summary>')) {
|
|
304
|
+
lead.push(line);
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
b.prose.push(line);
|
|
308
|
+
b.size += line.length;
|
|
309
|
+
if (seen.has(line))
|
|
310
|
+
continue;
|
|
311
|
+
seen.add(line);
|
|
312
|
+
prose.push(line);
|
|
313
|
+
}
|
|
314
|
+
const wordsIn = (l) => l.split(/\s+/).filter(w => /\p{L}{2}/u.test(w)).length;
|
|
315
|
+
const all = [...lead, ...prose];
|
|
316
|
+
const words = wordsIn(all.join(' ')) + (all.join('').match(CJK_ALL)?.length ?? 0) / 2;
|
|
317
|
+
// No prose, or only a pointer to the paste: the paste is what the prompt is about.
|
|
318
|
+
// The pointer leads, and the paste's head and tail fill the rest.
|
|
319
|
+
if (words < POINTER_WORDS) {
|
|
320
|
+
const pointer = all.join(' ');
|
|
321
|
+
const rest = headAndTail(machine.join('\n'), Math.max(0, budget - pointer.length - 1));
|
|
322
|
+
return headAndTail([pointer, rest].filter(Boolean).join('\n'), budget);
|
|
323
|
+
}
|
|
324
|
+
// 1. Questions move to the front, within half the budget.
|
|
325
|
+
const questions = [];
|
|
326
|
+
const asked = new Set();
|
|
327
|
+
let used = 0;
|
|
328
|
+
for (const line of prose) {
|
|
329
|
+
if (questions.length >= MAX_QUESTIONS)
|
|
330
|
+
break;
|
|
331
|
+
const at = line.search(QUESTION);
|
|
332
|
+
if (at < 0)
|
|
333
|
+
continue;
|
|
334
|
+
// A long line is cut to the sentence that asks (searched backwards from the '?',
|
|
335
|
+
// within a bounded window); the line itself stays in the prose.
|
|
336
|
+
let q = line;
|
|
337
|
+
if (line.length > QUESTION_LEN) {
|
|
338
|
+
const from = Math.max(0, at - 2 * QUESTION_LEN);
|
|
339
|
+
const before = line.slice(from, at);
|
|
340
|
+
const stop = Math.max(before.lastIndexOf('. '), before.lastIndexOf('! '), before.lastIndexOf('? '));
|
|
341
|
+
q = head(line.slice(stop >= 0 ? from + stop + 2 : from, at + 1).trim(), QUESTION_LEN);
|
|
342
|
+
}
|
|
343
|
+
if (used + q.length + 1 > budget / 2)
|
|
344
|
+
break;
|
|
345
|
+
questions.push(q);
|
|
346
|
+
if (q === line)
|
|
347
|
+
asked.add(line);
|
|
348
|
+
used += q.length + 1;
|
|
349
|
+
}
|
|
350
|
+
// 2. Otherwise the typed request is usually a block at one end of the prompt, set off
|
|
351
|
+
// from the paste by a blank line. An end block can lead only if it is mostly prose and
|
|
352
|
+
// holds a sentence that is not a heading, an introducer, a sign-off or a signature.
|
|
353
|
+
// When both ends can, the first leads unless it is clearly the paste (over twice the
|
|
354
|
+
// size of the last). This needs no knowledge of the paste's format, so it holds when
|
|
355
|
+
// some of a paste's lines leak through as prose.
|
|
356
|
+
const filled = blocks.filter(b => b.lines > 0);
|
|
357
|
+
const canLead = (b) => b.prose.length / b.lines >= 0.5
|
|
358
|
+
&& b.prose.some(l => (wordsIn(l) >= POINTER_WORDS || CJK.test(l))
|
|
359
|
+
&& !HEADING.test(l) && !INTRODUCER.test(l) && !SIGN_OFF.test(l) && !SIGNATURE.test(l));
|
|
360
|
+
let leadBlock = [];
|
|
361
|
+
let decided = questions.length > 0;
|
|
362
|
+
if (!decided && filled.length >= 2) {
|
|
363
|
+
const first = filled[0], last = filled[filled.length - 1];
|
|
364
|
+
const firstOk = canLead(first), lastOk = canLead(last);
|
|
365
|
+
if (lastOk && (!firstOk || last.size * 2 < first.size))
|
|
366
|
+
leadBlock = last.prose;
|
|
367
|
+
decided = firstOk || lastOk;
|
|
368
|
+
}
|
|
369
|
+
const front = new Set(leadBlock);
|
|
370
|
+
const remaining = [...new Set(leadBlock)].concat(prose.filter(l => !asked.has(l) && !front.has(l)));
|
|
371
|
+
// Fragments ("## Meeting notes", "Node.js v20.11.0", a stray "+ Get-Item C:\x" that
|
|
372
|
+
// escaped the machine rules) go to the back.
|
|
373
|
+
const isSentence = (l) => wordsIn(l) >= POINTER_WORDS || CJK.test(l);
|
|
374
|
+
const sentences = remaining.filter(isSentence);
|
|
375
|
+
const fragments = remaining.filter(l => !isSentence(l));
|
|
376
|
+
// 3. One block, or neither end can lead: among the sentences, the shorter end leads.
|
|
377
|
+
if (!decided && sentences.length >= 2 && sentences[sentences.length - 1].length < sentences[0].length) {
|
|
378
|
+
sentences.unshift(sentences.pop());
|
|
379
|
+
}
|
|
380
|
+
const rest = [...sentences, ...fragments];
|
|
381
|
+
// Error lines get a reserved share, so long prose cannot crowd them out.
|
|
382
|
+
const each = Math.floor((budget * SALIENT_SHARE) / Math.max(1, salient.length)) - 1;
|
|
383
|
+
const errors = each >= 20 ? salient.map(e => head(e, each)) : [];
|
|
384
|
+
const reserve = errors.length ? errors.join('\n').length + 1 : 0;
|
|
385
|
+
const body = headAndTail([...lead, ...questions, ...rest].join('\n'), budget - reserve);
|
|
386
|
+
return [body, ...errors].join('\n');
|
|
387
|
+
}
|
|
388
|
+
//# sourceMappingURL=prime-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prime-query.js","sourceRoot":"","sources":["../../src/hooks/prime-query.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks/prime.d.ts
CHANGED
|
@@ -36,13 +36,21 @@ export interface PrimeCandidate {
|
|
|
36
36
|
concept: string;
|
|
37
37
|
content: string;
|
|
38
38
|
memoryClass?: string;
|
|
39
|
+
validFrom?: string | null;
|
|
39
40
|
validTo?: string | null;
|
|
41
|
+
supersededBy?: string | null;
|
|
40
42
|
/** Used for the age label; Date from the store, string over HTTP. */
|
|
41
43
|
createdAt?: Date | string | null;
|
|
42
44
|
};
|
|
43
45
|
score: number;
|
|
44
46
|
summary?: string;
|
|
45
47
|
confidence?: number;
|
|
48
|
+
/** Other results in the same recall that look like another version of this fact. */
|
|
49
|
+
conflictsWith?: Array<{
|
|
50
|
+
id: string;
|
|
51
|
+
newer: boolean;
|
|
52
|
+
slot: string;
|
|
53
|
+
}>;
|
|
46
54
|
}
|
|
47
55
|
export interface PrimeOptions {
|
|
48
56
|
/** Hard ceiling on injected tokens. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prime.d.ts","sourceRoot":"","sources":["../../src/hooks/prime.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;
|
|
1
|
+
{"version":3,"file":"prime.d.ts","sourceRoot":"","sources":["../../src/hooks/prime.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAMH,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QACnE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,qEAAqE;QACrE,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;KAClC,CAAC;IACF,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrE;AAED,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,MAAM,CAAC,EAAE,YAAY,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;CAC/D;AAED,eAAO,MAAM,cAAc;;IAEzB;;;;;;;;OAQG;;;CAGK,CAAC;AAkCX;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,cAAc,EAAE,EAC5B,IAAI,GAAE,YAAiB,GACtB,WAAW,CA6Cb"}
|
package/dist/hooks/prime.js
CHANGED
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
* thrown error. A hook that errors on every prompt is worse than no hook.
|
|
33
33
|
*/
|
|
34
34
|
import { packRecallByBudget, estimateTokens } from '../core/token-budget.js';
|
|
35
|
+
import { isFaded } from '../core/format-recall.js';
|
|
36
|
+
import { validityState } from '../core/validity.js';
|
|
35
37
|
export const PRIME_DEFAULTS = {
|
|
36
38
|
maxTokens: 600,
|
|
37
39
|
/**
|
|
@@ -51,14 +53,31 @@ export const PRIME_DEFAULTS = {
|
|
|
51
53
|
* report. The id is retained so the agent can act on it (feedback, supersede). */
|
|
52
54
|
function formatPrimeLine(c, now = Date.now()) {
|
|
53
55
|
const body = c.summary ?? c.engram.content;
|
|
54
|
-
|
|
56
|
+
// Same validity decision as ranking and the MCP format (core/validity.ts).
|
|
57
|
+
const vstate = validityState(c.engram, now);
|
|
58
|
+
const validity = vstate === 'expired'
|
|
59
|
+
? ` ⚠ EXPIRED ${c.engram.validTo}`
|
|
60
|
+
: vstate === 'not-yet-valid'
|
|
61
|
+
? ` [not yet valid — from ${c.engram.validFrom}]`
|
|
62
|
+
: c.engram.validTo ? ` [valid until ${c.engram.validTo}]` : '';
|
|
63
|
+
// The MCP format has carried this since 0.12.x; the prime line dropped it, so
|
|
64
|
+
// pushed context could present a superseded memory as current with no sign.
|
|
65
|
+
const superseded = c.engram.supersededBy ? ` · superseded by ${c.engram.supersededBy}` : '';
|
|
66
|
+
// Terse form of the MCP conflict mark: enough to send the agent to the source.
|
|
67
|
+
const conflicts = (c.conflictsWith ?? []).length > 0
|
|
68
|
+
? ` · ${(c.conflictsWith ?? []).some(x => x.newer) ? 'newer than' : 'older than'} ${(c.conflictsWith ?? []).map(x => x.id).join(', ')} — confirm before stating a value`
|
|
69
|
+
: '';
|
|
55
70
|
// Class + age make the volatility rubric mechanical: a 90-day-old working
|
|
56
71
|
// memory reads differently from a 2-day-old canonical one, and the agent
|
|
57
72
|
// should not have to look either up before deciding how much to trust it.
|
|
58
73
|
const cls = c.engram.memoryClass ?? 'working';
|
|
59
74
|
const created = c.engram.createdAt ? new Date(c.engram.createdAt).getTime() : NaN;
|
|
60
75
|
const age = Number.isFinite(created) ? ` · ${Math.max(0, Math.round((now - created) / 86_400_000))}d` : '';
|
|
61
|
-
|
|
76
|
+
// Same reason as the MCP format: a trimmed body that still reads as an answer
|
|
77
|
+
// is the one failure mode the agent cannot detect for itself. Terser here
|
|
78
|
+
// because this is unrequested context.
|
|
79
|
+
const faded = isFaded(c.engram.content) ? ' · faded' : '';
|
|
80
|
+
return `- [${cls}${age}${faded}${superseded}${conflicts}] ${c.engram.concept}${validity} [${c.engram.id}]: ${body}`;
|
|
62
81
|
}
|
|
63
82
|
/**
|
|
64
83
|
* Build the injection for a prompt. Pure — no I/O — so it is unit-testable
|
package/dist/hooks/prime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prime.js","sourceRoot":"","sources":["../../src/hooks/prime.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,sCAAsC;AACtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAqB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"prime.js","sourceRoot":"","sources":["../../src/hooks/prime.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks/sidecar.d.ts
CHANGED
|
@@ -53,11 +53,18 @@ export interface SidecarDeps {
|
|
|
53
53
|
content: string;
|
|
54
54
|
createdAt?: string;
|
|
55
55
|
memoryClass?: string;
|
|
56
|
+
validFrom?: string | null;
|
|
56
57
|
validTo?: string | null;
|
|
58
|
+
supersededBy?: string | null;
|
|
57
59
|
};
|
|
58
60
|
score: number;
|
|
59
61
|
summary?: string;
|
|
60
62
|
confidence?: number;
|
|
63
|
+
conflictsWith?: Array<{
|
|
64
|
+
id: string;
|
|
65
|
+
newer: boolean;
|
|
66
|
+
slot: string;
|
|
67
|
+
}>;
|
|
61
68
|
}>>;
|
|
62
69
|
}
|
|
63
70
|
export interface SidecarHandle {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidecar.d.ts","sourceRoot":"","sources":["../../src/hooks/sidecar.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,YAAY,IAAI,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"sidecar.d.ts","sourceRoot":"","sources":["../../src/hooks/sidecar.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,YAAY,IAAI,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAMvE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;KAC3C,KAAK,OAAO,CAAC,KAAK,CAAC;QAClB,MAAM,EAAE;YACN,EAAE,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAC;YACzC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;SAClF,CAAC;QACF,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,OAAO,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACrE,CAAC,CAAC,CAAC;CACL;AA0GD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,wFAAwF;IACxF,SAAS,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,aAAa,CAmQ7D"}
|
package/dist/hooks/sidecar.js
CHANGED
|
@@ -19,6 +19,7 @@ import { createServer } from 'node:http';
|
|
|
19
19
|
import { readFileSync, existsSync } from 'node:fs';
|
|
20
20
|
import { log, getLogPath } from '../core/logger.js';
|
|
21
21
|
import { buildPrimeInjection } from './prime.js';
|
|
22
|
+
import { shapePrimeQuery } from './prime-query.js';
|
|
22
23
|
/**
|
|
23
24
|
* Parse the Claude Code transcript to extract context for auto-checkpointing.
|
|
24
25
|
* Reads the JSONL transcript file and extracts recent tool calls, files, and user messages.
|
|
@@ -210,8 +211,15 @@ export function startSidecar(deps) {
|
|
|
210
211
|
json(res, 200, { inject: '', kept: 0, total: 0, tokens: 0, reason: 'no-prompt' });
|
|
211
212
|
return;
|
|
212
213
|
}
|
|
214
|
+
// Recall against the prompt's question, not its paste (prime-query.ts).
|
|
215
|
+
const query = shapePrimeQuery(context);
|
|
216
|
+
if (!query.trim()) {
|
|
217
|
+
// Nothing but envelope (ids, fences, trailers): no question to recall for.
|
|
218
|
+
json(res, 200, { inject: '', kept: 0, total: 0, tokens: 0, reason: 'no-prompt' });
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
213
221
|
const candidates = await deps.activate({
|
|
214
|
-
context,
|
|
222
|
+
context: query,
|
|
215
223
|
limit: 8,
|
|
216
224
|
granularity: 'compact', // priming is a brief note, not a report
|
|
217
225
|
});
|
|
@@ -220,7 +228,7 @@ export function startSidecar(deps) {
|
|
|
220
228
|
minConfidence: body.minConfidence,
|
|
221
229
|
minScore: body.minScore,
|
|
222
230
|
});
|
|
223
|
-
log(agentId, 'hook:prime', `"${
|
|
231
|
+
log(agentId, 'hook:prime', `"${query.slice(0, 60)}"${query === context ? '' : ` (shaped ${context.length}→${query.length} chars)`} → ${primed.kept}/${primed.total} injected, ~${primed.tokens} tok${primed.reason ? ` (${primed.reason})` : ''}`);
|
|
224
232
|
json(res, 200, { ...primed });
|
|
225
233
|
}
|
|
226
234
|
catch (err) {
|