memhtml 0.2.2 → 0.2.3
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 +10 -6
- package/agent/channels/eve.ts +1 -1
- package/dist/{dist-DBdR0zt7.mjs → dist-Dj-MYf9q.mjs} +1 -1
- package/dist/{dist-0IU3R2cD.mjs → dist-dfrcDFad.mjs} +38 -38
- package/dist/dist-dfrcDFad.mjs.map +1 -0
- package/dist/{dist-CI2-0MRk.mjs → dist-t84Q_98w.mjs} +6 -6
- package/dist/dist-t84Q_98w.mjs.map +1 -0
- package/dist/memhtml-mcp.mjs +16 -16
- package/dist/memhtml-mcp.mjs.map +1 -1
- package/dist/memhtml.mjs +19 -19
- package/dist/memhtml.mjs.map +1 -1
- package/package.json +1 -1
- package/src/agent-build.ts +1 -1
- package/src/client.ts +2 -2
- package/src/contract.ts +2 -2
- package/src/mount.ts +1 -1
- package/dist/dist-0IU3R2cD.mjs.map +0 -1
- package/dist/dist-CI2-0MRk.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -410,7 +410,7 @@ envelope. `docs/code-mode.md` is the cookbook, with a measured helper and five r
|
|
|
410
410
|
| MemoryAgentBench FactConsolidation single-hop (26KB to 1.1MB stores) | 92% to 97% | ~60% at 26KB only |
|
|
411
411
|
| MemoryAgentBench FactConsolidation multi-hop | 37% to 49% | ≤7% all methods |
|
|
412
412
|
| BEAM Contradiction Resolution (100K split, 40 probes) | 43.8% mean | 0% to 5% all systems |
|
|
413
|
-
| LongMemEval-S (
|
|
413
|
+
| LongMemEval-S (full 500, judged 2026-08-07) | 67.0% | ~55% to 65% typical agent baselines |
|
|
414
414
|
|
|
415
415
|
Read the cross-judge numbers as reference points rather than as a ranking: the judges here are verbatim
|
|
416
416
|
prompt ports running haiku-4.5, where the papers used gpt-4o and gpt-4.1-mini. `ROADMAP.md` carries these
|
|
@@ -422,7 +422,7 @@ numbers and the horizons they rank.
|
|
|
422
422
|
$MEMHTML_ROOT/ # its own git repo, one global memory store
|
|
423
423
|
projects/<workspace-slug>/ # a workspace IS a directory. There is no workspaces table.
|
|
424
424
|
areas/<area-slug>/ # ongoing responsibilities
|
|
425
|
-
areas/arcs/ #
|
|
425
|
+
areas/arcs/ # behavioral arcs (system-written by sleep only)
|
|
426
426
|
areas/inbox/ # where an unplaceable memory lands
|
|
427
427
|
resources/<topic>/
|
|
428
428
|
resources/people/<person>.html # the person plane
|
|
@@ -441,10 +441,12 @@ The layering is strict and TypeScript project references enforce it. `@memhtml/c
|
|
|
441
441
|
`@memhtml/domain` import `effect` and nothing else, and a test reads `domain`'s own `dist` to confirm it
|
|
442
442
|
names no database driver, no SDK, and no `node:fs`.
|
|
443
443
|
|
|
444
|
-
None of them is published.
|
|
445
|
-
the
|
|
446
|
-
|
|
447
|
-
|
|
444
|
+
None of them is published. Every workspace package is `private`, and `mise run package:assemble`
|
|
445
|
+
bundles the libraries and the binary-bearing apps into the single `memhtml` package that carries the
|
|
446
|
+
two binaries — the docs site and the integration-test harness stay outside the bundle
|
|
447
|
+
(`tsdown.config.ts` names the exact set). The table below is a map of the source, not a list of
|
|
448
|
+
things to install. `RELEASING.md` covers how the artifact is built and what must stay outside the
|
|
449
|
+
bundle.
|
|
448
450
|
|
|
449
451
|
| Package | What it owns |
|
|
450
452
|
|---|---|
|
|
@@ -459,6 +461,8 @@ outside the bundle.
|
|
|
459
461
|
| `@memhtml/eval` | The fixture corpus generator and the refusable discrimination gate. |
|
|
460
462
|
| `@memhtml/cli` | The `memhtml` binary, the envelope contract, and the one composition root. |
|
|
461
463
|
| `@memhtml/mcp` | The `memhtml-mcp` stdio server: 14 tools, 2 resources. |
|
|
464
|
+
| `@memhtml/consolidator` | The sandboxed eve agent that distills candidate memories from raw transcripts. |
|
|
465
|
+
| `@memhtml/docs` | The documentation site. |
|
|
462
466
|
|
|
463
467
|
## Development
|
|
464
468
|
|
package/agent/channels/eve.ts
CHANGED
|
@@ -35,7 +35,7 @@ import { runVerifierConfig } from "../../src/run-auth.js"
|
|
|
35
35
|
* and eve rejects a token with no `sub` before consulting any matcher. That is what keeps a secret
|
|
36
36
|
* leaked into some other eve app's environment from cross-authenticating here.
|
|
37
37
|
*
|
|
38
|
-
* ## The bind address STAYS, as
|
|
38
|
+
* ## The bind address STAYS, as defense in depth
|
|
39
39
|
*
|
|
40
40
|
* `eve start` binds ALL INTERFACES by default (node_modules/eve/docs/reference/cli.md, `eve start
|
|
41
41
|
* --host`), so `src/client.ts` still spawns with `--host 127.0.0.1` from a constant that takes no
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as MAX_QUOTE_CHARS, C as ConsolidationResult, D as ConsolidatorUnavailable, E as ConsolidatorRunFailed, F as toJsonSchema, I as ungroundedEvidenceReason, M as credentialsMissingReason, N as hasConsolidatorCredentials, O as MAX_CLAIM_CHARS, P as isConsolidationKind, S as ConsolidationPayload, T as ConsolidatorCredentialsMissing, _ as readOnlyRootsProblem, a as RUN_SECRET_ENV, b as CandidateEvidence, c as runVerifierConfig, d as SANDBOX_MOUNTS_ENV, f as SandboxMountInvalid, g as pinCorpusSnapshot, h as mountReadOnlyRoots, i as makeConsolidator, j as MAX_TRANSCRIPTS_PER_RUN, k as MAX_GIST_CHARS, l as sameRunSecret, m as encodeSandboxMounts, n as consolidatorLive, o as mintRunSecret, p as decodeSandboxMounts, r as guestPathFor, s as runSecretFrom, t as Consolidator, u as signRunToken, v as CONSOLIDATION_KINDS, w as ConsolidatorContractViolation, x as CandidateMemory, y as CONSOLIDATION_OUTPUT_JSON_SCHEMA } from "./dist-
|
|
1
|
+
import { A as MAX_QUOTE_CHARS, C as ConsolidationResult, D as ConsolidatorUnavailable, E as ConsolidatorRunFailed, F as toJsonSchema, I as ungroundedEvidenceReason, M as credentialsMissingReason, N as hasConsolidatorCredentials, O as MAX_CLAIM_CHARS, P as isConsolidationKind, S as ConsolidationPayload, T as ConsolidatorCredentialsMissing, _ as readOnlyRootsProblem, a as RUN_SECRET_ENV, b as CandidateEvidence, c as runVerifierConfig, d as SANDBOX_MOUNTS_ENV, f as SandboxMountInvalid, g as pinCorpusSnapshot, h as mountReadOnlyRoots, i as makeConsolidator, j as MAX_TRANSCRIPTS_PER_RUN, k as MAX_GIST_CHARS, l as sameRunSecret, m as encodeSandboxMounts, n as consolidatorLive, o as mintRunSecret, p as decodeSandboxMounts, r as guestPathFor, s as runSecretFrom, t as Consolidator, u as signRunToken, v as CONSOLIDATION_KINDS, w as ConsolidatorContractViolation, x as CandidateMemory, y as CONSOLIDATION_OUTPUT_JSON_SCHEMA } from "./dist-t84Q_98w.mjs";
|
|
2
2
|
|
|
3
3
|
export { CONSOLIDATION_KINDS, CONSOLIDATION_OUTPUT_JSON_SCHEMA, CandidateEvidence, CandidateMemory, ConsolidationPayload, ConsolidationResult, Consolidator, ConsolidatorContractViolation, ConsolidatorCredentialsMissing, ConsolidatorRunFailed, ConsolidatorUnavailable, MAX_CLAIM_CHARS, MAX_GIST_CHARS, MAX_QUOTE_CHARS, MAX_TRANSCRIPTS_PER_RUN, RUN_SECRET_ENV, SANDBOX_MOUNTS_ENV, SandboxMountInvalid, consolidatorLive, credentialsMissingReason, decodeSandboxMounts, encodeSandboxMounts, guestPathFor, hasConsolidatorCredentials, isConsolidationKind, makeConsolidator, mintRunSecret, mountReadOnlyRoots, pinCorpusSnapshot, readOnlyRootsProblem, runSecretFrom, runVerifierConfig, sameRunSecret, signRunToken, toJsonSchema, ungroundedEvidenceReason };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as MEMORY_EXTENSION, B as ModelUnavailable, Ct as slugify, H as StorageFailure, J as relClassFor, L as DirtyTree, Q as INBOX_DIR, R as InvalidMemory, St as filenameFor, U as WriteConflict, V as PathNotFound, W as EdgeRel, X as relTokenFor, Y as relForToken, Z as ARCS_DIR, _t as TaskStatus, at as memoryPathFor, bt as parseEntity, ct as placementFor, dt as MEMORY_TYPES, et as PEOPLE_DIR, ft as MemoryStatus, gt as TASK_STATUSES, ht as PERSON_ENTITY_PREFIX, it as isValidMemoryPath, lt as Confidence, mt as PARA_BUCKETS, nt as archivePathFor, ot as normalizePath, pt as MemoryType, q as isEdgeRel, rt as isArchivePath, st as paraBucketOf, ut as Importance, vt as WRITABLE_MEMORY_TYPES, wt as withCollisionOrdinal, xt as SLUG_FALLBACK, yt as isTaskStatus, z as LlmContractViolation } from "./dist-
|
|
1
|
+
import { $ as MEMORY_EXTENSION, B as ModelUnavailable, Ct as slugify, H as StorageFailure, J as relClassFor, L as DirtyTree, Q as INBOX_DIR, R as InvalidMemory, St as filenameFor, U as WriteConflict, V as PathNotFound, W as EdgeRel, X as relTokenFor, Y as relForToken, Z as ARCS_DIR, _t as TaskStatus, at as memoryPathFor, bt as parseEntity, ct as placementFor, dt as MEMORY_TYPES, et as PEOPLE_DIR, ft as MemoryStatus, gt as TASK_STATUSES, ht as PERSON_ENTITY_PREFIX, it as isValidMemoryPath, lt as Confidence, mt as PARA_BUCKETS, nt as archivePathFor, ot as normalizePath, pt as MemoryType, q as isEdgeRel, rt as isArchivePath, st as paraBucketOf, ut as Importance, vt as WRITABLE_MEMORY_TYPES, wt as withCollisionOrdinal, xt as SLUG_FALLBACK, yt as isTaskStatus, z as LlmContractViolation } from "./dist-t84Q_98w.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { Config, Context, Effect, Layer, Result, Schedule, Schema } from "effect";
|
|
4
4
|
import { mkdir, mkdtemp, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -327,7 +327,7 @@ const pagerank = (nodes, edges, options = {}) => {
|
|
|
327
327
|
* Communities by label propagation over the edge list read as undirected.
|
|
328
328
|
*
|
|
329
329
|
* Deterministic in place of a seed: nodes start labelled by themselves, sweeps visit them in
|
|
330
|
-
* sorted order, and a node adopts the highest-weighted
|
|
330
|
+
* sorted order, and a node adopts the highest-weighted neighboring label with the
|
|
331
331
|
* lexicographically smallest label breaking a tie. The returned labels are canonicalized to
|
|
332
332
|
* the smallest member path of each community, so the partition itself is reproducible and not
|
|
333
333
|
* only the grouping.
|
|
@@ -340,15 +340,15 @@ const labelPropagation = (nodes, edges, options = {}) => {
|
|
|
340
340
|
const { sorted, folded } = normalize$1(nodes, edges);
|
|
341
341
|
const minSize = options.minCommunitySize ?? 3;
|
|
342
342
|
const maxSweeps = options.maxSweeps ?? 100;
|
|
343
|
-
const
|
|
343
|
+
const neighbors = /* @__PURE__ */ new Map();
|
|
344
344
|
const link = (from, to, strength) => {
|
|
345
|
-
const bucket =
|
|
345
|
+
const bucket = neighbors.get(from);
|
|
346
346
|
const edge = {
|
|
347
347
|
src: from,
|
|
348
348
|
dst: to,
|
|
349
349
|
strength
|
|
350
350
|
};
|
|
351
|
-
if (bucket === void 0)
|
|
351
|
+
if (bucket === void 0) neighbors.set(from, [edge]);
|
|
352
352
|
else bucket.push(edge);
|
|
353
353
|
};
|
|
354
354
|
for (const edge of folded) {
|
|
@@ -360,7 +360,7 @@ const labelPropagation = (nodes, edges, options = {}) => {
|
|
|
360
360
|
let changed = false;
|
|
361
361
|
for (const node of sorted) {
|
|
362
362
|
const weightByLabel = /* @__PURE__ */ new Map();
|
|
363
|
-
for (const edge of
|
|
363
|
+
for (const edge of neighbors.get(node) ?? []) {
|
|
364
364
|
const label = labels.get(edge.dst);
|
|
365
365
|
if (label === void 0) continue;
|
|
366
366
|
weightByLabel.set(label, (weightByLabel.get(label) ?? 0) + edge.strength);
|
|
@@ -1874,7 +1874,7 @@ const buildProbes = (base, wanted) => {
|
|
|
1874
1874
|
* the cosine. Measured before this was fixed: the kit-free control took FTS rank 1 and vector
|
|
1875
1875
|
* rank 3 while its target sat at 4 and 10, on 22 of 36 probes. The gate was failing on
|
|
1876
1876
|
* document length instead of on the fact. A control that wins by being terser proves nothing
|
|
1877
|
-
* about discrimination, and a fold that "fixed" it would be tuned against an
|
|
1877
|
+
* about discrimination, and a fold that "fixed" it would be tuned against an artifact.
|
|
1878
1878
|
*
|
|
1879
1879
|
* With the kit copied, the pair differs by exactly the flipped token, which is the
|
|
1880
1880
|
* high-cosine wrong-fact adversary design §5 asks for.
|
|
@@ -1956,7 +1956,7 @@ const ACCESSED_FRACTION = .6;
|
|
|
1956
1956
|
* happens to be some probe's control.
|
|
1957
1957
|
* 2. **The spread is QUERY-BLIND.** It is a function of the corpus seed and the path order. Nothing
|
|
1958
1958
|
* here reads the probe list, so a target's history is whatever its position in the corpus earns it.
|
|
1959
|
-
* A spread that
|
|
1959
|
+
* A spread that favored targets would make the gate pass by construction.
|
|
1960
1960
|
*
|
|
1961
1961
|
* The distribution is a long tail, `1 / (floor + jitter)`, because that is the shape retrieval traffic
|
|
1962
1962
|
* has: a handful of memories are read constantly and most are read once. A uniform count would make
|
|
@@ -4303,7 +4303,7 @@ const text = (result) => result.stdout.toString("utf8");
|
|
|
4303
4303
|
/**
|
|
4304
4304
|
* The service against a repository root. Exported rather than only wrapped in a layer, because every
|
|
4305
4305
|
* test in this package drives the real git binary against a temp-dir repo. A fake git
|
|
4306
|
-
* verifies the shape of these calls and not git's own
|
|
4306
|
+
* verifies the shape of these calls and not git's own behavior, and it is git's behavior
|
|
4307
4307
|
* (rename detection, index staging, merge conflict stages) that this package exists to use.
|
|
4308
4308
|
*/
|
|
4309
4309
|
const makeGit = (root) => ({
|
|
@@ -4661,7 +4661,7 @@ const subjectFor = (pending) => pending.length === 1 && pending[0] !== void 0 ?
|
|
|
4661
4661
|
const hasProvenance = (entry) => Object.keys(provenanceTrailers(entry.input)).length > 0;
|
|
4662
4662
|
/**
|
|
4663
4663
|
* The store over a git service. Exported so tests build it against a temp-dir repo with the
|
|
4664
|
-
* real git binary. This package's job IS git's
|
|
4664
|
+
* real git binary. This package's job IS git's behavior, so a fake git would verify only that
|
|
4665
4665
|
* the right strings were assembled and would miss every state transition that matters.
|
|
4666
4666
|
*/
|
|
4667
4667
|
const makeStore = (git, hooks = {}) => {
|
|
@@ -5999,7 +5999,7 @@ const IndexGit = Context.Service("memhtml/IndexGit");
|
|
|
5999
5999
|
* `onExcessProperty: "error"` means a column added to the SELECT without being added here is a
|
|
6000
6000
|
* decode failure, not a silently ignored field. Probed 2026-08-12 on node 24.19.0: `node:sqlite`
|
|
6001
6001
|
* hands back null-prototype records and `Schema.decodeUnknownEffect` reads them correctly, so the
|
|
6002
|
-
* driver's row objects need no
|
|
6002
|
+
* driver's row objects need no normalization at this seam.
|
|
6003
6003
|
*/
|
|
6004
6004
|
/**
|
|
6005
6005
|
* Every column of `index_state`, in the order `0007_watermark.sql` declares them.
|
|
@@ -7264,7 +7264,7 @@ const assembleScope = (scope = {}) => {
|
|
|
7264
7264
|
const types = (scope.memoryTypes ?? []).filter((type) => MEMORY_TYPES.includes(type));
|
|
7265
7265
|
if (types.length > 0)
|
|
7266
7266
|
/**
|
|
7267
|
-
* A caller-named type list is
|
|
7267
|
+
* A caller-named type list is honored VERBATIM, `task` included. Filtering `task` back out of
|
|
7268
7268
|
* an explicit list would make the opt-in unreachable, and there would then be no way to search
|
|
7269
7269
|
* tasks at all. The exclusion is a default and not a firewall. (The firewalls in this system are
|
|
7270
7270
|
* `edge_class` and the trace tables, and both reject a write rather than defaulting.)
|
|
@@ -7860,7 +7860,7 @@ const modelFailure = (modelId, cause) => ModelUnavailable.make({
|
|
|
7860
7860
|
* One InvokeModel round trip: send the body, decode the JSON payload. Both the transport
|
|
7861
7861
|
* rejection and an unparseable payload land on `ModelUnavailable`, because neither one
|
|
7862
7862
|
* says anything about the model's answer. They say only that no answer arrived. Reading
|
|
7863
|
-
* the answer, and judging whether it
|
|
7863
|
+
* the answer, and judging whether it honors its contract, is the caller's job.
|
|
7864
7864
|
*/
|
|
7865
7865
|
const invokeJson = (client, modelId, body) => Effect.gen(function* () {
|
|
7866
7866
|
const response = yield* Effect.tryPromise({
|
|
@@ -8928,7 +8928,7 @@ const ArcPlanEntry = Schema.Struct({
|
|
|
8928
8928
|
* slug would be a model-chosen file path.
|
|
8929
8929
|
*/
|
|
8930
8930
|
slug: Schema.String,
|
|
8931
|
-
/** A concise
|
|
8931
|
+
/** A concise behavioral-principal name, 3-8 words. */
|
|
8932
8932
|
title: Schema.String,
|
|
8933
8933
|
action: ArcAction,
|
|
8934
8934
|
/** One or two sentences naming what changed or emerged. */
|
|
@@ -8973,34 +8973,34 @@ memory, so when the two claims COULD both be true — different scope, different
|
|
|
8973
8973
|
aspect — answer neutral, not contradicts. Rate your confidence honestly and name the specific
|
|
8974
8974
|
conflicting or compatible claims in the rationale.`;
|
|
8975
8975
|
/** The arc-triage system prompt: plan only, no content. */
|
|
8976
|
-
const ARC_TRIAGE_SYSTEM = `You triage
|
|
8976
|
+
const ARC_TRIAGE_SYSTEM = `You triage behavioral arcs for an AI agent's long-term memory system. This is the planning pass:
|
|
8977
8977
|
a second pass writes each arc's content, so your output is only the plan.
|
|
8978
8978
|
|
|
8979
8979
|
- Assign every existing arc an action of update or skip. An arc omitted from the plan stays stale.
|
|
8980
|
-
- Propose create only when a genuinely new
|
|
8980
|
+
- Propose create only when a genuinely new behavioral pattern emerges that no existing arc covers.
|
|
8981
8981
|
- Propose update only when the evidence materially changes or reinforces the arc. Each update costs
|
|
8982
8982
|
a model call, so skip trivial or redundant evidence.
|
|
8983
8983
|
- Keep evidenceKeys to the strongest 1-5 supporting memories per arc.
|
|
8984
|
-
- Titles are concise
|
|
8984
|
+
- Titles are concise behavioral-principal names of 3-8 words.
|
|
8985
8985
|
- Rationale is one or two sentences naming what changed or emerged.
|
|
8986
8986
|
- Leave slug empty on a create.`;
|
|
8987
8987
|
/** The arc-execute system prompt: one arc's content. */
|
|
8988
|
-
const ARC_EXECUTE_SYSTEM = `You write one
|
|
8989
|
-
|
|
8988
|
+
const ARC_EXECUTE_SYSTEM = `You write one behavioral arc for an AI agent's long-term memory system. An arc is a self-contained
|
|
8989
|
+
behavioral principal — a statement of a pattern, preference, or principle the agent developed
|
|
8990
8990
|
through experience. Arcs are read back in future sessions with no transcript context, so the
|
|
8991
8991
|
content must stand alone.
|
|
8992
8992
|
|
|
8993
|
-
- claim is the ONE load-bearing sentence: the principle itself, stated as
|
|
8994
|
-
- paragraphs holds 2-12 sentences across one to four paragraphs.
|
|
8993
|
+
- claim is the ONE load-bearing sentence: the principle itself, stated as behavior to adopt.
|
|
8994
|
+
- paragraphs holds 2-12 sentences across one to four paragraphs. Behavioral principles fit at the
|
|
8995
8995
|
tight end; an operational playbook may span the wider range.
|
|
8996
|
-
- Use IF/THEN conditional phrasing for rules, framed positively around the
|
|
8996
|
+
- Use IF/THEN conditional phrasing for rules, framed positively around the behavior to adopt.
|
|
8997
8997
|
- When updating, incorporate both the existing content and the new evidence, preserving knowledge
|
|
8998
8998
|
that still holds.
|
|
8999
|
-
- Keep references like "the evidence" or "recent sessions" out of the text — name the
|
|
8999
|
+
- Keep references like "the evidence" or "recent sessions" out of the text — name the behavior.
|
|
9000
9000
|
- The content reads as a stable identity statement, not a changelog.`;
|
|
9001
9001
|
/** The compress-synthesis system prompt. */
|
|
9002
9002
|
const COMPRESS_SYSTEM = `You fold a group of related memories into ONE canonical memory for an AI agent's long-term memory
|
|
9003
|
-
system. The members are near-
|
|
9003
|
+
system. The members are near-neighbors in one community of the memory graph; the canonical replaces
|
|
9004
9004
|
them, and each member you list in absorbedKeys is archived once the canonical is written.
|
|
9005
9005
|
|
|
9006
9006
|
- claim is the ONE load-bearing sentence the group shares.
|
|
@@ -9016,13 +9016,13 @@ const dataBlock = (label, text) => wrapAsData(label, text);
|
|
|
9016
9016
|
* The stance judge's user turn for one pair. Both texts are wrapped; neither carries a path.
|
|
9017
9017
|
*
|
|
9018
9018
|
* The prompt names no path, no cosine, and no prior verdict, so the model cannot infer which answer
|
|
9019
|
-
* the caller is hoping for and cannot
|
|
9019
|
+
* the caller is hoping for and cannot recognize a pair it judged last night.
|
|
9020
9020
|
*/
|
|
9021
9021
|
const stancePrompt = (textA, textB) => `${dataBlock("memory_a", textA)}\n\n${dataBlock("memory_b", textB)}\n\nDo these two memories contradict each other? Give your verdict, your confidence, and a rationale naming the specific claims that conflict or why they are compatible.`;
|
|
9022
9022
|
/** The arc-triage user turn: the live arcs and the recent evidence, both wrapped. */
|
|
9023
|
-
const arcTriagePrompt = (arcsText, evidenceText) => `${dataBlock("current_arcs", arcsText)}\n\n${dataBlock("evidence", evidenceText)}\n\nProduce a triage plan. Assign update or skip to every existing arc, and add a create entry for any genuinely new
|
|
9023
|
+
const arcTriagePrompt = (arcsText, evidenceText) => `${dataBlock("current_arcs", arcsText)}\n\n${dataBlock("evidence", evidenceText)}\n\nProduce a triage plan. Assign update or skip to every existing arc, and add a create entry for any genuinely new behavioral pattern the existing arcs do not cover.`;
|
|
9024
9024
|
/** The arc-execute user turn for one arc. `current` is absent on a create. */
|
|
9025
|
-
const arcExecutePrompt = (input) => (input.current === void 0 ? `${dataBlock("new_arc_title", input.title)}\n\n` : `${dataBlock("existing_arc", input.current)}\n\n`) + `${dataBlock("evidence", input.evidenceText)}\n\n${dataBlock("triage_rationale", input.rationale)}\n\n` + (input.current === void 0 ? "Synthesize a new
|
|
9025
|
+
const arcExecutePrompt = (input) => (input.current === void 0 ? `${dataBlock("new_arc_title", input.title)}\n\n` : `${dataBlock("existing_arc", input.current)}\n\n`) + `${dataBlock("evidence", input.evidenceText)}\n\n${dataBlock("triage_rationale", input.rationale)}\n\n` + (input.current === void 0 ? "Synthesize a new behavioral principal from this evidence." : "Update the arc to incorporate the new evidence, preserving existing knowledge that holds.");
|
|
9026
9026
|
/** The compress user turn for one batch: every member's text, wrapped, under its offered key. */
|
|
9027
9027
|
const compressPrompt = (members) => `${members.map((member) => dataBlock(`member_${member.key}`, member.text)).join("\n\n")}\n\nFold these memories into one canonical memory. List in absorbedKeys exactly the members whose content the canonical carries forward.`;
|
|
9028
9028
|
/**
|
|
@@ -9081,11 +9081,11 @@ const activeCorpus = (db) => db.all(`SELECT path, memory_type, title, gist, body
|
|
|
9081
9081
|
word_count, created_at, updated_at, valid_until, reprieves
|
|
9082
9082
|
FROM files WHERE archived = 0 ORDER BY created_at ASC, path ASC`);
|
|
9083
9083
|
/**
|
|
9084
|
-
* Per-source top-`k` nearest
|
|
9084
|
+
* Per-source top-`k` nearest neighbors above a similarity floor, over first-chunk vectors.
|
|
9085
9085
|
*
|
|
9086
9086
|
* `ordinal = 0` collapses a file to its first chunk, not its best chunk. The format is one
|
|
9087
9087
|
* fact per file, so almost every file is a single chunk. Taking the first keeps the pair set
|
|
9088
|
-
* symmetric, which `min(distance)` over all chunks would not. An asymmetric
|
|
9088
|
+
* symmetric, which `min(distance)` over all chunks would not. An asymmetric neighborhood
|
|
9089
9089
|
* would make `(a, b)` a candidate while `(b, a)` is not, so which of two files was read first
|
|
9090
9090
|
* would decide whether they merge.
|
|
9091
9091
|
*
|
|
@@ -9094,7 +9094,7 @@ const activeCorpus = (db) => db.all(`SELECT path, memory_type, title, gist, body
|
|
|
9094
9094
|
* SQL function over two `Uint8Array` arguments (`packages/index/src/database.ts`) and not a driver
|
|
9095
9095
|
* builtin with a fixed calling shape.
|
|
9096
9096
|
*/
|
|
9097
|
-
const
|
|
9097
|
+
const neighborPairs = (db, options) => {
|
|
9098
9098
|
const excluded = options.excludeTypes ?? [];
|
|
9099
9099
|
const typeFilter = excluded.length === 0 ? "" : ` AND f.memory_type NOT IN (${excluded.map(() => "?").join(", ")})`;
|
|
9100
9100
|
return db.all(`WITH vecs AS (
|
|
@@ -9555,7 +9555,7 @@ const runRetentionPass = (db, at) => Effect.gen(function* () {
|
|
|
9555
9555
|
* `update`/`create` entries cost a second call.
|
|
9556
9556
|
*
|
|
9557
9557
|
* **One commit per arc, not one for the phase.** An arc is a standalone assertion about the agent's
|
|
9558
|
-
* own
|
|
9558
|
+
* own behavior, and a reviewer reads it as one thing; a commit carrying four unrelated arcs is a
|
|
9559
9559
|
* commit nobody reviews. It also means a model failure on the third arc leaves the first two
|
|
9560
9560
|
* committed, so the per-item isolation reaches the git history and not only the counters.
|
|
9561
9561
|
*
|
|
@@ -10000,7 +10000,7 @@ const confidenceDecay = (env) => Effect.gen(function* () {
|
|
|
10000
10000
|
*/
|
|
10001
10001
|
/** The moderate similarity floor a pair must clear to be worth a model call. */
|
|
10002
10002
|
const CONFLICT_COSINE_FLOOR = .8;
|
|
10003
|
-
/** Nearest same-entity
|
|
10003
|
+
/** Nearest same-entity neighbors considered per source. */
|
|
10004
10004
|
const CONFLICT_PER_SOURCE_K = 5;
|
|
10005
10005
|
/** Pairs judged per cycle. The model-cost guard. */
|
|
10006
10006
|
const CONFLICT_CANDIDATE_LIMIT = 200;
|
|
@@ -10143,7 +10143,7 @@ const dedupMerge = (env) => Effect.gen(function* () {
|
|
|
10143
10143
|
* The `files_content_hash_active` index carves tasks out for the same reason, so structural and
|
|
10144
10144
|
* semantic dedup agree about them.
|
|
10145
10145
|
*/
|
|
10146
|
-
const pairs = yield*
|
|
10146
|
+
const pairs = yield* neighborPairs(env.deps.db, {
|
|
10147
10147
|
floor: NEAR_DUPLICATE_THRESHOLD,
|
|
10148
10148
|
perSourceK: 5,
|
|
10149
10149
|
limit: 100 * 4,
|
|
@@ -10714,7 +10714,7 @@ const preflight = (env) => Effect.gen(function* () {
|
|
|
10714
10714
|
*/
|
|
10715
10715
|
/** The similarity floor a pair must clear to become a mined `relates_to`. */
|
|
10716
10716
|
const MINING_COSINE_FLOOR = .85;
|
|
10717
|
-
/** Nearest
|
|
10717
|
+
/** Nearest neighbors considered per source file. */
|
|
10718
10718
|
const MINING_PER_SOURCE_K = 5;
|
|
10719
10719
|
/** Pairs mined per cycle. The cost guard on a corpus whose pair space is quadratic. */
|
|
10720
10720
|
const MINING_SAMPLE_LIMIT = 2e3;
|
|
@@ -10726,7 +10726,7 @@ const relationshipMining = (env) => Effect.gen(function* () {
|
|
|
10726
10726
|
* count. The `edges` CHECK cannot refuse it, because `relates_to` under `memory` is a
|
|
10727
10727
|
* well-formed edge whatever files sit at its ends.
|
|
10728
10728
|
*/
|
|
10729
|
-
const pairs = yield*
|
|
10729
|
+
const pairs = yield* neighborPairs(env.deps.db, {
|
|
10730
10730
|
floor: MINING_COSINE_FLOOR,
|
|
10731
10731
|
perSourceK: 5,
|
|
10732
10732
|
limit: MINING_SAMPLE_LIMIT,
|
|
@@ -10882,7 +10882,7 @@ const headOf = (env) => env.deps.git.revParseHead().pipe(Effect.map((sha) => sha
|
|
|
10882
10882
|
* and re-assert the fact deliberately.
|
|
10883
10883
|
*
|
|
10884
10884
|
* **Arcs are exempt.** An arc is system-written and carries no meaningful TTL; expiring one on age
|
|
10885
|
-
* would delete the agent's own
|
|
10885
|
+
* would delete the agent's own behavioral identity on a schedule.
|
|
10886
10886
|
*/
|
|
10887
10887
|
const reprieve = (env) => Effect.gen(function* () {
|
|
10888
10888
|
const expired = (yield* runRetentionPass(env.deps.db, env.at)).scored.filter((entry) => {
|
|
@@ -11459,7 +11459,7 @@ const traceConsolidation = (env) => Effect.gen(function* () {
|
|
|
11459
11459
|
skipped,
|
|
11460
11460
|
conflicts: conflicted
|
|
11461
11461
|
};
|
|
11462
|
-
const commitSha = yield* commitPhase(env, "trace-consolidation", `${conflict === void 0 ? "
|
|
11462
|
+
const commitSha = yield* commitPhase(env, "trace-consolidation", `${conflict === void 0 ? "distill" : "distill (frame conflict)"} ${title}`, counts, commitContextFor(candidate, conflict));
|
|
11463
11463
|
if (commitSha !== null) lastCommit = commitSha;
|
|
11464
11464
|
written += 1;
|
|
11465
11465
|
}
|
|
@@ -12847,4 +12847,4 @@ const latest = (left, right) => left === null ? right : right === null ? left :
|
|
|
12847
12847
|
|
|
12848
12848
|
//#endregion
|
|
12849
12849
|
export { STATE_SIDECAR_PATH as $, makeIndexRecorder as A, makeGitPort as B, ModelClientLive as C, EMBED_DIM as D, EmbeddingsLive as E, reinforce as F, STATE_MIGRATIONS_DIR as G, DatabaseService as H, Indexer as I, expandRoot as J, STATE_SCHEMA as K, makeIndexer as L, readWatermark as M, Retrieval as N, EMBED_WATERMARK as O, makeRetrieval as P, STATE_DB_PATH as Q, readIndexState as R, ModelClient as S, Embeddings as T, makeDatabase as U, sanitizeFtsQuery as V, MIGRATIONS_DIR as W, INDEX_DB_PATH as X, makeStore as Y, SLEEP_REPORTS_DIR as Z, unlink as _, parseSidecar as a, commitSubject as at, discriminationGate as b, generateArtifacts as c, isValidDatetime as ct, danglingEdges as d, REINFORCE_SIGNALS as dt, attemptIo as et, publishRows as f, frameKeyOf as ft, meta as g, link as h, makeSleep as i, makeGit as it, persistScanned as j, IndexRecorder as k, accessRows as l, closesFence as lt, hrefFor as m, scanTraceRoot as n, readFileOrNull as nt, renderSidecar as o, checkMemory as ot, applyHeadEdits as p, Store as q, Sleep as r, Git as rt, archivedFormOf as s, setMeta as st, mergeTailExtract as t, initRepo as tt, allPaths as u, fenceOpeningOf as ut, SLEEP_PHASES as v, wrapAsData as w, runDiscrimination as x, isSleepPhase as y, IndexGit as z };
|
|
12850
|
-
//# sourceMappingURL=dist-
|
|
12850
|
+
//# sourceMappingURL=dist-dfrcDFad.mjs.map
|