@corenel/harness 0.6.0 → 0.7.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.
Files changed (55) hide show
  1. package/dist/core/factFile.d.ts +14 -4
  2. package/dist/core/factFile.d.ts.map +1 -1
  3. package/dist/core/factFile.js +34 -13
  4. package/dist/core/factFile.js.map +1 -1
  5. package/dist/dag/executeNode.d.ts +4 -1
  6. package/dist/dag/executeNode.d.ts.map +1 -1
  7. package/dist/dag/executeNode.js +19 -5
  8. package/dist/dag/executeNode.js.map +1 -1
  9. package/dist/memory/bm25.d.ts +20 -0
  10. package/dist/memory/bm25.d.ts.map +1 -0
  11. package/dist/memory/bm25.js +73 -0
  12. package/dist/memory/bm25.js.map +1 -0
  13. package/dist/memory/manifest.d.ts +62 -0
  14. package/dist/memory/manifest.d.ts.map +1 -0
  15. package/dist/memory/manifest.js +54 -0
  16. package/dist/memory/manifest.js.map +1 -0
  17. package/dist/memory/store.d.ts +61 -0
  18. package/dist/memory/store.d.ts.map +1 -0
  19. package/dist/memory/store.js +386 -0
  20. package/dist/memory/store.js.map +1 -0
  21. package/dist/memory/tier.d.ts +38 -0
  22. package/dist/memory/tier.d.ts.map +1 -0
  23. package/dist/memory/tier.js +52 -0
  24. package/dist/memory/tier.js.map +1 -0
  25. package/dist/prompts/config.d.ts +52 -3
  26. package/dist/prompts/config.d.ts.map +1 -1
  27. package/dist/prompts/config.js +175 -16
  28. package/dist/prompts/config.js.map +1 -1
  29. package/dist/prompts/host.d.ts +19 -0
  30. package/dist/prompts/host.d.ts.map +1 -1
  31. package/dist/prompts/host.js.map +1 -1
  32. package/dist/prompts/library/defaults.generated.d.ts.map +1 -1
  33. package/dist/prompts/library/defaults.generated.js +16 -0
  34. package/dist/prompts/library/defaults.generated.js.map +1 -1
  35. package/dist/prompts/syncConfig.d.ts +52 -0
  36. package/dist/prompts/syncConfig.d.ts.map +1 -0
  37. package/dist/prompts/syncConfig.js +132 -0
  38. package/dist/prompts/syncConfig.js.map +1 -0
  39. package/dist/sidecar/host.d.ts +56 -2
  40. package/dist/sidecar/host.d.ts.map +1 -1
  41. package/dist/sidecar/host.js +152 -1
  42. package/dist/sidecar/host.js.map +1 -1
  43. package/dist/sidecar/server.d.ts +130 -1
  44. package/dist/sidecar/server.d.ts.map +1 -1
  45. package/dist/sidecar/server.js +205 -5
  46. package/dist/sidecar/server.js.map +1 -1
  47. package/dist/tools/builtins.d.ts +2 -0
  48. package/dist/tools/builtins.d.ts.map +1 -1
  49. package/dist/tools/builtins.js +63 -14
  50. package/dist/tools/builtins.js.map +1 -1
  51. package/dist/tools/namespaces.d.ts +22 -4
  52. package/dist/tools/namespaces.d.ts.map +1 -1
  53. package/dist/tools/namespaces.js +49 -8
  54. package/dist/tools/namespaces.js.map +1 -1
  55. package/package.json +2 -2
@@ -1,9 +1,16 @@
1
+ import { type MemoryType } from '@corenel/protocol';
2
+ export type { MemoryType };
3
+ /** A body longer than this is refused: one fact must not be able to consume a
4
+ * whole plane's core budget. */
5
+ export declare const BODY_CAP_CHARS = 2000;
1
6
  /** One remembered fact, as stored. */
2
7
  export interface Fact {
3
8
  slug: string;
4
9
  description: string;
10
+ type: MemoryType;
5
11
  tags: string[];
6
12
  createdAt: number;
13
+ updatedAt: number;
7
14
  text: string;
8
15
  /** The scope the model asked for when it saved. RECORDED, NOT ROUTED, for a
9
16
  * per-agent store — an agent's memory is its own folder, so there is nothing
@@ -14,11 +21,14 @@ export interface Fact {
14
21
  /** The index file an agent maintains for itself. Never listed as a fact. */
15
22
  export declare const FACT_INDEX = "MEMORY.md";
16
23
  /** Kebab slug from arbitrary text: lowercase, alphanumerics and dashes, trimmed,
17
- * capped. Empty input -> 'note'. Callers de-duplicate with uniqueSlug. */
24
+ * capped. Empty input -> 'note'.
25
+ *
26
+ * MUST be idempotent (slugify(slugify(x)) === slugify(x)) -- assertName in
27
+ * memory/store.ts rejects a name that doesn't survive a round-trip. The dash
28
+ * trim runs a SECOND time, after the length cap: cutting at 48 chars can land
29
+ * mid-run of separators (e.g. right on a word boundary), leaving a trailing
30
+ * dash that a bare `.slice()` before the trim would miss. */
18
31
  export declare function slugify(text: string): string;
19
- /** `base`, or `base-2`, `base-3` ... until one is free. A save must never
20
- * silently replace an unrelated memory (spec §3.2). */
21
- export declare function uniqueSlug(base: string, taken: ReadonlySet<string>): string;
22
32
  export declare function renderFact(f: Fact): string;
23
33
  export declare function parseFact(slug: string, raw: string): Fact;
24
34
  export declare function factIndexLine(f: Fact): string;
@@ -1 +1 @@
1
- {"version":3,"file":"factFile.d.ts","sourceRoot":"","sources":["../../core/factFile.ts"],"names":[],"mappings":"AAWA,sCAAsC;AACtC,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb;;;0EAGsE;IACtE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,4EAA4E;AAC5E,eAAO,MAAM,UAAU,cAAc,CAAC;AAEtC;0EAC0E;AAC1E,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED;uDACuD;AACvD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAK3E;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAM1C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAmBzD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAE7C"}
1
+ {"version":3,"file":"factFile.d.ts","sourceRoot":"","sources":["../../core/factFile.ts"],"names":[],"mappings":"AAWA,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAClE,YAAY,EAAE,UAAU,EAAE,CAAC;AAE3B;gCACgC;AAChC,eAAO,MAAM,cAAc,OAAO,CAAC;AAMnC,sCAAsC;AACtC,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb;;;0EAGsE;IACtE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,4EAA4E;AAC5E,eAAO,MAAM,UAAU,cAAc,CAAC;AAEtC;;;;;;;6DAO6D;AAC7D,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5C;AAUD,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAO1C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CA6BzD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAE7C"}
@@ -8,30 +8,41 @@
8
8
  * Lives in core/ beside budget.ts and pricing.ts: no imports, no DOM, no node —
9
9
  * the browser and the daemon both build providers on it.
10
10
  */
11
+ import { MEMORY_TYPES } from '@corenel/protocol';
12
+ /** A body longer than this is refused: one fact must not be able to consume a
13
+ * whole plane's core budget. */
14
+ export const BODY_CAP_CHARS = 2000;
15
+ function asType(raw) {
16
+ return MEMORY_TYPES.includes(raw) ? raw : null;
17
+ }
11
18
  /** The index file an agent maintains for itself. Never listed as a fact. */
12
19
  export const FACT_INDEX = 'MEMORY.md';
13
20
  /** Kebab slug from arbitrary text: lowercase, alphanumerics and dashes, trimmed,
14
- * capped. Empty input -> 'note'. Callers de-duplicate with uniqueSlug. */
21
+ * capped. Empty input -> 'note'.
22
+ *
23
+ * MUST be idempotent (slugify(slugify(x)) === slugify(x)) -- assertName in
24
+ * memory/store.ts rejects a name that doesn't survive a round-trip. The dash
25
+ * trim runs a SECOND time, after the length cap: cutting at 48 chars can land
26
+ * mid-run of separators (e.g. right on a word boundary), leaving a trailing
27
+ * dash that a bare `.slice()` before the trim would miss. */
15
28
  export function slugify(text) {
16
- const s = text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 48);
29
+ const s = text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 48).replace(/^-+|-+$/g, '');
17
30
  return s || 'note';
18
31
  }
19
- /** `base`, or `base-2`, `base-3` ... until one is free. A save must never
20
- * silently replace an unrelated memory (spec §3.2). */
21
- export function uniqueSlug(base, taken) {
22
- if (!taken.has(base))
23
- return base;
24
- let i = 2;
25
- while (taken.has(`${base}-${i}`))
26
- i++;
27
- return `${base}-${i}`;
32
+ /** Collapse CR/LF to a single space. `name` and `description` are interpolated
33
+ * directly into a frontmatter block; either one carrying a real newline could
34
+ * inject an extra frontmatter line (e.g. a forged `type:`) into the fact a
35
+ * model just asked to save. */
36
+ function oneLine(s) {
37
+ return s.replace(/[\r\n]+/g, ' ');
28
38
  }
29
39
  export function renderFact(f) {
30
40
  const tagList = f.tags.length ? `[${f.tags.join(', ')}]` : '[]';
31
41
  // The scope line is omitted when empty so this renders byte-identically to
32
42
  // what shared memory wrote before the extraction.
33
43
  const scopeLine = f.scope ? `scope: ${f.scope}\n` : '';
34
- return `---\nname: ${f.slug}\ndescription: ${f.description}\ntags: ${tagList}\ncreatedAt: ${f.createdAt}\n${scopeLine}---\n${f.text}\n`;
44
+ return `---\nname: ${oneLine(f.slug)}\ndescription: ${oneLine(f.description)}\ntype: ${f.type}\ntags: ${tagList}\n`
45
+ + `createdAt: ${f.createdAt}\nupdatedAt: ${f.updatedAt}\n${scopeLine}---\n${f.text}\n`;
35
46
  }
36
47
  export function parseFact(slug, raw) {
37
48
  const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(raw);
@@ -44,11 +55,21 @@ export function parseFact(slug, raw) {
44
55
  const description = field('description') || body.split('\n')[0] || slug;
45
56
  const tagsRaw = field('tags').replace(/^\[|\]$/g, '').trim();
46
57
  const tags = tagsRaw ? tagsRaw.split(',').map((t) => t.trim()).filter(Boolean) : [];
58
+ const createdAt = Number(field('createdAt')) || 0;
59
+ /* An old file has no `type`. Fall back to a tag that names one -- the only
60
+ * signal such a file carries -- and then to 'project', the safe default: it
61
+ * takes the lower tier weight, so a guess never pins a fact into core. */
62
+ const type = asType(field('type')) ?? tags.map(asType).find((t) => t !== null) ?? 'project';
63
+ /* No `updatedAt` means the file was never revised: it was last written when
64
+ * it was created. */
65
+ const updatedAt = Number(field('updatedAt')) || createdAt;
47
66
  return {
48
67
  slug,
49
68
  description,
69
+ type,
50
70
  tags,
51
- createdAt: Number(field('createdAt')) || 0,
71
+ createdAt,
72
+ updatedAt,
52
73
  text: body,
53
74
  scope: field('scope'),
54
75
  };
@@ -1 +1 @@
1
- {"version":3,"file":"factFile.js","sourceRoot":"","sources":["../../core/factFile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"factFile.js","sourceRoot":"","sources":["../../core/factFile.ts"],"names":[],"mappings":"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"}
@@ -25,7 +25,10 @@ export interface RunNodeDeps {
25
25
  /** Read-biased default tool set for a node with no explicit allowlist (§4). No
26
26
  * mutating tools, so a delegated node never writes unless its allowlist opts in. */
27
27
  export declare const READ_BIASED_TOOLS: string[];
28
- export declare const SUBAGENT_SYSTEM: string;
28
+ /** What a delegated sub-agent is told about its situation. It cannot see the
29
+ * parent conversation, so this is the whole of it. From the config workspace
30
+ * so a user can retune how delegation behaves. */
31
+ export declare const subagentSystem: () => Promise<string>;
29
32
  /** Resolve the node's effective tool list: allowlist (or read-biased default),
30
33
  * with spawn_* tools dropped when this context can't spawn (the depth cap). */
31
34
  export declare function resolveTools(all: AgentTool[], allow: string[] | undefined, ctx: ToolContext): AgentTool[];
@@ -1 +1 @@
1
- {"version":3,"file":"executeNode.d.ts","sourceRoot":"","sources":["../../dag/executeNode.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAIjC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EACV,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,EAC7D,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAC/C,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;CACjC;AAED;;0CAE0C;AAC1C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;oFACoF;AACpF,eAAO,MAAM,iBAAiB,UAI7B,CAAC;AAEF,eAAO,MAAM,eAAe,QAI6D,CAAC;AAE1F;+EAC+E;AAC/E,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,SAAS,EAAE,CAKzG;AAED;mFACmF;AACnF,wBAAsB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAWrG;AAED;gEACgE;AAChE,wBAAsB,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAiC5F;AAED;oEACoE;AACpE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,GAAG,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAExG"}
1
+ {"version":3,"file":"executeNode.d.ts","sourceRoot":"","sources":["../../dag/executeNode.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAIjC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EACV,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,EAC7D,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAC/C,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;CACjC;AAED;;0CAE0C;AAC1C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;oFACoF;AACpF,eAAO,MAAM,iBAAiB,UAI7B,CAAC;AAEF;;kDAEkD;AAClD,eAAO,MAAM,cAAc,QAAO,OAAO,CAAC,MAAM,CAAmD,CAAC;AAEpG;+EAC+E;AAC/E,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,SAAS,EAAE,CAKzG;AAED;mFACmF;AACnF,wBAAsB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAWrG;AAED;gEACgE;AAChE,wBAAsB,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAiC5F;AAED;oEACoE;AACpE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,GAAG,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAExG"}
@@ -1,3 +1,17 @@
1
+ /* DAG node executor — the executor layer of docs/SUBAGENT-DAG-CONTRACT.md.
2
+ *
3
+ * runNode() runs ONE graph node = one runAgent call with a FRESH message history
4
+ * (the isolation that keeps a node's work out of the rest of the graph's context
5
+ * windows). It composes the task (literal `task`, or a Nunjucks `promptTemplate`
6
+ * bound to upstream `inputs`, or a fan-in concat), resolves the node's tool
7
+ * allowlist (read-biased by default), runs the loop, and emits the node-tagged
8
+ * NodeEvent stream the canvas consumes.
9
+ *
10
+ * This is also the in-worker primitive behind the spawn_agent tool (Phase 1/2):
11
+ * the worker's makeSpawn wraps runNode. The shapes the canvas binds to
12
+ * (NodeOutput / NodeEvent) live in ./types and are REUSED here, not redefined;
13
+ * the executor-only shapes (NodeSpec / NodeRunRequest / deps) live here. */
14
+ import { compileConfigTemplate } from '../prompts/index.js';
1
15
  import { runAgent } from '../core/loop.js';
2
16
  import { compilePrompt } from '../promptCompiler.js';
3
17
  /** Read-biased default tool set for a node with no explicit allowlist (§4). No
@@ -7,10 +21,10 @@ export const READ_BIASED_TOOLS = [
7
21
  'read_file', 'list_files', 'search_files', 'stat_file',
8
22
  'recall_result', 'recall_memory', 'kv_get',
9
23
  ];
10
- export const SUBAGENT_SYSTEM = 'You are a focused Prompd sub-agent. A parent agent has delegated ONE ' +
11
- 'self-contained task to you. You do not see the parent conversation. Complete ' +
12
- 'only that task and return a concise, complete result the parent can use ' +
13
- 'directly. Prefer calling a tool over guessing. State the result plainly, no preamble.';
24
+ /** What a delegated sub-agent is told about its situation. It cannot see the
25
+ * parent conversation, so this is the whole of it. From the config workspace
26
+ * so a user can retune how delegation behaves. */
27
+ export const subagentSystem = () => compileConfigTemplate('agent/subagent.md', {});
14
28
  /** Resolve the node's effective tool list: allowlist (or read-biased default),
15
29
  * with spawn_* tools dropped when this context can't spawn (the depth cap). */
16
30
  export function resolveTools(all, allow, ctx) {
@@ -48,7 +62,7 @@ export async function runNode(req, deps) {
48
62
  const result = await runAgent({
49
63
  client: deps.client,
50
64
  model: node.model || deps.defaultModel,
51
- system: node.system || deps.defaultSystem || SUBAGENT_SYSTEM,
65
+ system: node.system || deps.defaultSystem || await subagentSystem(),
52
66
  messages,
53
67
  tools,
54
68
  toolCtx: deps.toolCtx,
@@ -1 +1 @@
1
- {"version":3,"file":"executeNode.js","sourceRoot":"","sources":["../../dag/executeNode.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"executeNode.js","sourceRoot":"","sources":["../../dag/executeNode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /** Lowercase, split on non-alphanumerics, drop stopwords and single characters. */
2
+ export declare function tokenize(text: string): string[];
3
+ /** The per-fact map the manifest stores: term -> count. */
4
+ export declare function termFrequencies(text: string): Record<string, number>;
5
+ export interface Bm25Doc {
6
+ id: string;
7
+ tf: Record<string, number>;
8
+ /** Total token count of the document (sum of tf values). */
9
+ length: number;
10
+ }
11
+ /**
12
+ * Rank `docs` against `query`, best first, dropping documents that match no
13
+ * query term at all. A zero-score document is not a weak answer, it is a
14
+ * non-answer: returning it would put unrelated memories in front of the model.
15
+ */
16
+ export declare function rankBm25(docs: Bm25Doc[], query: string, limit: number): {
17
+ id: string;
18
+ score: number;
19
+ }[];
20
+ //# sourceMappingURL=bm25.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bm25.d.ts","sourceRoot":"","sources":["../../memory/bm25.ts"],"names":[],"mappings":"AAyBA,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAK/C;AAED,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIpE;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CA4BvG"}
@@ -0,0 +1,73 @@
1
+ /* BM25 over pre-computed term frequencies.
2
+ *
3
+ * Pure, and deliberately free of every app type: it takes ids and frequency
4
+ * maps, so the store can rank without reading a single fact body. Term
5
+ * frequencies are computed once at write time and live in the manifest; the
6
+ * corpus statistics (document frequency, average length) are derived here on
7
+ * each call, which costs one pass over a few hundred small objects.
8
+ *
9
+ * Rewritten from the shape of Marshal's packages/harness/src/memory/bm25.ts;
10
+ * no code is shared because that module is node-flavoured and this one must run
11
+ * in a browser worker. */
12
+ const K1 = 1.2;
13
+ const B = 0.75;
14
+ /* Words that carry no signal in a short factual note. Kept small on purpose: a
15
+ * long stoplist starts eating real query terms (a memory about "the state dir"
16
+ * is about a state dir). */
17
+ const STOPWORDS = new Set([
18
+ 'a', 'an', 'and', 'are', 'as', 'at', 'be', 'but', 'by', 'do', 'for', 'from', 'how',
19
+ 'i', 'if', 'in', 'is', 'it', 'me', 'my', 'no', 'not', 'of', 'on', 'or', 'our', 'so',
20
+ 'that', 'the', 'their', 'then', 'there', 'they', 'this', 'to', 'was', 'we', 'were',
21
+ 'what', 'when', 'where', 'which', 'who', 'why', 'will', 'with', 'you', 'your',
22
+ ]);
23
+ /** Lowercase, split on non-alphanumerics, drop stopwords and single characters. */
24
+ export function tokenize(text) {
25
+ return (text || '')
26
+ .toLowerCase()
27
+ .split(/[^a-z0-9]+/)
28
+ .filter((t) => t.length > 1 && !STOPWORDS.has(t));
29
+ }
30
+ /** The per-fact map the manifest stores: term -> count. */
31
+ export function termFrequencies(text) {
32
+ const out = {};
33
+ for (const t of tokenize(text))
34
+ out[t] = (out[t] ?? 0) + 1;
35
+ return out;
36
+ }
37
+ /**
38
+ * Rank `docs` against `query`, best first, dropping documents that match no
39
+ * query term at all. A zero-score document is not a weak answer, it is a
40
+ * non-answer: returning it would put unrelated memories in front of the model.
41
+ */
42
+ export function rankBm25(docs, query, limit) {
43
+ const terms = tokenize(query);
44
+ if (!terms.length || !docs.length)
45
+ return [];
46
+ const n = docs.length;
47
+ const avgLen = docs.reduce((sum, d) => sum + d.length, 0) / n || 1;
48
+ const df = new Map();
49
+ for (const term of new Set(terms)) {
50
+ let count = 0;
51
+ for (const d of docs)
52
+ if (d.tf[term])
53
+ count += 1;
54
+ df.set(term, count);
55
+ }
56
+ const scored = [];
57
+ for (const d of docs) {
58
+ let score = 0;
59
+ for (const term of terms) {
60
+ const f = d.tf[term];
61
+ if (!f)
62
+ continue;
63
+ /* The +1 inside the log keeps idf non-negative: a term in EVERY document
64
+ * scores ~0 rather than going negative and actively penalising a match. */
65
+ const idf = Math.log(1 + (n - (df.get(term) ?? 0) + 0.5) / ((df.get(term) ?? 0) + 0.5));
66
+ score += idf * ((f * (K1 + 1)) / (f + K1 * (1 - B + (B * d.length) / avgLen)));
67
+ }
68
+ if (score > 0)
69
+ scored.push({ id: d.id, score });
70
+ }
71
+ return scored.sort((a, b) => b.score - a.score || a.id.localeCompare(b.id)).slice(0, limit);
72
+ }
73
+ //# sourceMappingURL=bm25.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bm25.js","sourceRoot":"","sources":["../../memory/bm25.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { MemoryType } from '../core/factFile';
2
+ import type { Tier } from './tier';
3
+ export declare const MANIFEST_FILE = "memory.json";
4
+ export declare const MANIFEST_VERSION = 1;
5
+ export interface ManifestEntry {
6
+ type: MemoryType;
7
+ /** Copy of the fact's description, so listing and rendering need no body reads. */
8
+ description: string;
9
+ /**
10
+ * CHEAP drift check: size and mtime as the directory listing reported them
11
+ * when this entry was indexed. A content hash would be exact, but obtaining
12
+ * one means READING every file -- precisely the cost this manifest exists to
13
+ * avoid. MemoryFileService (the browser's store) reports no mtime at all, so
14
+ * in the browser this is size alone.
15
+ */
16
+ sig: string;
17
+ /** EXACT check: hash of the body as last indexed. Verified only when a body is
18
+ * read for some other reason, which is what catches an edit that kept the
19
+ * same size. */
20
+ hash: string;
21
+ created: number;
22
+ updated: number;
23
+ tier: Tier;
24
+ recallCount: number;
25
+ lastRecalledAt?: number;
26
+ /** Term frequencies over name + description + body, computed at write time. */
27
+ tf: Record<string, number>;
28
+ /** Estimated prompt cost, from estimateFactTokens. */
29
+ tokens: number;
30
+ }
31
+ export interface Manifest {
32
+ version: number;
33
+ facts: Record<string, ManifestEntry>;
34
+ }
35
+ export declare function emptyManifest(): Manifest;
36
+ export declare function renderManifest(m: Manifest): string;
37
+ /** Never throws: a corrupt or future-versioned manifest reads as empty, and the
38
+ * store rebuilds it from the files that are actually there. */
39
+ export declare function parseManifest(raw: string): Manifest;
40
+ /** The listing-cheap signature. Empty mtime is normal in the browser. */
41
+ export declare function fileSignature(size: number, mtime?: number): string;
42
+ /** Stable 32-bit FNV-1a, hex. Same function the config workspace uses for its
43
+ * baselines -- cheap, sync, and only ever compared to itself. */
44
+ export declare function hashContent(s: string): string;
45
+ export interface ReconcilePlan {
46
+ /** Facts whose .md must be read and re-indexed (new, or changed size/mtime). */
47
+ reindex: string[];
48
+ /** Manifest entries whose .md is gone. */
49
+ drop: string[];
50
+ }
51
+ /**
52
+ * What the store must do to agree with the disk.
53
+ *
54
+ * The point is the NEGATIVE space: a fact whose hash matches is not re-read.
55
+ * With a few hundred facts on a sidecar, re-reading everything on every load is
56
+ * the difference between a usable store and a slow one.
57
+ */
58
+ export declare function planReconcile(m: Manifest, onDisk: {
59
+ name: string;
60
+ sig: string;
61
+ }[]): ReconcilePlan;
62
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../memory/manifest.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAC3C,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;oBAEgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACtC;AAED,wBAAgB,aAAa,IAAI,QAAQ,CAExC;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAElD;AAED;+DAC+D;AAC/D,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAQnD;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;iEACiE;AACjE,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI7C;AAED,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,aAAa,CASjG"}
@@ -0,0 +1,54 @@
1
+ export const MANIFEST_FILE = 'memory.json';
2
+ export const MANIFEST_VERSION = 1;
3
+ export function emptyManifest() {
4
+ return { version: MANIFEST_VERSION, facts: {} };
5
+ }
6
+ export function renderManifest(m) {
7
+ return JSON.stringify(m, null, 2);
8
+ }
9
+ /** Never throws: a corrupt or future-versioned manifest reads as empty, and the
10
+ * store rebuilds it from the files that are actually there. */
11
+ export function parseManifest(raw) {
12
+ try {
13
+ const j = JSON.parse(raw);
14
+ if (!j || j.version !== MANIFEST_VERSION || typeof j.facts !== 'object' || j.facts === null || Array.isArray(j.facts))
15
+ return emptyManifest();
16
+ return { version: MANIFEST_VERSION, facts: j.facts };
17
+ }
18
+ catch {
19
+ return emptyManifest();
20
+ }
21
+ }
22
+ /** The listing-cheap signature. Empty mtime is normal in the browser. */
23
+ export function fileSignature(size, mtime) {
24
+ return `${size}:${mtime ?? ''}`;
25
+ }
26
+ /** Stable 32-bit FNV-1a, hex. Same function the config workspace uses for its
27
+ * baselines -- cheap, sync, and only ever compared to itself. */
28
+ export function hashContent(s) {
29
+ let h = 0x811c9dc5;
30
+ for (let i = 0; i < s.length; i++) {
31
+ h ^= s.charCodeAt(i);
32
+ h = Math.imul(h, 0x01000193);
33
+ }
34
+ return (h >>> 0).toString(16);
35
+ }
36
+ /**
37
+ * What the store must do to agree with the disk.
38
+ *
39
+ * The point is the NEGATIVE space: a fact whose hash matches is not re-read.
40
+ * With a few hundred facts on a sidecar, re-reading everything on every load is
41
+ * the difference between a usable store and a slow one.
42
+ */
43
+ export function planReconcile(m, onDisk) {
44
+ const reindex = [];
45
+ const seen = new Set();
46
+ for (const f of onDisk) {
47
+ seen.add(f.name);
48
+ if (m.facts[f.name]?.sig !== f.sig)
49
+ reindex.push(f.name);
50
+ }
51
+ const drop = Object.keys(m.facts).filter((name) => !seen.has(name));
52
+ return { reindex, drop };
53
+ }
54
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../memory/manifest.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;AAC3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAkClC,MAAM,UAAU,aAAa;IAC3B,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAW;IACxC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACpC,CAAC;AAED;+DAC+D;AAC/D,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAC;QAC/C,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,gBAAgB,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;YAAE,OAAO,aAAa,EAAE,CAAC;QAC9I,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,CAAC,KAAsC,EAAE,CAAC;IACxF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,aAAa,EAAE,CAAC;IACzB,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,KAAc;IACxD,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;AAClC,CAAC;AAED;iEACiE;AACjE,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,CAAC,GAAG,UAAU,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAAC,CAAC;IAC1F,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChC,CAAC;AASD;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,CAAW,EAAE,MAAuC;IAChF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { type FileService } from '@corenel/protocol';
2
+ import { type MemoryType } from '../core/factFile';
3
+ import { type Tier } from './tier';
4
+ export interface StoredFact {
5
+ name: string;
6
+ type: MemoryType;
7
+ description: string;
8
+ body: string;
9
+ created: number;
10
+ updated: number;
11
+ tier: Tier;
12
+ /** The BM25 score this fact matched a query with. Set only by `recall()` --
13
+ * `read()`, `list()` and `core()` don't rank against a query, so they leave
14
+ * it undefined. A cross-plane caller (the app's router) needs this to merge
15
+ * two planes' hits by relevance rather than by which plane happened to be
16
+ * asked first. */
17
+ score?: number;
18
+ }
19
+ export interface SaveInput {
20
+ name: string;
21
+ type: MemoryType;
22
+ description: string;
23
+ body: string;
24
+ }
25
+ export interface CoreBlock {
26
+ facts: StoredFact[];
27
+ archivedCount: number;
28
+ }
29
+ export interface RankedCandidate {
30
+ name: string;
31
+ score: number;
32
+ }
33
+ export interface FactStore {
34
+ save(input: SaveInput): Promise<StoredFact>;
35
+ read(name: string): Promise<StoredFact | null>;
36
+ recall(query: string, limit?: number): Promise<StoredFact[]>;
37
+ /**
38
+ * Rank facts against a query WITHOUT marking any of them recalled -- a pure
39
+ * read, like core(). For a caller that will merge candidates across several
40
+ * stores before deciding what the model actually sees (fileMemory.ts's
41
+ * cross-plane recall), ranking every plane's candidates first and marking
42
+ * only the final winners (via hydrateRecalled) is the only way a fact that
43
+ * gets sliced away in that merge is not still recorded as used.
44
+ */
45
+ rankCandidates(query: string, limit?: number): Promise<RankedCandidate[]>;
46
+ /**
47
+ * Load bodies for exactly these names and record a recall against each --
48
+ * the "used" half of recall(), split out so a caller can apply it only to
49
+ * the facts it actually returns. Names not in the manifest are skipped.
50
+ */
51
+ hydrateRecalled(names: string[]): Promise<StoredFact[]>;
52
+ list(limit?: number): Promise<StoredFact[]>;
53
+ forget(name: string): Promise<void>;
54
+ /** Core facts plus how many are archived -- everything injection needs, and
55
+ * nothing it could write with. */
56
+ core(): Promise<CoreBlock>;
57
+ }
58
+ type GetFiles = () => FileService | null | Promise<FileService | null>;
59
+ export declare function makeFactStore(getFiles: GetFiles, root: string): FactStore;
60
+ export {};
61
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../memory/store.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EACuD,KAAK,UAAU,EAC5E,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAoC,KAAK,IAAI,EAAE,MAAM,QAAQ,CAAC;AAgBrE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX;;;;sBAIkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAEhE,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAC/C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC7D;;;;;;;OAOG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC1E;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC5C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC;sCACkC;IAClC,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC;CAC5B;AAED,KAAK,QAAQ,GAAG,MAAM,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAqBvE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAgVzE"}