@zenera/neo 1.1.19 → 1.1.21

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.
@@ -1,103 +0,0 @@
1
- import { MEMORY_COMMIT_TOOL, MEMORY_FORGET_TOOL, MEMORY_LOAD_TOOL, MEMORY_SEARCH_TOOL, } from "../types.js";
2
- import { RECOLLECTION_TAG } from "./render.js";
3
- import { canForget, canWrite } from "./types.js";
4
- // ---------------------------------------------------------------------------
5
- // Teaching the model to read and write memory
6
- //
7
- // The tool schemas say what the arguments are; none of them says when a thing
8
- // is worth remembering, or that a recollection is a subgraph rather than a
9
- // ranked list. That is policy, it is the same for every agent, and it belongs
10
- // in the system prompt — which is also the only place it can be stated once
11
- // per run instead of once per call.
12
- //
13
- // Both halves go in through `composePrompt`'s `derived` array, so they sit in
14
- // the cacheable prefix and are recorded in the `system_prompt` node like every
15
- // other part of what the model read.
16
- //
17
- // The text is gated on the binding, not on the project: an agent that cannot
18
- // write is never told how to commit. A rule it cannot act on is a rule it can
19
- // only be confused by, and an unusable tool name in the prompt invites a call
20
- // that will be refused.
21
- // ---------------------------------------------------------------------------
22
- export const PREFERENCES_TAG = 'memory-preferences';
23
- /**
24
- * Deliberately not a function of `sees`: those labels come from the run's
25
- * context, and naming them here would rewrite the prompt whenever the context
26
- * moved. It also tells an agent the shape of a slice it was not given.
27
- */
28
- export function memoryInstructions(binding) {
29
- const parts = [READING];
30
- if (canWrite(binding)) {
31
- parts.push(WRITING);
32
- }
33
- if (canForget(binding)) {
34
- parts.push(FORGETTING);
35
- }
36
- return parts.join('\n\n');
37
- }
38
- const READING = `Memory is a graph shared with other agents, and it outlives this run.
39
-
40
- A <${RECOLLECTION_TAG}> block is a subgraph, not a ranked list — the links are
41
- as much of the answer as the nodes. It is an outline, and the indentation is
42
- the graph. A line at the left margin reads \`score kind id\` and is something
43
- the search matched. A line indented under it reads \`<arrow>relation kind id\`
44
- and is a neighbour: \`\u2192produced\` means the line above produced this one,
45
- \`\u2190informed\` means this one informed the line above. A neighbour the
46
- search matched in its own right carries a score too, after the arrow. Under
47
- each header, indented further, is that node's text — and for a \`file\`, the
48
- path under /memory you can open or run, its size and how often it has been read.
49
-
50
- A line beginning \`+\` is a link to an id already shown above, for an edge the
51
- outline could not nest. Text is clipped: copy an id into \`${MEMORY_LOAD_TOOL}\`
52
- to read a node whole. \`${MEMORY_SEARCH_TOOL}\` finds ids, it does not return
53
- contents.
54
-
55
- You see part of the graph, not all of it. Finding nothing means nothing you can
56
- see, not that it never happened.`;
57
- const WRITING = `Commit when a run produced something a later run would otherwise have to work
58
- out again: a script that ran, an interface that behaved differently from its
59
- documentation, a call sequence that turned out to be necessary. Commit it in
60
- one \`${MEMORY_COMMIT_TOOL}\` call — the artifact and what explains it are one
61
- memory, and splitting them leaves a later run holding a script with no idea why
62
- it exists.
63
-
64
- Do not commit the request restated, progress notes, anything you have not
65
- verified, or anything a search already returned. A node that says what one
66
- already in memory says is folded into it and its existing id comes back under
67
- your ref, so the links you asked for still land — on the memory that was
68
- already there.
69
-
70
- Never edit a memory to correct it. Add the new one and link it to the old with
71
- SUPERSEDES; the wrong answer is evidence too, and the link is what hides it
72
- from later recalls without destroying the history.
73
-
74
- Commit a preference only when the user's own words generalise — "always", "from
75
- now on", "I prefer", "never". A single request being fulfilled is not a
76
- standing instruction.`;
77
- const FORGETTING = `Forget only what is wrong and has no successor. A superseded memory is already
78
- hidden from recall and should stay for the history, so \`${MEMORY_FORGET_TOOL}\`
79
- is for what should never have been written, not for what has been replaced.`;
80
- /**
81
- * The id on each line is what makes a preference revisable rather than merely
82
- * readable: without it the model can read the instruction but cannot name the
83
- * thing it would supersede.
84
- */
85
- export function renderPreferences(nodes) {
86
- if (!nodes.length) {
87
- return '';
88
- }
89
- const lines = nodes.map((n) => `- ${oneLine(n.text)} [${n.id}]`);
90
- return [
91
- `<${PREFERENCES_TAG}>`,
92
- "Standing instructions from earlier runs. They apply unless this run's",
93
- 'request contradicts them; to change one, commit the replacement and link',
94
- 'it to the id here with SUPERSEDES.',
95
- ...lines,
96
- `</${PREFERENCES_TAG}>`,
97
- ].join('\n');
98
- }
99
- /** Never clipped: half an instruction is a different instruction. */
100
- function oneLine(text) {
101
- return text.replace(/\s+/g, ' ').trim();
102
- }
103
- //# sourceMappingURL=instructions.js.map