@hviana/sema 0.2.4 → 0.2.5
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/src/geometry.d.ts +26 -0
- package/dist/src/geometry.js +32 -3
- package/dist/src/mind/attention.d.ts +232 -5
- package/dist/src/mind/attention.js +718 -166
- package/dist/src/mind/index.d.ts +2 -0
- package/dist/src/mind/junction.d.ts +30 -1
- package/dist/src/mind/junction.js +73 -18
- package/dist/src/mind/mind.d.ts +2 -0
- package/dist/src/mind/rationale.d.ts +7 -2
- package/dist/src/mind/rationale.js +6 -5
- package/dist/src/mind/traverse.js +74 -10
- package/dist/src/mind/types.d.ts +18 -0
- package/package.json +1 -1
- package/src/geometry.ts +52 -3
- package/src/mind/attention.ts +1134 -121
- package/src/mind/index.ts +16 -0
- package/src/mind/junction.ts +125 -16
- package/src/mind/mind.ts +15 -0
- package/src/mind/rationale.ts +12 -4
- package/src/mind/traverse.ts +75 -7
- package/src/mind/types.ts +25 -0
- package/test/51-structural-resonance-ladder.test.mjs +552 -0
- package/test/52-climb-consensus-instrumentation.test.mjs +324 -0
package/dist/src/geometry.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Vec } from "./vec.js";
|
|
1
2
|
import { Sema, Space } from "./sema.js";
|
|
2
3
|
import { Alphabet } from "./alphabet.js";
|
|
3
4
|
/** The store's geometric identity bar: cosine ≥ 1 − 1/√D is the similarity at
|
|
@@ -144,6 +145,31 @@ export declare function stablePrefixFoldIncremental(space: Space, alphabet: Alph
|
|
|
144
145
|
tree: Sema;
|
|
145
146
|
fold: StableFold;
|
|
146
147
|
};
|
|
148
|
+
/** Plain river fold WITHOUT the final root normalize — the segment-level
|
|
149
|
+
* building block of {@link stablePrefixFold} (interiors must keep their
|
|
150
|
+
* byte-proportional magnitude; only the whole perception's root is ever
|
|
151
|
+
* normalized). Exported so callers that COMPOSE already-existing structural
|
|
152
|
+
* parts into a hypothetical synthetic root (see {@link composeStructuralGist})
|
|
153
|
+
* can feed the same raw primitive instead of duplicating its mathematics. */
|
|
154
|
+
export declare function riverFoldRaw(space: Space, row: Folded[]): Folded;
|
|
155
|
+
/** One already-existing structural vector to compose, paired with the byte
|
|
156
|
+
* span (query-slot) length it stands in for. `len`, not the vector's own
|
|
157
|
+
* magnitude, is what {@link composeStructuralGist} restores — the composed
|
|
158
|
+
* slot's NATURAL span, exactly as the linear river fold would carry it. */
|
|
159
|
+
export interface StructuralPart {
|
|
160
|
+
v: Vec;
|
|
161
|
+
len: number;
|
|
162
|
+
}
|
|
163
|
+
/** Synthesize a hypothetical internal structure from already-existing
|
|
164
|
+
* structural vectors — NOT from bytes. This is the raw positional
|
|
165
|
+
* composition the linear river fold already uses (see the folding header
|
|
166
|
+
* above): each part is positionally bound into its own seat, its natural
|
|
167
|
+
* span magnitude is preserved, the parts are linearly superposed, and only
|
|
168
|
+
* the final synthetic root is normalized. It never calls {@link gistOf}
|
|
169
|
+
* (there is no `gistOf` here — geometry.ts has no store), never perceives a
|
|
170
|
+
* concatenated byte string, and never interns or stores a new node: the
|
|
171
|
+
* result is an opaque, ungrounded Vec for an ANN probe only. */
|
|
172
|
+
export declare function composeStructuralGist(space: Space, parts: readonly StructuralPart[]): Vec;
|
|
147
173
|
/** The PLAIN fold's full level pyramid — every level's item list, bottom
|
|
148
174
|
* (leaves) to top (root). Left-grouped folding is RADIX-ALIGNED: the item
|
|
149
175
|
* at level L, index i, covers exactly bytes [i·mg^L, (i+1)·mg^L) whenever
|
package/dist/src/geometry.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// that cross the stable-prefix boundary are split so the prefix folds
|
|
7
7
|
// identically regardless of what follows — pure structural stability.
|
|
8
8
|
// 3. The same rule recurses level after level until one root remains.
|
|
9
|
-
import { normalize } from "./vec.js";
|
|
9
|
+
import { addInto, copy, normalize, zeros } from "./vec.js";
|
|
10
10
|
import { sema } from "./sema.js";
|
|
11
11
|
// ---- geometric constants ----
|
|
12
12
|
//
|
|
@@ -374,8 +374,10 @@ function fold2(space, a, b) {
|
|
|
374
374
|
/** Plain river fold WITHOUT the final root normalize — the segment-level
|
|
375
375
|
* building block of {@link stablePrefixFold} (interiors must keep their
|
|
376
376
|
* byte-proportional magnitude; only the whole perception's root is ever
|
|
377
|
-
* normalized).
|
|
378
|
-
|
|
377
|
+
* normalized). Exported so callers that COMPOSE already-existing structural
|
|
378
|
+
* parts into a hypothetical synthetic root (see {@link composeStructuralGist})
|
|
379
|
+
* can feed the same raw primitive instead of duplicating its mathematics. */
|
|
380
|
+
export function riverFoldRaw(space, row) {
|
|
379
381
|
if (row.length === 0) {
|
|
380
382
|
const z = new Float32Array(space.D);
|
|
381
383
|
return { tree: sema(z, new Uint8Array(0), null), len: 0 };
|
|
@@ -390,6 +392,33 @@ function riverFoldRaw(space, row) {
|
|
|
390
392
|
}
|
|
391
393
|
return level[0];
|
|
392
394
|
}
|
|
395
|
+
/** Synthesize a hypothetical internal structure from already-existing
|
|
396
|
+
* structural vectors — NOT from bytes. This is the raw positional
|
|
397
|
+
* composition the linear river fold already uses (see the folding header
|
|
398
|
+
* above): each part is positionally bound into its own seat, its natural
|
|
399
|
+
* span magnitude is preserved, the parts are linearly superposed, and only
|
|
400
|
+
* the final synthetic root is normalized. It never calls {@link gistOf}
|
|
401
|
+
* (there is no `gistOf` here — geometry.ts has no store), never perceives a
|
|
402
|
+
* concatenated byte string, and never interns or stores a new node: the
|
|
403
|
+
* result is an opaque, ungrounded Vec for an ANN probe only. */
|
|
404
|
+
export function composeStructuralGist(space, parts) {
|
|
405
|
+
const foldedParts = [];
|
|
406
|
+
for (const part of parts) {
|
|
407
|
+
if (part.len <= 0)
|
|
408
|
+
continue;
|
|
409
|
+
const direction = copy(part.v);
|
|
410
|
+
normalize(direction);
|
|
411
|
+
const scaled = zeros(space.D);
|
|
412
|
+
addInto(scaled, direction, Math.sqrt(part.len));
|
|
413
|
+
foldedParts.push({ tree: sema(scaled), len: part.len });
|
|
414
|
+
}
|
|
415
|
+
if (foldedParts.length === 0)
|
|
416
|
+
return zeros(space.D);
|
|
417
|
+
const rawRoot = riverFoldRaw(space, foldedParts);
|
|
418
|
+
const result = copy(rawRoot.tree.v);
|
|
419
|
+
normalize(result);
|
|
420
|
+
return result;
|
|
421
|
+
}
|
|
393
422
|
/** Plain bytes→tree (identical to capability-less {@link bytesToTree}) that
|
|
394
423
|
* also RETURNS its pyramid, reusing `prev` — the pyramid of a PROPER
|
|
395
424
|
* prefix of `bytes` (caller guarantees content match and
|
|
@@ -1,5 +1,181 @@
|
|
|
1
1
|
import type { DerivationStep } from "./graph-search.js";
|
|
2
|
-
import type { AncestorReach, Attention, AttentionRead, DFMode, MindContext, Region, RegionVote, SaturationInfo } from "./types.js";
|
|
2
|
+
import type { AncestorReach, Attention, AttentionRead, DFMode, MindContext, Region, RegionVote, SaturationInfo, SaturationStop } from "./types.js";
|
|
3
|
+
import { type StructuralPart } from "../geometry.js";
|
|
4
|
+
import { type JunctionSynonymSides } from "./junction.js";
|
|
5
|
+
/** How the newly-added graded junction ladder (junction.ts / attention.ts's
|
|
6
|
+
* {@link CrossRegionTier}) is reported on a `junctionVotes` entry. The
|
|
7
|
+
* instrumentation spec this implements predates that ladder and only knew
|
|
8
|
+
* two tiers ("exact" | "synonym"); with the richer `CrossRegionTier` now
|
|
9
|
+
* the real shape of a junction vote's provenance, `junctionVotes[].tier`
|
|
10
|
+
* reports it DIRECTLY (the tier as-is: "exact" | "single-synonym" |
|
|
11
|
+
* "double-synonym" | "structural-resonance") rather than collapsing every
|
|
12
|
+
* non-exact tier into a lossy "synonym" bucket — the whole point of
|
|
13
|
+
* exposing `tier` here is to let a debugger tell a halo-sibling
|
|
14
|
+
* substitution apart from a structural-resonance ANN guess, which the
|
|
15
|
+
* spec's original two-value type cannot do. */
|
|
16
|
+
export type ClimbConsensusJunctionTier = CrossRegionTier;
|
|
17
|
+
export type RegionOutcome = "voted" | "no-ann-hit" | "no-structural-reach" | "saturated-abstention" | "nonpositive-df-weight" | "contrastive-margin-rejection";
|
|
18
|
+
export interface ConsensusRegionTrace {
|
|
19
|
+
index: number;
|
|
20
|
+
source: "perceived" | "recognised";
|
|
21
|
+
span: [number, number];
|
|
22
|
+
chunk: boolean;
|
|
23
|
+
known: boolean;
|
|
24
|
+
canonicalId?: number;
|
|
25
|
+
canonicalUsable: boolean;
|
|
26
|
+
canonicalFailed: boolean;
|
|
27
|
+
annQueried: boolean;
|
|
28
|
+
annHitsReturned: number;
|
|
29
|
+
annHitsExamined: number;
|
|
30
|
+
selected?: {
|
|
31
|
+
source: "canonical" | "ann";
|
|
32
|
+
node: number;
|
|
33
|
+
rank?: number;
|
|
34
|
+
score: number;
|
|
35
|
+
fallback?: "orphan" | "saturated-tie";
|
|
36
|
+
};
|
|
37
|
+
reachNode?: number;
|
|
38
|
+
outcome: RegionOutcome;
|
|
39
|
+
idf?: number;
|
|
40
|
+
dfWeight?: number;
|
|
41
|
+
contrastiveMargin?: number;
|
|
42
|
+
contrastiveNoiseFloor?: number;
|
|
43
|
+
mutualWeight?: number;
|
|
44
|
+
voteWeightPerRoot?: number;
|
|
45
|
+
focusWeightPerRoot?: number;
|
|
46
|
+
ordinaryVoteProduced: boolean;
|
|
47
|
+
superseded: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface ConsensusReachTrace {
|
|
50
|
+
node: number;
|
|
51
|
+
roots: number[];
|
|
52
|
+
contextsReached: number;
|
|
53
|
+
saturated: boolean;
|
|
54
|
+
saturation?: SaturationStop;
|
|
55
|
+
}
|
|
56
|
+
export type AnchorRejectionReason = "below-natural-break" | "below-consensus-floor" | "leading-saturation";
|
|
57
|
+
export interface ConsensusAnchorTrace {
|
|
58
|
+
anchor: number;
|
|
59
|
+
rank: number;
|
|
60
|
+
pooledVote: number;
|
|
61
|
+
idfVote: number;
|
|
62
|
+
candidateBreadth: number;
|
|
63
|
+
contributingVotes: number;
|
|
64
|
+
contributingEvidence: number;
|
|
65
|
+
breadth: number;
|
|
66
|
+
contributingSpans: Array<[number, number]>;
|
|
67
|
+
clusters: number;
|
|
68
|
+
commit: {
|
|
69
|
+
status: "root" | "overlap" | "rejected";
|
|
70
|
+
dominant: boolean;
|
|
71
|
+
passesNaturalBreak?: boolean;
|
|
72
|
+
passesConsensusFloor?: boolean;
|
|
73
|
+
pastLeadingSaturation?: boolean;
|
|
74
|
+
rejectionReasons: AnchorRejectionReason[];
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export interface JunctionVoteTrace {
|
|
78
|
+
container: number;
|
|
79
|
+
span: [number, number];
|
|
80
|
+
roots: number[];
|
|
81
|
+
sourceRegionIndices: number[];
|
|
82
|
+
explainedAwayRegionIndices: number[];
|
|
83
|
+
absorbed: number;
|
|
84
|
+
tier?: ClimbConsensusJunctionTier;
|
|
85
|
+
}
|
|
86
|
+
export interface ClimbConsensusData {
|
|
87
|
+
version: 1;
|
|
88
|
+
cache: {
|
|
89
|
+
hit: boolean;
|
|
90
|
+
detailAvailable: boolean;
|
|
91
|
+
};
|
|
92
|
+
config: {
|
|
93
|
+
annK: number;
|
|
94
|
+
crossRegionProbeLimit: number;
|
|
95
|
+
mode: DFMode;
|
|
96
|
+
corpusN?: number;
|
|
97
|
+
dimension?: number;
|
|
98
|
+
hubBound?: number;
|
|
99
|
+
estimatorNoise?: number;
|
|
100
|
+
naturalBreak?: number;
|
|
101
|
+
consensusFloor?: number;
|
|
102
|
+
};
|
|
103
|
+
candidates: {
|
|
104
|
+
perceived: number;
|
|
105
|
+
recognised: number;
|
|
106
|
+
total: number;
|
|
107
|
+
};
|
|
108
|
+
regions?: ConsensusRegionTrace[];
|
|
109
|
+
reaches?: ConsensusReachTrace[];
|
|
110
|
+
crossRegion?: {
|
|
111
|
+
eligibleRegions: number;
|
|
112
|
+
maximalRegions: number;
|
|
113
|
+
probeLimit: number;
|
|
114
|
+
probesAttempted: number;
|
|
115
|
+
junctionVotes: JunctionVoteTrace[];
|
|
116
|
+
supersededOrdinaryVotes: number;
|
|
117
|
+
};
|
|
118
|
+
saturation?: {
|
|
119
|
+
regionIntervals: Array<{
|
|
120
|
+
start: number;
|
|
121
|
+
end: number;
|
|
122
|
+
}>;
|
|
123
|
+
hasLeading: boolean;
|
|
124
|
+
leadingEnd: number;
|
|
125
|
+
};
|
|
126
|
+
pooling?: {
|
|
127
|
+
inputVotes: number;
|
|
128
|
+
eligibleVotes: number;
|
|
129
|
+
saturationMaskedVotes: number;
|
|
130
|
+
};
|
|
131
|
+
anchors?: ConsensusAnchorTrace[];
|
|
132
|
+
result: AttentionRead;
|
|
133
|
+
}
|
|
134
|
+
/** The mutable collection buffers threaded through one traced consensus
|
|
135
|
+
* climb — allocated exactly once, in {@link computeAttention}, only when
|
|
136
|
+
* `ctx.trace` is set. Every field mirrors a `ClimbConsensusData` array/map,
|
|
137
|
+
* built incrementally as the pipeline runs so commit-time decisions (in
|
|
138
|
+
* particular) are recorded LIVE, not reconstructed afterward. */
|
|
139
|
+
interface TraceDraft {
|
|
140
|
+
perceivedCount: number;
|
|
141
|
+
regions: ConsensusRegionTrace[];
|
|
142
|
+
crossRegionJunctionVotes: JunctionVoteTrace[];
|
|
143
|
+
crossRegionSummary?: {
|
|
144
|
+
eligibleRegions: number;
|
|
145
|
+
maximalRegions: number;
|
|
146
|
+
probeLimit: number;
|
|
147
|
+
probesAttempted: number;
|
|
148
|
+
};
|
|
149
|
+
supersededOrdinaryVotes: number;
|
|
150
|
+
saturation?: {
|
|
151
|
+
regionIntervals: Array<{
|
|
152
|
+
start: number;
|
|
153
|
+
end: number;
|
|
154
|
+
}>;
|
|
155
|
+
hasLeading: boolean;
|
|
156
|
+
leadingEnd: number;
|
|
157
|
+
};
|
|
158
|
+
pooling?: {
|
|
159
|
+
inputVotes: number;
|
|
160
|
+
eligibleVotes: number;
|
|
161
|
+
saturationMaskedVotes: number;
|
|
162
|
+
};
|
|
163
|
+
anchors: ConsensusAnchorTrace[];
|
|
164
|
+
}
|
|
165
|
+
/** The config/corpus context {@link traceAttention} needs to fill in
|
|
166
|
+
* `ClimbConsensusData.config` and `.result` at whichever exit fires —
|
|
167
|
+
* threaded down from {@link computeAttention} rather than re-derived, so
|
|
168
|
+
* every emission point reports the SAME numbers the real climb used. */
|
|
169
|
+
interface ClimbConsensusCfg {
|
|
170
|
+
k: number;
|
|
171
|
+
mode: DFMode;
|
|
172
|
+
perceivedCount: number;
|
|
173
|
+
totalRegions: number;
|
|
174
|
+
N?: number;
|
|
175
|
+
reachMemo?: ReadonlyMap<number, AncestorReach>;
|
|
176
|
+
naturalBreak?: number;
|
|
177
|
+
consensusFloor?: number;
|
|
178
|
+
}
|
|
3
179
|
/** Climb the query's perceived byte regions up the structural DAG via
|
|
4
180
|
* resonance, pool the evidence, and return only the ROOT points of
|
|
5
181
|
* attention — those that cleared commitVotes' significance floor. */
|
|
@@ -19,7 +195,7 @@ export declare function climbAttention(ctx: MindContext, query: Uint8Array, k: n
|
|
|
19
195
|
export declare function climbAttentionAll(ctx: MindContext, query: Uint8Array, k: number, mode?: DFMode): Promise<AttentionRead>;
|
|
20
196
|
export declare function computeAttention(ctx: MindContext, query: Uint8Array, k: number, mode: DFMode): Promise<AttentionRead>;
|
|
21
197
|
export declare function collectRegions(ctx: MindContext, query: Uint8Array): Region[];
|
|
22
|
-
export declare function voteRegions(ctx: MindContext, query: Uint8Array, regions: readonly Region[], k: number, mode: DFMode, N: number, reachMemo?: Map<number, AncestorReach
|
|
198
|
+
export declare function voteRegions(ctx: MindContext, query: Uint8Array, regions: readonly Region[], k: number, mode: DFMode, N: number, reachMemo?: Map<number, AncestorReach>, td?: TraceDraft): Promise<{
|
|
23
199
|
votes: RegionVote[];
|
|
24
200
|
saturated: boolean[];
|
|
25
201
|
voters: Array<{
|
|
@@ -40,7 +216,7 @@ export declare function voteRegions(ctx: MindContext, query: Uint8Array, regions
|
|
|
40
216
|
* merely logs alongside it. `votesIdf`/`support` are the same two
|
|
41
217
|
* read-outs {@link commitVotes} always gated on; only how they accumulate
|
|
42
218
|
* changed. */
|
|
43
|
-
export declare function poolVotes(ctx: MindContext, regionVotes: readonly RegionVote[], sat: SaturationInfo, N: number): {
|
|
219
|
+
export declare function poolVotes(ctx: MindContext, regionVotes: readonly RegionVote[], sat: SaturationInfo, N: number, td?: TraceDraft): {
|
|
44
220
|
votes: Map<number, number>;
|
|
45
221
|
votesIdf: Map<number, number>;
|
|
46
222
|
support: Map<number, {
|
|
@@ -70,7 +246,7 @@ export declare function commitVotes(ctx: MindContext, pooled: {
|
|
|
70
246
|
id: number;
|
|
71
247
|
score: number;
|
|
72
248
|
w: number;
|
|
73
|
-
} | null>, N: number): AttentionRead;
|
|
249
|
+
} | null>, N: number, td?: TraceDraft, cfg?: ClimbConsensusCfg): AttentionRead;
|
|
74
250
|
export declare function detectSaturated(ctx: MindContext, regions: ReadonlyArray<{
|
|
75
251
|
start: number;
|
|
76
252
|
end: number;
|
|
@@ -78,6 +254,56 @@ export declare function detectSaturated(ctx: MindContext, regions: ReadonlyArray
|
|
|
78
254
|
}>, saturated: ReadonlyArray<boolean>): SaturationInfo;
|
|
79
255
|
export declare function canonicalChunkId(ctx: MindContext, regionBytes: Uint8Array, N: number, reachMemo?: Map<number, AncestorReach>): number | null;
|
|
80
256
|
export declare function naturalBreak(votes: number[]): number;
|
|
257
|
+
export type CrossRegionTier = "exact" | "single-synonym" | "double-synonym" | "structural-resonance";
|
|
258
|
+
export interface StructuralVariant {
|
|
259
|
+
left: StructuralPart;
|
|
260
|
+
right: StructuralPart;
|
|
261
|
+
kind: "exact-exact" | "left-synonym" | "right-synonym" | "double-synonym";
|
|
262
|
+
semanticConfidence: number;
|
|
263
|
+
leftSiblingId?: number;
|
|
264
|
+
rightSiblingId?: number;
|
|
265
|
+
}
|
|
266
|
+
export interface StructuralResonanceProposal {
|
|
267
|
+
id: number;
|
|
268
|
+
annScore: number;
|
|
269
|
+
semanticConfidence: number;
|
|
270
|
+
effectiveScore: number;
|
|
271
|
+
variant: StructuralVariant["kind"];
|
|
272
|
+
leftSiblingId?: number;
|
|
273
|
+
rightSiblingId?: number;
|
|
274
|
+
}
|
|
275
|
+
/** Build, bound and order every mandatory structural variant (§7-8): the
|
|
276
|
+
* exact/exact composition is always kept; up to `ctx.cfg.haloQueryK`
|
|
277
|
+
* synonym variants (single- and double-synonym combined, one shared
|
|
278
|
+
* budget) are appended, ordered by confidence, then kind, then sibling id. */
|
|
279
|
+
export declare function buildStructuralVariants(ctx: MindContext, ra: Region, rb: Region, sides: JunctionSynonymSides): {
|
|
280
|
+
variants: StructuralVariant[];
|
|
281
|
+
exactLeft: StructuralPart;
|
|
282
|
+
exactRight: StructuralPart;
|
|
283
|
+
};
|
|
284
|
+
/** The final approximate tier: compose every retained structural variant,
|
|
285
|
+
* ANN-query each, merge proposals by candidate id, and validate the winner
|
|
286
|
+
* through the SAME structural gates every other tier answers to (saturation,
|
|
287
|
+
* roots, IDF, contrastive margin). Returns null when nothing survives. */
|
|
288
|
+
export declare function structuralResonance(ctx: MindContext, query: Uint8Array, ra: Region, rb: Region, sides: JunctionSynonymSides, k: number, N: number, reachMemo: Map<number, AncestorReach>,
|
|
289
|
+
/** Each side's OWN individual climb roots (from voteRegions), when it cast
|
|
290
|
+
* one — the self-evidence backstop structural-resonance needs and the
|
|
291
|
+
* exact tier gets for free from literal byte containment (§11's whole
|
|
292
|
+
* premise: recover a JOINT context neither side votes for alone). A
|
|
293
|
+
* candidate whose reach is exactly one side's own conclusion is not new
|
|
294
|
+
* evidence of a joint whole; it is that side's resonance rediscovering
|
|
295
|
+
* itself through a synthetic gist still dominated by its own direction. */
|
|
296
|
+
ownRootsA: readonly number[] | undefined, ownRootsB: readonly number[] | undefined): Promise<{
|
|
297
|
+
proposal: StructuralResonanceProposal;
|
|
298
|
+
reach: AncestorReach;
|
|
299
|
+
idf: number;
|
|
300
|
+
} | null>;
|
|
301
|
+
/** Emit the "climbConsensus" step — the human-readable note this always
|
|
302
|
+
* produced, now paired (when `ctx.trace` and `cfg` are both present) with
|
|
303
|
+
* the structured {@link ClimbConsensusData} payload on the SAME step's
|
|
304
|
+
* `data` field. Every exit of {@link computeAttention} funnels through
|
|
305
|
+
* here, so instrumentation and the existing rationale text can never drift
|
|
306
|
+
* apart — see the instrumentation spec's §9 "every exit path". */
|
|
81
307
|
export declare function traceAttention(ctx: MindContext, regions: ReadonlyArray<{
|
|
82
308
|
start: number;
|
|
83
309
|
end: number;
|
|
@@ -85,4 +311,5 @@ export declare function traceAttention(ctx: MindContext, regions: ReadonlyArray<
|
|
|
85
311
|
id: number;
|
|
86
312
|
score: number;
|
|
87
313
|
w: number;
|
|
88
|
-
} | null>, roots: ReadonlyArray<Attention>, steps?: ReadonlyArray<DerivationStep>): void;
|
|
314
|
+
} | null>, roots: ReadonlyArray<Attention>, steps?: ReadonlyArray<DerivationStep>, td?: TraceDraft, cfg?: ClimbConsensusCfg, ranked?: ReadonlyArray<Attention>): void;
|
|
315
|
+
export {};
|