@oharness/engine 0.12.0 → 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/dist/agent/agent.d.ts +3 -0
- package/dist/agent/agent.js +32 -12
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/background-usage.d.ts +34 -0
- package/dist/agent/background-usage.js +53 -0
- package/dist/agent/background-usage.js.map +1 -0
- package/dist/agent/background.d.ts +2 -0
- package/dist/agent/background.js +11 -0
- package/dist/agent/background.js.map +1 -1
- package/dist/agent/memory-backup.d.ts +1 -1
- package/dist/agent/memory-backup.js +1 -1
- package/dist/agent/memory-backup.js.map +1 -1
- package/dist/agent/memory-digest.d.ts +107 -0
- package/dist/agent/memory-digest.js +208 -0
- package/dist/agent/memory-digest.js.map +1 -0
- package/dist/agent/memory-dream.d.ts +106 -0
- package/dist/agent/memory-dream.js +237 -0
- package/dist/agent/memory-dream.js.map +1 -0
- package/dist/agent/memory-ledger.d.ts +154 -0
- package/dist/agent/memory-ledger.js +179 -0
- package/dist/agent/memory-ledger.js.map +1 -0
- package/dist/agent/memory-provider.d.ts +12 -0
- package/dist/agent/memory-recall.d.ts +2 -0
- package/dist/agent/memory-recall.js +5 -2
- package/dist/agent/memory-recall.js.map +1 -1
- package/dist/agent/memory-usage.d.ts +20 -0
- package/dist/agent/memory-usage.js +16 -1
- package/dist/agent/memory-usage.js.map +1 -1
- package/dist/agent/memory.d.ts +3 -0
- package/dist/agent/memory.js +24 -4
- package/dist/agent/memory.js.map +1 -1
- package/dist/agent/store.d.ts +7 -0
- package/dist/agent/store.js +14 -1
- package/dist/agent/store.js.map +1 -1
- package/dist/config-files.d.ts +6 -1
- package/dist/config-files.js +7 -2
- package/dist/config-files.js.map +1 -1
- package/dist/harness.d.ts +20 -0
- package/dist/harness.js +58 -8
- package/dist/harness.js.map +1 -1
- package/dist/runtime-plugins/builtin/dreaming-coordinator.d.ts +244 -0
- package/dist/runtime-plugins/builtin/dreaming-coordinator.js +548 -0
- package/dist/runtime-plugins/builtin/dreaming-coordinator.js.map +1 -0
- package/dist/runtime-plugins/builtin/dreaming.d.ts +30 -0
- package/dist/runtime-plugins/builtin/dreaming.js +231 -0
- package/dist/runtime-plugins/builtin/dreaming.js.map +1 -0
- package/dist/runtime-plugins/builtin/memory.d.ts +89 -2
- package/dist/runtime-plugins/builtin/memory.js +186 -5
- package/dist/runtime-plugins/builtin/memory.js.map +1 -1
- package/dist/runtime-plugins/host.js +2 -0
- package/dist/runtime-plugins/host.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { MEMORY_SAFETY, isMemoryType } from "./memory-limits.js";
|
|
2
|
+
import { rankNotes } from "./memory-recall.js";
|
|
3
|
+
import { redactSecrets } from "./memory-redact.js";
|
|
4
|
+
export const DREAM_PROMPT = `You maintain the durable notes an assistant reads in future sessions. You are given new claims taken from recent conversations, with the evidence for each, and the existing notes they may touch. Propose the smallest set of edits that makes the notes true and useful.
|
|
5
|
+
|
|
6
|
+
Operations:
|
|
7
|
+
- "create": a new note from one or more claims that no existing note covers.
|
|
8
|
+
- "update": rewrite one existing note because claims correct or extend it. Write the complete new body, keeping every detail of the old body that is still true.
|
|
9
|
+
- "merge": several existing notes say the same thing; write the one note that replaces them.
|
|
10
|
+
- "stale": a note's content has lapsed (a date passed, work finished) according to the claims. Do not rewrite it.
|
|
11
|
+
- "conflict": claims contradict a note and nobody said which one replaces the other. Do not choose; explain.
|
|
12
|
+
|
|
13
|
+
Rules:
|
|
14
|
+
- Cite the claims each operation rests on by id. Every operation except "merge" must cite at least one claim.
|
|
15
|
+
- Only touch notes listed below, by their id.
|
|
16
|
+
- Newer evidence is the claim's time, never a note's "last edited" time. Replace a note's statement only when a claim says the user replaced it.
|
|
17
|
+
- Never turn a plan into a completed fact because its date passed.
|
|
18
|
+
- If claims add nothing, leave them out. Proposing nothing is a good outcome.
|
|
19
|
+
- Create a note only for something a later conversation would need: a preference, a correction, a decision and its reason, an ongoing goal. Never for the specification of one task (its columns, steps or format).
|
|
20
|
+
|
|
21
|
+
How a note is written, because recall matches words, not meaning:
|
|
22
|
+
- "summary": one concrete line naming what the note is about.
|
|
23
|
+
- "tags": the words someone might search with instead of the summary's own, including synonyms and the term in the other language in use. A merge keeps every tag of the notes it combines unless one is plainly wrong.
|
|
24
|
+
- "body": the fact, then a line starting "Why:" and a line starting "How to apply:".
|
|
25
|
+
- A note that has been recalled often is revised conservatively: keep its summary's key words and its tags unless the evidence says they are wrong.
|
|
26
|
+
|
|
27
|
+
Respond with a JSON array and nothing else. Each element is one of:
|
|
28
|
+
{"op":"create","scope":"project"|"user","claims":["<claim id>"],"summary":"...","body":"...","tags":["..."],"type":"user"|"feedback"|"project"|"reference"}
|
|
29
|
+
{"op":"update","id":"<note id>","claims":["..."],"summary":"...","body":"...","tags":["..."],"type":"..."}
|
|
30
|
+
{"op":"merge","ids":["<note id>","<note id>"],"claims":["..."],"summary":"...","body":"...","tags":["..."],"type":"..."}
|
|
31
|
+
{"op":"stale","id":"<note id>","claims":["..."],"reason":"..."}
|
|
32
|
+
{"op":"conflict","id":"<note id>","claims":["..."],"reason":"..."}
|
|
33
|
+
|
|
34
|
+
Return [] when nothing should change.`;
|
|
35
|
+
const when = (at) => new Date(at).toISOString().slice(0, 10);
|
|
36
|
+
/** The prompt for one scope: claims with their evidence, notes with their history. */
|
|
37
|
+
export function dreamPrompt(claims, notes, now = Date.now()) {
|
|
38
|
+
const claimBlocks = claims.map((claim) => {
|
|
39
|
+
const extra = [
|
|
40
|
+
`kind=${claim.kind}`, `said=${when(claim.at)}`, `scope=${claim.scope}`, `session=${claim.session}`,
|
|
41
|
+
claim.validUntil ? `validUntil=${when(claim.validUntil)}` : "",
|
|
42
|
+
claim.supersedes ? `supersedes="${claim.supersedes}"` : "",
|
|
43
|
+
claim.lasting ? "lasting=yes" : "",
|
|
44
|
+
claim.inContext?.length ? `noteInContext=${claim.inContext.join(",")}` : "",
|
|
45
|
+
].filter(Boolean).join(" ");
|
|
46
|
+
return `<claim id="${claim.id}" ${extra}>\n${claim.text}${claim.quote ? `\nUser's words: "${claim.quote}"` : ""}\n</claim>`;
|
|
47
|
+
});
|
|
48
|
+
const noteBlocks = notes.map((note) => {
|
|
49
|
+
const meta = [
|
|
50
|
+
`id=${note.id}`, `scope=${note.scope}`, note.type ? `type=${note.type}` : "",
|
|
51
|
+
`lastEdited=${when(note.updatedAt ?? note.createdAt)}`,
|
|
52
|
+
note.recalled ? `recalled=${note.recalled.count}x,last=${when(note.recalled.last)}` : "recalled=never",
|
|
53
|
+
note.tags.length ? `tags=${note.tags.join(",")}` : "",
|
|
54
|
+
].filter(Boolean).join(" ");
|
|
55
|
+
return `<note ${meta}>\n${note.summary}\n\n${note.body}\n</note>`;
|
|
56
|
+
});
|
|
57
|
+
return [
|
|
58
|
+
`Today is ${when(now)}.`,
|
|
59
|
+
"",
|
|
60
|
+
"New claims:",
|
|
61
|
+
claimBlocks.join("\n\n") || "(none)",
|
|
62
|
+
"",
|
|
63
|
+
"Existing notes you may touch:",
|
|
64
|
+
noteBlocks.join("\n\n") || "(none)",
|
|
65
|
+
"",
|
|
66
|
+
"Propose the edits now, as a JSON array.",
|
|
67
|
+
].join("\n");
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The notes a dream may touch: those most related to each claim, and every
|
|
71
|
+
* note a claim says was recalled when it was made, whether or not the ranker
|
|
72
|
+
* finds it. Bodies are shown in full, so the set is bounded.
|
|
73
|
+
*/
|
|
74
|
+
export function chooseNotes(claims, notes, limit = 12, bodyBudget = 24_000) {
|
|
75
|
+
const byId = new Map(notes.map((note) => [`${note.scope}:${note.id}`, note]));
|
|
76
|
+
const chosen = new Map();
|
|
77
|
+
const take = (note) => {
|
|
78
|
+
if (!note || chosen.has(`${note.scope}:${note.id}`) || chosen.size >= limit)
|
|
79
|
+
return;
|
|
80
|
+
if (note.body.length > bodyBudget)
|
|
81
|
+
return;
|
|
82
|
+
bodyBudget -= note.body.length;
|
|
83
|
+
chosen.set(`${note.scope}:${note.id}`, note);
|
|
84
|
+
};
|
|
85
|
+
for (const claim of claims)
|
|
86
|
+
for (const id of claim.inContext ?? [])
|
|
87
|
+
take(byId.get(`${claim.scope}:${id}`) ?? byId.get(`project:${id}`) ?? byId.get(`user:${id}`));
|
|
88
|
+
for (const claim of claims)
|
|
89
|
+
for (const ranked of rankNotes(notes, claim.text).slice(0, 3))
|
|
90
|
+
take(ranked.note);
|
|
91
|
+
return [...chosen.values()];
|
|
92
|
+
}
|
|
93
|
+
function cleanTags(tags) {
|
|
94
|
+
if (!Array.isArray(tags))
|
|
95
|
+
return [];
|
|
96
|
+
const out = [];
|
|
97
|
+
for (const tag of tags) {
|
|
98
|
+
if (typeof tag !== "string")
|
|
99
|
+
continue;
|
|
100
|
+
const value = tag.trim().toLowerCase();
|
|
101
|
+
if (MEMORY_SAFETY.tagPattern.test(value) && !out.includes(value))
|
|
102
|
+
out.push(value);
|
|
103
|
+
if (out.length >= MEMORY_SAFETY.maxTags)
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
function draft(value) {
|
|
109
|
+
const summary = typeof value.summary === "string" ? redactSecrets(value.summary.replace(/[\r\n]+/g, " ").trim()).text : "";
|
|
110
|
+
const body = typeof value.body === "string" ? redactSecrets(value.body.trim()).text : "";
|
|
111
|
+
if (summary.length < 4 || summary.length > MEMORY_SAFETY.maxSummaryChars || body.length < 4)
|
|
112
|
+
return undefined;
|
|
113
|
+
return { summary, body, tags: cleanTags(value.tags), ...(isMemoryType(value.type) ? { type: value.type } : {}) };
|
|
114
|
+
}
|
|
115
|
+
const text = (value, max) => typeof value === "string" ? redactSecrets(value.replace(/\s+/g, " ").trim()).text.slice(0, max) : "";
|
|
116
|
+
/**
|
|
117
|
+
* Validate a dream reply against what it was shown. Operations on notes it
|
|
118
|
+
* was not shown, citing claims it was not given, or crossing scopes are
|
|
119
|
+
* dropped; so is a second operation on a note already touched.
|
|
120
|
+
*/
|
|
121
|
+
export function parseDreamOps(reply, claims, notes) {
|
|
122
|
+
const start = reply.indexOf("["), end = reply.lastIndexOf("]");
|
|
123
|
+
if (start === -1 || end <= start)
|
|
124
|
+
return [];
|
|
125
|
+
let raw;
|
|
126
|
+
try {
|
|
127
|
+
raw = JSON.parse(reply.slice(start, end + 1));
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
if (!Array.isArray(raw))
|
|
133
|
+
return [];
|
|
134
|
+
const claimById = new Map(claims.map((claim) => [claim.id, claim]));
|
|
135
|
+
const noteById = new Map(notes.map((note) => [note.id, note]));
|
|
136
|
+
const touched = new Set();
|
|
137
|
+
const ops = [];
|
|
138
|
+
for (const item of raw.slice(0, 30)) {
|
|
139
|
+
if (!item || typeof item !== "object")
|
|
140
|
+
continue;
|
|
141
|
+
const value = item;
|
|
142
|
+
const cited = Array.isArray(value.claims)
|
|
143
|
+
? [...new Set(value.claims.filter((id) => typeof id === "string" && claimById.has(id)))]
|
|
144
|
+
: [];
|
|
145
|
+
const target = typeof value.id === "string" ? noteById.get(value.id) : undefined;
|
|
146
|
+
const fresh = (note) => !!note && !touched.has(note.id);
|
|
147
|
+
// A claim about one scope cannot change a note in another.
|
|
148
|
+
const sameScope = (scope) => cited.every((id) => claimById.get(id).scope === scope);
|
|
149
|
+
if (value.op === "create") {
|
|
150
|
+
const body = draft(value);
|
|
151
|
+
if (!body || !cited.length)
|
|
152
|
+
continue;
|
|
153
|
+
const scope = claimById.get(cited[0]).scope;
|
|
154
|
+
if (!sameScope(scope))
|
|
155
|
+
continue;
|
|
156
|
+
ops.push({ op: "create", scope, claims: cited, ...body });
|
|
157
|
+
}
|
|
158
|
+
else if (value.op === "update") {
|
|
159
|
+
const body = draft(value);
|
|
160
|
+
if (!body || !cited.length || !fresh(target) || !sameScope(target.scope))
|
|
161
|
+
continue;
|
|
162
|
+
touched.add(target.id);
|
|
163
|
+
ops.push({ op: "update", id: target.id, scope: target.scope, claims: cited, expectedHash: target.hash, ...body, ...(body.type ?? target.type ? { type: body.type ?? target.type } : {}) });
|
|
164
|
+
}
|
|
165
|
+
else if (value.op === "merge") {
|
|
166
|
+
const body = draft(value);
|
|
167
|
+
const ids = Array.isArray(value.ids) ? [...new Set(value.ids.filter((id) => typeof id === "string"))] : [];
|
|
168
|
+
const group = ids.map((id) => noteById.get(id));
|
|
169
|
+
if (!body || group.length < 2 || group.length > 6 || !group.every(fresh))
|
|
170
|
+
continue;
|
|
171
|
+
const scope = group[0].scope;
|
|
172
|
+
if (!group.every((note) => note.scope === scope) || !sameScope(scope))
|
|
173
|
+
continue;
|
|
174
|
+
for (const note of group)
|
|
175
|
+
touched.add(note.id);
|
|
176
|
+
ops.push({ op: "merge", ids: group.map((note) => note.id), scope, claims: cited, expectedHashes: group.map((note) => note.hash), ...body });
|
|
177
|
+
}
|
|
178
|
+
else if (value.op === "stale" || value.op === "conflict") {
|
|
179
|
+
const reason = text(value.reason, 300);
|
|
180
|
+
if (!cited.length || !reason || !fresh(target) || !sameScope(target.scope))
|
|
181
|
+
continue;
|
|
182
|
+
touched.add(target.id);
|
|
183
|
+
ops.push({ op: value.op, id: target.id, scope: target.scope, claims: cited, reason, expectedHash: target.hash });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return ops;
|
|
187
|
+
}
|
|
188
|
+
const DIRECT = new Set(["stated", "confirmed"]);
|
|
189
|
+
/**
|
|
190
|
+
* Whether an operation may be applied without asking. Conservative by
|
|
191
|
+
* design: an inference from one conversation, a user-wide preference drawn
|
|
192
|
+
* from inference, anything about lapsed or contradicted notes, and edits to
|
|
193
|
+
* notes changed by hand since a dream last wrote them all wait for a person.
|
|
194
|
+
*
|
|
195
|
+
* `dreamWrote` maps a note id to the hash a dream last left it at, when one did.
|
|
196
|
+
*/
|
|
197
|
+
export function dispose(op, claims, dreamWrote = new Map()) {
|
|
198
|
+
if (op.op === "stale")
|
|
199
|
+
return { op, disposition: "review", why: "stale" };
|
|
200
|
+
if (op.op === "conflict")
|
|
201
|
+
return { op, disposition: "review", why: "conflict" };
|
|
202
|
+
const byId = new Map(claims.map((claim) => [claim.id, claim]));
|
|
203
|
+
const cited = op.claims.map((id) => byId.get(id)).filter((claim) => !!claim);
|
|
204
|
+
const targets = op.op === "update" ? [{ id: op.id, hash: op.expectedHash }]
|
|
205
|
+
: op.op === "merge" ? op.ids.map((id, i) => ({ id, hash: op.expectedHashes[i] })) : [];
|
|
206
|
+
if (targets.some((target) => dreamWrote.has(target.id) && dreamWrote.get(target.id) !== target.hash)) {
|
|
207
|
+
return { op, disposition: "review", why: "hand-edited" };
|
|
208
|
+
}
|
|
209
|
+
if (op.op === "merge" && !cited.length)
|
|
210
|
+
return { op, disposition: "apply" };
|
|
211
|
+
const sessions = new Set(cited.map((claim) => claim.session));
|
|
212
|
+
const inferred = cited.filter((claim) => !DIRECT.has(claim.kind));
|
|
213
|
+
if (inferred.length) {
|
|
214
|
+
if (op.scope === "user")
|
|
215
|
+
return { op, disposition: "review", why: "user-scope-inference" };
|
|
216
|
+
if (sessions.size < 2)
|
|
217
|
+
return { op, disposition: "review", why: "inferred-once" };
|
|
218
|
+
}
|
|
219
|
+
// A new note is the riskiest change: most of what one conversation says is
|
|
220
|
+
// about that conversation. It applies on its own only when the user said it
|
|
221
|
+
// lasts, or more than one conversation says it.
|
|
222
|
+
if (op.op === "create" && sessions.size < 2 && !cited.some((claim) => claim.lasting)) {
|
|
223
|
+
return { op, disposition: "review", why: "one-conversation" };
|
|
224
|
+
}
|
|
225
|
+
return { op, disposition: "apply" };
|
|
226
|
+
}
|
|
227
|
+
/** One model call for one scope. Writes nothing. */
|
|
228
|
+
export async function dreamScope(run) {
|
|
229
|
+
if (!run.claims.length)
|
|
230
|
+
return { ops: [], shown: [], chars: 0 };
|
|
231
|
+
const shown = chooseNotes(run.claims, run.notes);
|
|
232
|
+
const prompt = dreamPrompt(run.claims, shown, run.now);
|
|
233
|
+
const reply = await run.generate(DREAM_PROMPT, prompt, run.signal);
|
|
234
|
+
const ops = parseDreamOps(reply, run.claims, shown).map((op) => dispose(op, run.claims, run.dreamWrote));
|
|
235
|
+
return { ops, shown, chars: DREAM_PROMPT.length + prompt.length + reply.length };
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=memory-dream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-dream.js","sourceRoot":"","sources":["../../src/agent/memory-dream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAqCnD,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCA8BU,CAAC;AAEvC,MAAM,IAAI,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAErE,sFAAsF;AACtF,MAAM,UAAU,WAAW,CAAC,MAA8B,EAAE,KAA2B,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACvG,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACvC,MAAM,KAAK,GAAG;YACZ,QAAQ,KAAK,CAAC,IAAI,EAAE,EAAE,QAAQ,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,CAAC,KAAK,EAAE,EAAE,WAAW,KAAK,CAAC,OAAO,EAAE;YAClG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;YAC9D,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE;YAC1D,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE;YAClC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,iBAAiB,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;SAC5E,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,cAAc,KAAK,CAAC,EAAE,KAAK,KAAK,MAAM,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,oBAAoB,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;IAC9H,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACpC,MAAM,IAAI,GAAG;YACX,MAAM,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;YAC5E,cAAc,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE;YACtD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,KAAK,UAAU,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB;YACtG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;SACtD,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,SAAS,IAAI,MAAM,IAAI,CAAC,OAAO,OAAO,IAAI,CAAC,IAAI,WAAW,CAAC;IACpE,CAAC,CAAC,CAAC;IACH,OAAO;QACL,YAAY,IAAI,CAAC,GAAG,CAAC,GAAG;QACxB,EAAE;QACF,aAAa;QACb,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,QAAQ;QACpC,EAAE;QACF,+BAA+B;QAC/B,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,QAAQ;QACnC,EAAE;QACF,yCAAyC;KAC1C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,MAA8B,EAAE,KAA2B,EAAE,KAAK,GAAG,EAAE,EAAE,UAAU,GAAG,MAAM;IACtH,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC5C,MAAM,IAAI,GAAG,CAAC,IAA2B,EAAE,EAAE;QAC3C,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,IAAI,IAAI,KAAK;YAAE,OAAO;QACpF,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU;YAAE,OAAO;QAC1C,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/B,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;IAClK,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7G,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,SAAS,CAAC,IAAa;IAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,SAAS;QACtC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACvC,IAAI,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClF,IAAI,GAAG,CAAC,MAAM,IAAI,aAAa,CAAC,OAAO;YAAE,MAAM;IACjD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,KAAK,CAAC,KAA8B;IAC3C,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3H,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACzF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,aAAa,CAAC,eAAe,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9G,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACnH,CAAC;AAED,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,GAAW,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAEnJ;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,MAA8B,EAAE,KAA2B;IACtG,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/D,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,IAAI,KAAK;QAAE,OAAO,EAAE,CAAC;IAC5C,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;IAC3E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,SAAS;QAChD,MAAM,KAAK,GAAG,IAA+B,CAAC;QAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;YACvC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAgB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACjF,MAAM,KAAK,GAAG,CAAC,IAA2B,EAAqB,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClG,2DAA2D;QAC3D,MAAM,SAAS,GAAG,CAAC,KAAkB,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QAElG,IAAI,KAAK,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM;gBAAE,SAAS;YACrC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,CAAE,CAAC,KAAK,CAAC;YAC9C,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;gBAAE,SAAS;YAChC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QAC5D,CAAC;aAAM,IAAI,KAAK,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;gBAAE,SAAS;YACnF,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvB,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7L,CAAC;aAAM,IAAI,KAAK,CAAC,EAAE,KAAK,OAAO,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAgB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzH,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YAChD,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;gBAAE,SAAS;YACnF,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;gBAAE,SAAS;YAChF,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC/C,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QAC9I,CAAC;aAAM,IAAI,KAAK,CAAC,EAAE,KAAK,OAAO,IAAI,KAAK,CAAC,EAAE,KAAK,UAAU,EAAE,CAAC;YAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACvC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;gBAAE,SAAS;YACrF,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvB,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACnH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,MAAM,GAA2B,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;AAExE;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,EAAW,EAAE,MAA8B,EAAE,aAA0C,IAAI,GAAG,EAAE;IACtH,IAAI,EAAE,CAAC,EAAE,KAAK,OAAO;QAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAC1E,IAAI,EAAE,CAAC,EAAE,KAAK,UAAU;QAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;IAChF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAwB,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnG,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,EAAE,CAAC;QACzE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1F,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACrG,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC;IAC3D,CAAC;IACD,IAAI,EAAE,CAAC,EAAE,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;IAC5E,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAClE,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,IAAI,EAAE,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,EAAE,sBAAsB,EAAE,CAAC;QAC3F,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,EAAE,CAAC;IACpF,CAAC;IACD,2EAA2E;IAC3E,4EAA4E;IAC5E,gDAAgD;IAChD,IAAI,EAAE,CAAC,EAAE,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACrF,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,EAAE,kBAAkB,EAAE,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC;AAkBD,oDAAoD;AACpD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAa;IAC5C,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAChE,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnE,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;IACzG,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { DigestClaim } from "./memory-digest.ts";
|
|
2
|
+
import type { MemoryNote } from "./memory.ts";
|
|
3
|
+
/**
|
|
4
|
+
* What dreaming keeps on this machine, beside the notes and never in them.
|
|
5
|
+
*
|
|
6
|
+
* - `digests/<session>.jsonl`: the claims each conversation produced.
|
|
7
|
+
* - `cursors.json`: which messages of each conversation have been read.
|
|
8
|
+
* - `ledger/<scope>.jsonl`: runs, proposals and, later, applied changes.
|
|
9
|
+
* - `state.json`: the day's model budget and when each scope last dreamed.
|
|
10
|
+
*
|
|
11
|
+
* Machine-local like recall counts: none of it syncs, so another device sees
|
|
12
|
+
* a dreamed note but not why it was written. Nothing here is read by recall.
|
|
13
|
+
*/
|
|
14
|
+
export interface StoredClaim extends DigestClaim {
|
|
15
|
+
/** The project the conversation belonged to, for project-scope claims. */
|
|
16
|
+
project: string;
|
|
17
|
+
}
|
|
18
|
+
/** A claim as kept with a change, so the change can show its evidence after the claim is consumed. */
|
|
19
|
+
export interface EvidenceSnapshot {
|
|
20
|
+
id: string;
|
|
21
|
+
kind: string;
|
|
22
|
+
text: string;
|
|
23
|
+
quote?: string;
|
|
24
|
+
at: number;
|
|
25
|
+
}
|
|
26
|
+
/** A note as it was before a change, or null when the change created it. */
|
|
27
|
+
export interface NoteBefore {
|
|
28
|
+
id: string;
|
|
29
|
+
note: MemoryNote | null;
|
|
30
|
+
}
|
|
31
|
+
/** One change a dream wrote, enough to show it and to undo it. */
|
|
32
|
+
export interface AppliedChange {
|
|
33
|
+
id: string;
|
|
34
|
+
op: "create" | "update" | "merge";
|
|
35
|
+
summary: string;
|
|
36
|
+
before: NoteBefore[];
|
|
37
|
+
after: Array<{
|
|
38
|
+
id: string;
|
|
39
|
+
hash: string | null;
|
|
40
|
+
}>;
|
|
41
|
+
evidence: EvidenceSnapshot[];
|
|
42
|
+
/** Set when it came from a suggestion a person applied. */
|
|
43
|
+
fromProposal?: string;
|
|
44
|
+
/** The run that made it. */
|
|
45
|
+
run?: string;
|
|
46
|
+
}
|
|
47
|
+
/** One pass of dreaming over a project, for its history. */
|
|
48
|
+
export interface RunRecord {
|
|
49
|
+
id: string;
|
|
50
|
+
at: number;
|
|
51
|
+
trigger: "auto" | "manual";
|
|
52
|
+
seconds: number;
|
|
53
|
+
digested: number;
|
|
54
|
+
applied: number;
|
|
55
|
+
proposals: number;
|
|
56
|
+
/** Ids of the changes it applied. */
|
|
57
|
+
changes: string[];
|
|
58
|
+
/** As the provider reported them; input includes cached prompt tokens. */
|
|
59
|
+
tokens: {
|
|
60
|
+
input: number;
|
|
61
|
+
output: number;
|
|
62
|
+
};
|
|
63
|
+
costUsd: number;
|
|
64
|
+
model?: string;
|
|
65
|
+
outcome: "changed" | "suggested" | "nothing" | "no-call" | "refused" | "failed" | "budget";
|
|
66
|
+
errors: string[];
|
|
67
|
+
}
|
|
68
|
+
export type LedgerEvent = {
|
|
69
|
+
type: "preview";
|
|
70
|
+
at: number;
|
|
71
|
+
scope: string;
|
|
72
|
+
claims: number;
|
|
73
|
+
ops: unknown[];
|
|
74
|
+
chars: number;
|
|
75
|
+
} | {
|
|
76
|
+
type: "consumed";
|
|
77
|
+
at: number;
|
|
78
|
+
claims: string[];
|
|
79
|
+
} | {
|
|
80
|
+
type: "applied";
|
|
81
|
+
at: number;
|
|
82
|
+
scope: string;
|
|
83
|
+
changes: AppliedChange[];
|
|
84
|
+
} | {
|
|
85
|
+
type: "proposal";
|
|
86
|
+
at: number;
|
|
87
|
+
scope: string;
|
|
88
|
+
id: string;
|
|
89
|
+
op: unknown;
|
|
90
|
+
why?: string;
|
|
91
|
+
evidence: EvidenceSnapshot[];
|
|
92
|
+
} | {
|
|
93
|
+
type: "proposal-state";
|
|
94
|
+
at: number;
|
|
95
|
+
id: string;
|
|
96
|
+
state: "applied" | "dismissed" | "stale";
|
|
97
|
+
} | {
|
|
98
|
+
type: "undone";
|
|
99
|
+
at: number;
|
|
100
|
+
change: string;
|
|
101
|
+
} | {
|
|
102
|
+
type: "failed";
|
|
103
|
+
at: number;
|
|
104
|
+
scope: string;
|
|
105
|
+
error: string;
|
|
106
|
+
};
|
|
107
|
+
/** Today, in this machine's calendar. */
|
|
108
|
+
export declare function localDay(at?: number): string;
|
|
109
|
+
export declare class DreamStore {
|
|
110
|
+
private readonly fixedRoot?;
|
|
111
|
+
private writing;
|
|
112
|
+
constructor(root?: string);
|
|
113
|
+
/**
|
|
114
|
+
* Resolved on use, not at construction: the process's store is built when
|
|
115
|
+
* the module loads, before a test or fixture has pointed `OHARNESS_HOME`
|
|
116
|
+
* somewhere else, and fixing the path then would write into the real home.
|
|
117
|
+
*/
|
|
118
|
+
get root(): string;
|
|
119
|
+
/** Writes one at a time: two passes in one process never interleave a file. */
|
|
120
|
+
private serial;
|
|
121
|
+
private readJson;
|
|
122
|
+
private writeJson;
|
|
123
|
+
private readLines;
|
|
124
|
+
private append;
|
|
125
|
+
digested(session: string): Promise<Set<string>>;
|
|
126
|
+
/**
|
|
127
|
+
* Claims first, cursor after: a crash between the two reads the stretch
|
|
128
|
+
* again rather than losing it, and the claim ids it produces are the same,
|
|
129
|
+
* so `claims()` holds each once.
|
|
130
|
+
*/
|
|
131
|
+
recordDigest(session: string, project: string, claims: readonly DigestClaim[], keys: readonly string[]): Promise<void>;
|
|
132
|
+
/** A deleted conversation takes its claims and its cursor with it. */
|
|
133
|
+
dropSession(session: string): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Claims not yet consumed, for one scope: a project's (by its id) or the
|
|
136
|
+
* user's own. Oldest first, each id once.
|
|
137
|
+
*/
|
|
138
|
+
claims(scope: {
|
|
139
|
+
scope: "user";
|
|
140
|
+
} | {
|
|
141
|
+
scope: "project";
|
|
142
|
+
project: string;
|
|
143
|
+
}, ledgerKey: string): Promise<StoredClaim[]>;
|
|
144
|
+
ledger(key: string): Promise<LedgerEvent[]>;
|
|
145
|
+
record(key: string, event: LedgerEvent): Promise<void>;
|
|
146
|
+
/** Tokens spent on model calls today, as providers reported them. */
|
|
147
|
+
spentToday(now?: number): Promise<number>;
|
|
148
|
+
spend(tokens: number, now?: number): Promise<void>;
|
|
149
|
+
recordRun(project: string, run: RunRecord): Promise<void>;
|
|
150
|
+
/** A project's runs, newest first. */
|
|
151
|
+
runs(project: string, limit?: number): Promise<RunRecord[]>;
|
|
152
|
+
dreamedToday(key: string, now?: number): Promise<boolean>;
|
|
153
|
+
markDreamed(key: string, now?: number): Promise<void>;
|
|
154
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { appendFile, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { userPath } from "../paths.js";
|
|
5
|
+
import { renameWithRetry } from "../util/fs.js";
|
|
6
|
+
/** Today, in this machine's calendar. */
|
|
7
|
+
export function localDay(at = Date.now()) {
|
|
8
|
+
const d = new Date(at);
|
|
9
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
10
|
+
}
|
|
11
|
+
const fileKey = (value) => createHash("sha256").update(value).digest("hex").slice(0, 32);
|
|
12
|
+
const safeSession = (id) => /^[A-Za-z0-9_-]{1,128}$/.test(id) ? id : fileKey(id);
|
|
13
|
+
export class DreamStore {
|
|
14
|
+
fixedRoot;
|
|
15
|
+
writing = Promise.resolve();
|
|
16
|
+
constructor(root) { this.fixedRoot = root; }
|
|
17
|
+
/**
|
|
18
|
+
* Resolved on use, not at construction: the process's store is built when
|
|
19
|
+
* the module loads, before a test or fixture has pointed `OHARNESS_HOME`
|
|
20
|
+
* somewhere else, and fixing the path then would write into the real home.
|
|
21
|
+
*/
|
|
22
|
+
get root() { return this.fixedRoot ?? userPath("dreams"); }
|
|
23
|
+
/** Writes one at a time: two passes in one process never interleave a file. */
|
|
24
|
+
serial(work) {
|
|
25
|
+
const next = this.writing.then(work, work);
|
|
26
|
+
this.writing = next.catch(() => { });
|
|
27
|
+
return next;
|
|
28
|
+
}
|
|
29
|
+
async readJson(name, fallback) {
|
|
30
|
+
try {
|
|
31
|
+
return JSON.parse(await readFile(path.join(this.root, name), "utf8"));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return fallback;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async writeJson(name, data) {
|
|
38
|
+
const file = path.join(this.root, name);
|
|
39
|
+
await mkdir(path.dirname(file), { recursive: true });
|
|
40
|
+
const temp = `${file}.${randomUUID()}.tmp`;
|
|
41
|
+
try {
|
|
42
|
+
await writeFile(temp, JSON.stringify(data) + "\n", { mode: 0o600, flag: "wx" });
|
|
43
|
+
await renameWithRetry(temp, file);
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
await rm(temp, { force: true });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async readLines(name) {
|
|
50
|
+
let raw;
|
|
51
|
+
try {
|
|
52
|
+
raw = await readFile(path.join(this.root, name), "utf8");
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
const out = [];
|
|
58
|
+
for (const line of raw.split("\n")) {
|
|
59
|
+
if (!line.trim())
|
|
60
|
+
continue;
|
|
61
|
+
// A line cut short by a crash is skipped, not fatal.
|
|
62
|
+
try {
|
|
63
|
+
out.push(JSON.parse(line));
|
|
64
|
+
}
|
|
65
|
+
catch { /* skip */ }
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
async append(name, rows) {
|
|
70
|
+
if (!rows.length)
|
|
71
|
+
return;
|
|
72
|
+
const file = path.join(this.root, name);
|
|
73
|
+
await mkdir(path.dirname(file), { recursive: true });
|
|
74
|
+
await appendFile(file, rows.map((row) => JSON.stringify(row)).join("\n") + "\n", { mode: 0o600 });
|
|
75
|
+
}
|
|
76
|
+
// --- cursors ------------------------------------------------------------
|
|
77
|
+
async digested(session) {
|
|
78
|
+
const cursors = await this.readJson("cursors.json", { sessions: {} });
|
|
79
|
+
return new Set(cursors.sessions?.[session]?.keys ?? []);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Claims first, cursor after: a crash between the two reads the stretch
|
|
83
|
+
* again rather than losing it, and the claim ids it produces are the same,
|
|
84
|
+
* so `claims()` holds each once.
|
|
85
|
+
*/
|
|
86
|
+
async recordDigest(session, project, claims, keys) {
|
|
87
|
+
await this.serial(async () => {
|
|
88
|
+
await this.append(`digests/${safeSession(session)}.jsonl`, claims.map((claim) => ({ ...claim, project })));
|
|
89
|
+
const cursors = await this.readJson("cursors.json", { sessions: {} });
|
|
90
|
+
const held = new Set(cursors.sessions?.[session]?.keys ?? []);
|
|
91
|
+
for (const key of keys)
|
|
92
|
+
held.add(key);
|
|
93
|
+
cursors.sessions = { ...cursors.sessions, [session]: { keys: [...held], at: Date.now() } };
|
|
94
|
+
await this.writeJson("cursors.json", cursors);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/** A deleted conversation takes its claims and its cursor with it. */
|
|
98
|
+
async dropSession(session) {
|
|
99
|
+
await this.serial(async () => {
|
|
100
|
+
await rm(path.join(this.root, "digests", `${safeSession(session)}.jsonl`), { force: true });
|
|
101
|
+
const cursors = await this.readJson("cursors.json", { sessions: {} });
|
|
102
|
+
if (!cursors.sessions?.[session])
|
|
103
|
+
return;
|
|
104
|
+
delete cursors.sessions[session];
|
|
105
|
+
await this.writeJson("cursors.json", cursors);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// --- claims -------------------------------------------------------------
|
|
109
|
+
/**
|
|
110
|
+
* Claims not yet consumed, for one scope: a project's (by its id) or the
|
|
111
|
+
* user's own. Oldest first, each id once.
|
|
112
|
+
*/
|
|
113
|
+
async claims(scope, ledgerKey) {
|
|
114
|
+
let files;
|
|
115
|
+
try {
|
|
116
|
+
files = (await readdir(path.join(this.root, "digests"))).filter((name) => name.endsWith(".jsonl"));
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
files = [];
|
|
120
|
+
}
|
|
121
|
+
const consumed = new Set();
|
|
122
|
+
for (const event of await this.ledger(ledgerKey))
|
|
123
|
+
if (event.type === "consumed")
|
|
124
|
+
for (const id of event.claims)
|
|
125
|
+
consumed.add(id);
|
|
126
|
+
const byId = new Map();
|
|
127
|
+
for (const name of files) {
|
|
128
|
+
for (const claim of await this.readLines(`digests/${name}`)) {
|
|
129
|
+
if (!claim || typeof claim.id !== "string" || consumed.has(claim.id) || byId.has(claim.id))
|
|
130
|
+
continue;
|
|
131
|
+
if (claim.scope !== scope.scope)
|
|
132
|
+
continue;
|
|
133
|
+
if (scope.scope === "project" && claim.project !== scope.project)
|
|
134
|
+
continue;
|
|
135
|
+
byId.set(claim.id, claim);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return [...byId.values()].sort((a, b) => a.at - b.at);
|
|
139
|
+
}
|
|
140
|
+
// --- ledger -------------------------------------------------------------
|
|
141
|
+
async ledger(key) {
|
|
142
|
+
return this.readLines(`ledger/${fileKey(key)}.jsonl`);
|
|
143
|
+
}
|
|
144
|
+
async record(key, event) {
|
|
145
|
+
await this.serial(() => this.append(`ledger/${fileKey(key)}.jsonl`, [event]));
|
|
146
|
+
}
|
|
147
|
+
// --- budget and days ----------------------------------------------------
|
|
148
|
+
/** Tokens spent on model calls today, as providers reported them. */
|
|
149
|
+
async spentToday(now = Date.now()) {
|
|
150
|
+
const state = await this.readJson("state.json", {});
|
|
151
|
+
return state.day === localDay(now) ? state.tokens ?? 0 : 0;
|
|
152
|
+
}
|
|
153
|
+
async spend(tokens, now = Date.now()) {
|
|
154
|
+
await this.serial(async () => {
|
|
155
|
+
const { chars: _chars, ...state } = await this.readJson("state.json", {});
|
|
156
|
+
const day = localDay(now);
|
|
157
|
+
await this.writeJson("state.json", { ...state, day, tokens: (state.day === day ? state.tokens ?? 0 : 0) + tokens });
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// --- runs ---------------------------------------------------------------
|
|
161
|
+
async recordRun(project, run) {
|
|
162
|
+
await this.serial(() => this.append(`runs/${fileKey(project)}.jsonl`, [run]));
|
|
163
|
+
}
|
|
164
|
+
/** A project's runs, newest first. */
|
|
165
|
+
async runs(project, limit = 100) {
|
|
166
|
+
return (await this.readLines(`runs/${fileKey(project)}.jsonl`)).sort((a, b) => b.at - a.at).slice(0, limit);
|
|
167
|
+
}
|
|
168
|
+
async dreamedToday(key, now = Date.now()) {
|
|
169
|
+
const state = await this.readJson("state.json", {});
|
|
170
|
+
return state.dreamed?.[key] === localDay(now);
|
|
171
|
+
}
|
|
172
|
+
async markDreamed(key, now = Date.now()) {
|
|
173
|
+
await this.serial(async () => {
|
|
174
|
+
const state = await this.readJson("state.json", {});
|
|
175
|
+
await this.writeJson("state.json", { ...state, dreamed: { ...state.dreamed, [key]: localDay(now) } });
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=memory-ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-ledger.js","sourceRoot":"","sources":["../../src/agent/memory-ledger.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,11 +14,21 @@ export interface MemoryRecallInput {
|
|
|
14
14
|
context?: string;
|
|
15
15
|
/** Notes already attached in this session since the last compaction. */
|
|
16
16
|
exclude: ReadonlySet<string>;
|
|
17
|
+
/**
|
|
18
|
+
* The content hash each of those notes had when it was attached, where
|
|
19
|
+
* known. A note that has changed since is attached again, as updated, so a
|
|
20
|
+
* conversation resumed after a dream does not go on with the old text.
|
|
21
|
+
*/
|
|
22
|
+
shown?: ReadonlyMap<string, string>;
|
|
17
23
|
}
|
|
18
24
|
export interface MemoryRecallItem {
|
|
19
25
|
id: string;
|
|
20
26
|
summary: string;
|
|
21
27
|
scope?: MemoryScope;
|
|
28
|
+
/** Content hash as attached, recorded so a later change can be noticed. */
|
|
29
|
+
hash?: string;
|
|
30
|
+
/** Attached again because it changed since it was last shown. */
|
|
31
|
+
changed?: boolean;
|
|
22
32
|
}
|
|
23
33
|
export interface MemoryRecallResult {
|
|
24
34
|
/** Rendered block appended to the user message. */
|
|
@@ -70,4 +80,6 @@ export interface MemoryExtractionTarget {
|
|
|
70
80
|
export interface MemoryProvider {
|
|
71
81
|
recall(input: MemoryRecallInput): Promise<MemoryRecallResult | undefined>;
|
|
72
82
|
extraction?: MemoryExtractionTarget;
|
|
83
|
+
/** Changes made in the background since the last call (a dream), each told once. */
|
|
84
|
+
notices?(): Promise<ExtractedSummary[]>;
|
|
73
85
|
}
|