@seanhogg/builderforce-memory 2026.6.27 → 2026.6.30
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 +28 -0
- package/dist/diagnostics/index.d.ts +7 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +6 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/diagnostics/stack-diagnostic.d.ts +71 -0
- package/dist/diagnostics/stack-diagnostic.d.ts.map +1 -0
- package/dist/diagnostics/stack-diagnostic.js +43 -0
- package/dist/diagnostics/stack-diagnostic.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/memory/MemoryStore.d.ts +12 -0
- package/dist/memory/MemoryStore.d.ts.map +1 -1
- package/dist/memory/MemoryStore.js +28 -0
- package/dist/memory/MemoryStore.js.map +1 -1
- package/dist/retrieval/HybridRetriever.d.ts +56 -0
- package/dist/retrieval/HybridRetriever.d.ts.map +1 -0
- package/dist/retrieval/HybridRetriever.js +75 -0
- package/dist/retrieval/HybridRetriever.js.map +1 -0
- package/dist/retrieval/bm25.d.ts +32 -0
- package/dist/retrieval/bm25.d.ts.map +1 -0
- package/dist/retrieval/bm25.js +66 -0
- package/dist/retrieval/bm25.js.map +1 -0
- package/dist/retrieval/chunk.d.ts +33 -0
- package/dist/retrieval/chunk.d.ts.map +1 -0
- package/dist/retrieval/chunk.js +83 -0
- package/dist/retrieval/chunk.js.map +1 -0
- package/dist/retrieval/fusion.d.ts +40 -0
- package/dist/retrieval/fusion.d.ts.map +1 -0
- package/dist/retrieval/fusion.js +64 -0
- package/dist/retrieval/fusion.js.map +1 -0
- package/dist/retrieval/index.d.ts +16 -0
- package/dist/retrieval/index.d.ts.map +1 -0
- package/dist/retrieval/index.js +12 -0
- package/dist/retrieval/index.js.map +1 -0
- package/dist/workflow/index.d.ts +11 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +10 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/registry.d.ts +23 -0
- package/dist/workflow/registry.d.ts.map +1 -0
- package/dist/workflow/registry.js +47 -0
- package/dist/workflow/registry.js.map +1 -0
- package/dist/workflow/run.d.ts +26 -0
- package/dist/workflow/run.d.ts.map +1 -0
- package/dist/workflow/run.js +40 -0
- package/dist/workflow/run.js.map +1 -0
- package/dist/workflow/steps.d.ts +19 -0
- package/dist/workflow/steps.d.ts.map +1 -0
- package/dist/workflow/steps.js +318 -0
- package/dist/workflow/steps.js.map +1 -0
- package/dist/workflow/templates.d.ts +24 -0
- package/dist/workflow/templates.d.ts.map +1 -0
- package/dist/workflow/templates.js +80 -0
- package/dist/workflow/templates.js.map +1 -0
- package/dist/workflow/types.d.ts +38 -0
- package/dist/workflow/types.d.ts.map +1 -0
- package/dist/workflow/types.js +11 -0
- package/dist/workflow/types.js.map +1 -0
- package/package.json +12 -6
- package/src/diagnostics/index.ts +14 -0
- package/src/diagnostics/stack-diagnostic.ts +103 -0
- package/src/index.ts +84 -0
- package/src/memory/MemoryStore.ts +36 -0
- package/src/retrieval/HybridRetriever.ts +122 -0
- package/src/retrieval/bm25.ts +83 -0
- package/src/retrieval/chunk.ts +101 -0
- package/src/retrieval/fusion.ts +84 -0
- package/src/retrieval/index.ts +24 -0
- package/src/workflow/index.ts +24 -0
- package/src/workflow/registry.ts +55 -0
- package/src/workflow/run.ts +58 -0
- package/src/workflow/steps.ts +325 -0
- package/src/workflow/templates.ts +87 -0
- package/src/workflow/types.ts +42 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BM25 (Okapi) lexical ranking.
|
|
3
|
+
*
|
|
4
|
+
* The keyword half of hybrid retrieval. Dense vector search matches meaning but
|
|
5
|
+
* misses exact tokens (identifiers, error codes, rare names); BM25 catches those.
|
|
6
|
+
* Fusing the two (see {@link ./fusion}) is what lifts the memory layer from
|
|
7
|
+
* "cosine only" to a hybrid retriever on par with Weaviate-style search.
|
|
8
|
+
*
|
|
9
|
+
* Pure and zero-dependency — reuses the shared `tokenize` from ../similarity.
|
|
10
|
+
*/
|
|
11
|
+
import { tokenize } from '../similarity/index.js';
|
|
12
|
+
/**
|
|
13
|
+
* Scores every document against `query` with Okapi BM25, returning hits sorted by
|
|
14
|
+
* descending score (documents with no query-term overlap score 0 and are dropped).
|
|
15
|
+
* Builds the index inline — for a recall over a bounded candidate set (the memory
|
|
16
|
+
* store / a vector pre-filter) this is O(N·terms) and needs no persistence.
|
|
17
|
+
*/
|
|
18
|
+
export function bm25Search(query, docs, opts = {}) {
|
|
19
|
+
const k1 = opts.k1 ?? 1.5;
|
|
20
|
+
const b = opts.b ?? 0.75;
|
|
21
|
+
const N = docs.length;
|
|
22
|
+
if (N === 0)
|
|
23
|
+
return [];
|
|
24
|
+
const queryTerms = new Set(tokenize(query));
|
|
25
|
+
if (queryTerms.size === 0)
|
|
26
|
+
return [];
|
|
27
|
+
// Per-doc term frequencies + document lengths.
|
|
28
|
+
const docTerms = [];
|
|
29
|
+
const df = new Map();
|
|
30
|
+
let totalLen = 0;
|
|
31
|
+
for (const doc of docs) {
|
|
32
|
+
const tokens = tokenize(doc.text);
|
|
33
|
+
const tf = new Map();
|
|
34
|
+
for (const t of tokens)
|
|
35
|
+
tf.set(t, (tf.get(t) ?? 0) + 1);
|
|
36
|
+
for (const t of tf.keys())
|
|
37
|
+
if (queryTerms.has(t))
|
|
38
|
+
df.set(t, (df.get(t) ?? 0) + 1);
|
|
39
|
+
docTerms.push({ id: doc.id, tf, len: tokens.length });
|
|
40
|
+
totalLen += tokens.length;
|
|
41
|
+
}
|
|
42
|
+
const avgdl = totalLen / N || 1;
|
|
43
|
+
// idf with the +1 smoothing variant (always non-negative).
|
|
44
|
+
const idf = new Map();
|
|
45
|
+
for (const term of queryTerms) {
|
|
46
|
+
const n = df.get(term) ?? 0;
|
|
47
|
+
idf.set(term, Math.log(1 + (N - n + 0.5) / (n + 0.5)));
|
|
48
|
+
}
|
|
49
|
+
const hits = [];
|
|
50
|
+
for (const d of docTerms) {
|
|
51
|
+
let score = 0;
|
|
52
|
+
for (const term of queryTerms) {
|
|
53
|
+
const f = d.tf.get(term);
|
|
54
|
+
if (!f)
|
|
55
|
+
continue;
|
|
56
|
+
const numer = f * (k1 + 1);
|
|
57
|
+
const denom = f + k1 * (1 - b + b * (d.len / avgdl));
|
|
58
|
+
score += idf.get(term) * (numer / denom);
|
|
59
|
+
}
|
|
60
|
+
if (score > 0)
|
|
61
|
+
hits.push({ id: d.id, score });
|
|
62
|
+
}
|
|
63
|
+
hits.sort((a, b) => b.score - a.score);
|
|
64
|
+
return hits;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=bm25.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bm25.js","sourceRoot":"","sources":["../../src/retrieval/bm25.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document chunking — recursive character text splitter with overlap.
|
|
3
|
+
*
|
|
4
|
+
* The classic RAG ingestion step the memory layer was missing: large documents
|
|
5
|
+
* are split into smaller, semantically-coherent chunks before embedding so that
|
|
6
|
+
* retrieval returns precise passages rather than whole files. Mirrors the
|
|
7
|
+
* behaviour of LangChain's RecursiveCharacterTextSplitter (split on the largest
|
|
8
|
+
* natural boundary that fits, fall back to finer ones) but is zero-dependency.
|
|
9
|
+
*/
|
|
10
|
+
export interface ChunkOptions {
|
|
11
|
+
/** Target maximum chunk size in characters. Default 1000. */
|
|
12
|
+
chunkSize?: number;
|
|
13
|
+
/** Characters of overlap carried from the end of one chunk into the next,
|
|
14
|
+
* preserving context across boundaries. Default 200. Clamped below chunkSize. */
|
|
15
|
+
chunkOverlap?: number;
|
|
16
|
+
/** Separators tried in order, largest natural boundary first. */
|
|
17
|
+
separators?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface Chunk {
|
|
20
|
+
/** The chunk text. */
|
|
21
|
+
text: string;
|
|
22
|
+
/** 0-based ordinal of this chunk within its source document. */
|
|
23
|
+
index: number;
|
|
24
|
+
/** Character offset of this chunk's start within the original document. */
|
|
25
|
+
start: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Splits `text` into overlapping chunks no larger than `chunkSize` characters,
|
|
29
|
+
* preferring the largest natural separator that keeps a piece under the limit.
|
|
30
|
+
* Returns `[]` for empty/whitespace input. Deterministic and pure.
|
|
31
|
+
*/
|
|
32
|
+
export declare function chunkText(text: string, opts?: ChunkOptions): Chunk[];
|
|
33
|
+
//# sourceMappingURL=chunk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk.d.ts","sourceRoot":"","sources":["../../src/retrieval/chunk.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,YAAY;IACzB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;sFACkF;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,KAAK;IAClB,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;CACjB;AAID;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,KAAK,EAAE,CA0CxE"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document chunking — recursive character text splitter with overlap.
|
|
3
|
+
*
|
|
4
|
+
* The classic RAG ingestion step the memory layer was missing: large documents
|
|
5
|
+
* are split into smaller, semantically-coherent chunks before embedding so that
|
|
6
|
+
* retrieval returns precise passages rather than whole files. Mirrors the
|
|
7
|
+
* behaviour of LangChain's RecursiveCharacterTextSplitter (split on the largest
|
|
8
|
+
* natural boundary that fits, fall back to finer ones) but is zero-dependency.
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_SEPARATORS = ['\n\n', '\n', '. ', ' ', ''];
|
|
11
|
+
/**
|
|
12
|
+
* Splits `text` into overlapping chunks no larger than `chunkSize` characters,
|
|
13
|
+
* preferring the largest natural separator that keeps a piece under the limit.
|
|
14
|
+
* Returns `[]` for empty/whitespace input. Deterministic and pure.
|
|
15
|
+
*/
|
|
16
|
+
export function chunkText(text, opts = {}) {
|
|
17
|
+
const chunkSize = Math.max(1, opts.chunkSize ?? 1000);
|
|
18
|
+
const overlap = Math.min(Math.max(0, opts.chunkOverlap ?? 200), chunkSize - 1);
|
|
19
|
+
const separators = opts.separators ?? DEFAULT_SEPARATORS;
|
|
20
|
+
const trimmed = text.trim();
|
|
21
|
+
if (trimmed.length === 0)
|
|
22
|
+
return [];
|
|
23
|
+
if (trimmed.length <= chunkSize)
|
|
24
|
+
return [{ text: trimmed, index: 0, start: 0 }];
|
|
25
|
+
const pieces = splitRecursive(trimmed, chunkSize, separators);
|
|
26
|
+
// Merge adjacent pieces up to chunkSize, then stitch overlap between chunks.
|
|
27
|
+
const chunks = [];
|
|
28
|
+
let buf = '';
|
|
29
|
+
const flush = () => {
|
|
30
|
+
const t = buf.trim();
|
|
31
|
+
if (t.length > 0) {
|
|
32
|
+
const start = chunks.length === 0 ? 0 : Math.max(0, trimmed.indexOf(t));
|
|
33
|
+
chunks.push({ text: t, index: chunks.length, start });
|
|
34
|
+
}
|
|
35
|
+
buf = '';
|
|
36
|
+
};
|
|
37
|
+
for (const piece of pieces) {
|
|
38
|
+
if (buf.length + piece.length <= chunkSize) {
|
|
39
|
+
buf += piece;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
flush();
|
|
43
|
+
// Carry overlap from the previous chunk's tail.
|
|
44
|
+
const prev = chunks[chunks.length - 1]?.text ?? '';
|
|
45
|
+
buf = (overlap > 0 ? prev.slice(-overlap) : '') + piece;
|
|
46
|
+
// A single piece longer than chunkSize is hard-split.
|
|
47
|
+
while (buf.length > chunkSize) {
|
|
48
|
+
const head = buf.slice(0, chunkSize);
|
|
49
|
+
chunks.push({ text: head.trim(), index: chunks.length, start: 0 });
|
|
50
|
+
buf = (overlap > 0 ? head.slice(-overlap) : '') + buf.slice(chunkSize);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
flush();
|
|
55
|
+
return chunks.map((c, i) => ({ ...c, index: i }));
|
|
56
|
+
}
|
|
57
|
+
/** Recursively splits text on the first separator that yields sub-chunkSize pieces. */
|
|
58
|
+
function splitRecursive(text, chunkSize, separators) {
|
|
59
|
+
/* istanbul ignore next -- defensive base case; callers only recurse on parts > chunkSize */
|
|
60
|
+
if (text.length <= chunkSize)
|
|
61
|
+
return [text];
|
|
62
|
+
const [sep, ...rest] = separators;
|
|
63
|
+
if (sep === undefined)
|
|
64
|
+
return [text];
|
|
65
|
+
if (sep === '') {
|
|
66
|
+
// Last resort: hard character split.
|
|
67
|
+
const out = [];
|
|
68
|
+
for (let i = 0; i < text.length; i += chunkSize)
|
|
69
|
+
out.push(text.slice(i, i + chunkSize));
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
const parts = text.split(sep);
|
|
73
|
+
const out = [];
|
|
74
|
+
for (let i = 0; i < parts.length; i++) {
|
|
75
|
+
const part = i < parts.length - 1 ? parts[i] + sep : parts[i];
|
|
76
|
+
if (part.length > chunkSize)
|
|
77
|
+
out.push(...splitRecursive(part, chunkSize, rest));
|
|
78
|
+
else
|
|
79
|
+
out.push(part);
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=chunk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk.js","sourceRoot":"","sources":["../../src/retrieval/chunk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rank fusion + diversity reranking.
|
|
3
|
+
*
|
|
4
|
+
* • Reciprocal Rank Fusion (RRF) merges the dense (vector) and sparse (BM25)
|
|
5
|
+
* rankings into one list without needing the two score scales to be
|
|
6
|
+
* commensurable — it fuses on RANK, not raw score. This is the standard,
|
|
7
|
+
* parameter-light way to combine hybrid retrieval signals.
|
|
8
|
+
* • Maximal Marginal Relevance (MMR) reranks the fused list to trade off
|
|
9
|
+
* relevance against novelty, so the top-k isn't five near-duplicate chunks.
|
|
10
|
+
*
|
|
11
|
+
* Pure and zero-dependency.
|
|
12
|
+
*/
|
|
13
|
+
export interface RankedList {
|
|
14
|
+
/** Ordered ids, most relevant first. */
|
|
15
|
+
ids: string[];
|
|
16
|
+
/** Optional weight for this list in the fusion (default 1). */
|
|
17
|
+
weight?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface FusedHit {
|
|
20
|
+
id: string;
|
|
21
|
+
score: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Reciprocal Rank Fusion over any number of ranked lists.
|
|
25
|
+
* score(d) = Σ_lists weight / (k + rank(d)). `k` (default 60) damps the
|
|
26
|
+
* contribution of low-ranked items; the canonical TREC value.
|
|
27
|
+
*/
|
|
28
|
+
export declare function reciprocalRankFusion(lists: RankedList[], k?: number): FusedHit[];
|
|
29
|
+
export interface MmrCandidate {
|
|
30
|
+
id: string;
|
|
31
|
+
vector: Float32Array;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Maximal Marginal Relevance rerank. Greedily selects up to `topK` candidates,
|
|
35
|
+
* each step maximising `λ·sim(query, d) − (1−λ)·max sim(d, already-selected)`.
|
|
36
|
+
* λ=1 is pure relevance; lower λ injects diversity. Candidates without vectors
|
|
37
|
+
* should be filtered out by the caller (they cannot be MMR-scored).
|
|
38
|
+
*/
|
|
39
|
+
export declare function maximalMarginalRelevance(queryVec: Float32Array, candidates: MmrCandidate[], topK: number, lambda?: number): string[];
|
|
40
|
+
//# sourceMappingURL=fusion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fusion.d.ts","sourceRoot":"","sources":["../../src/retrieval/fusion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,WAAW,UAAU;IACvB,wCAAwC;IACxC,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC,SAAK,GAAG,QAAQ,EAAE,CAW5E;AAED,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,YAAY,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,YAAY,EAAE,EAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,SAAM,GACb,MAAM,EAAE,CAsBV"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rank fusion + diversity reranking.
|
|
3
|
+
*
|
|
4
|
+
* • Reciprocal Rank Fusion (RRF) merges the dense (vector) and sparse (BM25)
|
|
5
|
+
* rankings into one list without needing the two score scales to be
|
|
6
|
+
* commensurable — it fuses on RANK, not raw score. This is the standard,
|
|
7
|
+
* parameter-light way to combine hybrid retrieval signals.
|
|
8
|
+
* • Maximal Marginal Relevance (MMR) reranks the fused list to trade off
|
|
9
|
+
* relevance against novelty, so the top-k isn't five near-duplicate chunks.
|
|
10
|
+
*
|
|
11
|
+
* Pure and zero-dependency.
|
|
12
|
+
*/
|
|
13
|
+
import { cosineSimilarity } from '../similarity/index.js';
|
|
14
|
+
/**
|
|
15
|
+
* Reciprocal Rank Fusion over any number of ranked lists.
|
|
16
|
+
* score(d) = Σ_lists weight / (k + rank(d)). `k` (default 60) damps the
|
|
17
|
+
* contribution of low-ranked items; the canonical TREC value.
|
|
18
|
+
*/
|
|
19
|
+
export function reciprocalRankFusion(lists, k = 60) {
|
|
20
|
+
const acc = new Map();
|
|
21
|
+
for (const list of lists) {
|
|
22
|
+
const weight = list.weight ?? 1;
|
|
23
|
+
list.ids.forEach((id, rank) => {
|
|
24
|
+
acc.set(id, (acc.get(id) ?? 0) + weight / (k + rank + 1));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return [...acc.entries()]
|
|
28
|
+
.map(([id, score]) => ({ id, score }))
|
|
29
|
+
.sort((a, b) => b.score - a.score);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Maximal Marginal Relevance rerank. Greedily selects up to `topK` candidates,
|
|
33
|
+
* each step maximising `λ·sim(query, d) − (1−λ)·max sim(d, already-selected)`.
|
|
34
|
+
* λ=1 is pure relevance; lower λ injects diversity. Candidates without vectors
|
|
35
|
+
* should be filtered out by the caller (they cannot be MMR-scored).
|
|
36
|
+
*/
|
|
37
|
+
export function maximalMarginalRelevance(queryVec, candidates, topK, lambda = 0.7) {
|
|
38
|
+
const remaining = [...candidates];
|
|
39
|
+
const selected = [];
|
|
40
|
+
const relevance = new Map();
|
|
41
|
+
for (const c of remaining)
|
|
42
|
+
relevance.set(c.id, cosineSimilarity(queryVec, c.vector));
|
|
43
|
+
while (selected.length < topK && remaining.length > 0) {
|
|
44
|
+
let bestIdx = 0;
|
|
45
|
+
let bestScore = -Infinity;
|
|
46
|
+
for (let i = 0; i < remaining.length; i++) {
|
|
47
|
+
const c = remaining[i];
|
|
48
|
+
let maxSimToSelected = 0;
|
|
49
|
+
for (const s of selected) {
|
|
50
|
+
const sim = cosineSimilarity(c.vector, s.vector);
|
|
51
|
+
if (sim > maxSimToSelected)
|
|
52
|
+
maxSimToSelected = sim;
|
|
53
|
+
}
|
|
54
|
+
const mmr = lambda * relevance.get(c.id) - (1 - lambda) * maxSimToSelected;
|
|
55
|
+
if (mmr > bestScore) {
|
|
56
|
+
bestScore = mmr;
|
|
57
|
+
bestIdx = i;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
selected.push(remaining.splice(bestIdx, 1)[0]);
|
|
61
|
+
}
|
|
62
|
+
return selected.map(s => s.id);
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=fusion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fusion.js","sourceRoot":"","sources":["../../src/retrieval/fusion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieval layer — chunking, BM25, rank fusion, and the HybridRetriever.
|
|
3
|
+
*
|
|
4
|
+
* The classic RAG pieces the memory stack previously lacked (chunking, hybrid
|
|
5
|
+
* dense+sparse search, reranking), implemented zero-dependency so they run in the
|
|
6
|
+
* browser, Node, and the SSM runtime alike.
|
|
7
|
+
*/
|
|
8
|
+
export { chunkText } from './chunk.js';
|
|
9
|
+
export type { Chunk, ChunkOptions } from './chunk.js';
|
|
10
|
+
export { bm25Search } from './bm25.js';
|
|
11
|
+
export type { Bm25Doc, Bm25Hit, Bm25Options } from './bm25.js';
|
|
12
|
+
export { reciprocalRankFusion, maximalMarginalRelevance } from './fusion.js';
|
|
13
|
+
export type { RankedList, FusedHit, MmrCandidate } from './fusion.js';
|
|
14
|
+
export { hybridRetrieve } from './HybridRetriever.js';
|
|
15
|
+
export type { RetrievalCandidate, HybridQuery, HybridRetrieveOptions, HybridHit, } from './HybridRetriever.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/retrieval/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC7E,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EACR,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,SAAS,GACZ,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieval layer — chunking, BM25, rank fusion, and the HybridRetriever.
|
|
3
|
+
*
|
|
4
|
+
* The classic RAG pieces the memory stack previously lacked (chunking, hybrid
|
|
5
|
+
* dense+sparse search, reranking), implemented zero-dependency so they run in the
|
|
6
|
+
* browser, Node, and the SSM runtime alike.
|
|
7
|
+
*/
|
|
8
|
+
export { chunkText } from './chunk.js';
|
|
9
|
+
export { bm25Search } from './bm25.js';
|
|
10
|
+
export { reciprocalRankFusion, maximalMarginalRelevance } from './fusion.js';
|
|
11
|
+
export { hybridRetrieve } from './HybridRetriever.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/retrieval/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAG7E,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configurable agent/LLM workflows — templates, a step-type registry, and a
|
|
3
|
+
* runner that produces an execution-output timeline (+ a trained `.evermind`
|
|
4
|
+
* artifact for build workflows).
|
|
5
|
+
*/
|
|
6
|
+
export type { WorkflowConfig, WorkflowStepConfig, StepTypeInfo, StepFactory } from "./types.js";
|
|
7
|
+
export { StepTypeRegistry, createDefaultRegistry, defaultStepRegistry } from "./registry.js";
|
|
8
|
+
export { BUILTIN_STEPS } from "./steps.js";
|
|
9
|
+
export { AGENTIC_SEVEN_LAYER, TRAIN_LLM, WORKFLOW_TEMPLATES, getTemplate, cloneTemplate, } from "./templates.js";
|
|
10
|
+
export { compileWorkflow, validateWorkflow, runWorkflow, buildEvermindStackSteps, type WorkflowValidationError, type RunWorkflowOptions, } from "./run.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workflow/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,kBAAkB,EAClB,WAAW,EACX,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,uBAAuB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,GACxB,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configurable agent/LLM workflows — templates, a step-type registry, and a
|
|
3
|
+
* runner that produces an execution-output timeline (+ a trained `.evermind`
|
|
4
|
+
* artifact for build workflows).
|
|
5
|
+
*/
|
|
6
|
+
export { StepTypeRegistry, createDefaultRegistry, defaultStepRegistry } from "./registry.js";
|
|
7
|
+
export { BUILTIN_STEPS } from "./steps.js";
|
|
8
|
+
export { AGENTIC_SEVEN_LAYER, TRAIN_LLM, WORKFLOW_TEMPLATES, getTemplate, cloneTemplate, } from "./templates.js";
|
|
9
|
+
export { compileWorkflow, validateWorkflow, runWorkflow, buildEvermindStackSteps, } from "./run.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workflow/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,kBAAkB,EAClB,WAAW,EACX,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,uBAAuB,GAGxB,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow/registry.ts — the step-type registry.
|
|
3
|
+
*
|
|
4
|
+
* Maps a step `type` → its factory + metadata. Built-ins are pre-registered;
|
|
5
|
+
* callers (e.g. the agent runtime) can `register` real implementations for the
|
|
6
|
+
* layers they own. Unknown types compile to a failing step so a bad workflow is
|
|
7
|
+
* localized in the timeline rather than crashing the run.
|
|
8
|
+
*/
|
|
9
|
+
import type { StepFactory, StepTypeInfo, WorkflowStepConfig } from "./types.js";
|
|
10
|
+
import type { StackStep } from "../diagnostics/stack-diagnostic.js";
|
|
11
|
+
export declare class StepTypeRegistry {
|
|
12
|
+
private readonly map;
|
|
13
|
+
register(info: StepTypeInfo, factory: StepFactory): this;
|
|
14
|
+
has(type: string): boolean;
|
|
15
|
+
/** Compile one step config to a runnable step (failing step for unknown types). */
|
|
16
|
+
build(cfg: WorkflowStepConfig): StackStep;
|
|
17
|
+
/** All registered step types — a workflow-builder palette reads this. */
|
|
18
|
+
types(): StepTypeInfo[];
|
|
19
|
+
}
|
|
20
|
+
export declare function createDefaultRegistry(): StepTypeRegistry;
|
|
21
|
+
/** Shared registry seeded with the built-in step types. */
|
|
22
|
+
export declare const defaultStepRegistry: StepTypeRegistry;
|
|
23
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/workflow/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAEpE,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAmE;IAEvF,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAKxD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,mFAAmF;IACnF,KAAK,CAAC,GAAG,EAAE,kBAAkB,GAAG,SAAS;IAezC,yEAAyE;IACzE,KAAK,IAAI,YAAY,EAAE;CAGxB;AAED,wBAAgB,qBAAqB,IAAI,gBAAgB,CAIxD;AAED,2DAA2D;AAC3D,eAAO,MAAM,mBAAmB,kBAA0B,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow/registry.ts — the step-type registry.
|
|
3
|
+
*
|
|
4
|
+
* Maps a step `type` → its factory + metadata. Built-ins are pre-registered;
|
|
5
|
+
* callers (e.g. the agent runtime) can `register` real implementations for the
|
|
6
|
+
* layers they own. Unknown types compile to a failing step so a bad workflow is
|
|
7
|
+
* localized in the timeline rather than crashing the run.
|
|
8
|
+
*/
|
|
9
|
+
import { BUILTIN_STEPS } from "./steps.js";
|
|
10
|
+
export class StepTypeRegistry {
|
|
11
|
+
map = new Map();
|
|
12
|
+
register(info, factory) {
|
|
13
|
+
this.map.set(info.type, { info, factory });
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
has(type) {
|
|
17
|
+
return this.map.has(type);
|
|
18
|
+
}
|
|
19
|
+
/** Compile one step config to a runnable step (failing step for unknown types). */
|
|
20
|
+
build(cfg) {
|
|
21
|
+
const entry = this.map.get(cfg.type);
|
|
22
|
+
if (!entry) {
|
|
23
|
+
return {
|
|
24
|
+
id: cfg.id,
|
|
25
|
+
layer: "?",
|
|
26
|
+
label: cfg.label ?? cfg.type,
|
|
27
|
+
run: async () => {
|
|
28
|
+
throw new Error(`unknown step type "${cfg.type}"`);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return entry.factory(cfg);
|
|
33
|
+
}
|
|
34
|
+
/** All registered step types — a workflow-builder palette reads this. */
|
|
35
|
+
types() {
|
|
36
|
+
return [...this.map.values()].map((e) => e.info);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function createDefaultRegistry() {
|
|
40
|
+
const r = new StepTypeRegistry();
|
|
41
|
+
for (const { info, factory } of Object.values(BUILTIN_STEPS))
|
|
42
|
+
r.register(info, factory);
|
|
43
|
+
return r;
|
|
44
|
+
}
|
|
45
|
+
/** Shared registry seeded with the built-in step types. */
|
|
46
|
+
export const defaultStepRegistry = createDefaultRegistry();
|
|
47
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/workflow/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAI3C,MAAM,OAAO,gBAAgB;IACV,GAAG,GAAG,IAAI,GAAG,EAAwD,CAAC;IAEvF,QAAQ,CAAC,IAAkB,EAAE,OAAoB;QAC/C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,mFAAmF;IACnF,KAAK,CAAC,GAAuB;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,KAAK,EAAE,GAAG;gBACV,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI;gBAC5B,GAAG,EAAE,KAAK,IAAI,EAAE;oBACd,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;gBACrD,CAAC;aACF,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,yEAAyE;IACzE,KAAK;QACH,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,CAAC,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACjC,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC;QAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow/run.ts — compile, validate, and run a workflow config.
|
|
3
|
+
*/
|
|
4
|
+
import { type RunStackOptions, type StackDiagnosticResult, type StackStep } from "../diagnostics/stack-diagnostic.js";
|
|
5
|
+
import { StepTypeRegistry } from "./registry.js";
|
|
6
|
+
import type { WorkflowConfig } from "./types.js";
|
|
7
|
+
/** Compile a workflow config to runnable steps (unknown types → failing steps). */
|
|
8
|
+
export declare function compileWorkflow(config: WorkflowConfig, registry?: StepTypeRegistry): StackStep[];
|
|
9
|
+
export interface WorkflowValidationError {
|
|
10
|
+
stepId: string;
|
|
11
|
+
type: string;
|
|
12
|
+
message: string;
|
|
13
|
+
}
|
|
14
|
+
/** Static checks before running: non-empty, unique ids, known types. */
|
|
15
|
+
export declare function validateWorkflow(config: WorkflowConfig, registry?: StepTypeRegistry): WorkflowValidationError[];
|
|
16
|
+
export interface RunWorkflowOptions extends RunStackOptions {
|
|
17
|
+
registry?: StepTypeRegistry;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Run a workflow config and return its execution-output timeline + artifacts
|
|
21
|
+
* (e.g. `result.artifacts.evermind` is the trained model for a build workflow).
|
|
22
|
+
*/
|
|
23
|
+
export declare function runWorkflow(config: WorkflowConfig, opts?: RunWorkflowOptions): Promise<StackDiagnosticResult>;
|
|
24
|
+
/** Back-compat: the 7-layer template compiled to steps (consumed by the e2e test). */
|
|
25
|
+
export declare function buildEvermindStackSteps(): StackStep[];
|
|
26
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/workflow/run.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAuB,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,GAAE,gBAAsC,GAAG,SAAS,EAAE,CAErH;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,GAAE,gBAAsC,GAAG,uBAAuB,EAAE,CAapI;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAGjH;AAED,sFAAsF;AACtF,wBAAgB,uBAAuB,IAAI,SAAS,EAAE,CAErD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow/run.ts — compile, validate, and run a workflow config.
|
|
3
|
+
*/
|
|
4
|
+
import { runStackDiagnostic, } from "../diagnostics/stack-diagnostic.js";
|
|
5
|
+
import { defaultStepRegistry } from "./registry.js";
|
|
6
|
+
import { AGENTIC_SEVEN_LAYER } from "./templates.js";
|
|
7
|
+
/** Compile a workflow config to runnable steps (unknown types → failing steps). */
|
|
8
|
+
export function compileWorkflow(config, registry = defaultStepRegistry) {
|
|
9
|
+
return config.steps.map((s) => registry.build(s));
|
|
10
|
+
}
|
|
11
|
+
/** Static checks before running: non-empty, unique ids, known types. */
|
|
12
|
+
export function validateWorkflow(config, registry = defaultStepRegistry) {
|
|
13
|
+
const errors = [];
|
|
14
|
+
if (!config.steps || config.steps.length === 0) {
|
|
15
|
+
errors.push({ stepId: "", type: "", message: "workflow has no steps" });
|
|
16
|
+
return errors;
|
|
17
|
+
}
|
|
18
|
+
const seen = new Set();
|
|
19
|
+
for (const s of config.steps) {
|
|
20
|
+
if (seen.has(s.id))
|
|
21
|
+
errors.push({ stepId: s.id, type: s.type, message: `duplicate step id "${s.id}"` });
|
|
22
|
+
seen.add(s.id);
|
|
23
|
+
if (!registry.has(s.type))
|
|
24
|
+
errors.push({ stepId: s.id, type: s.type, message: `unknown step type "${s.type}"` });
|
|
25
|
+
}
|
|
26
|
+
return errors;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Run a workflow config and return its execution-output timeline + artifacts
|
|
30
|
+
* (e.g. `result.artifacts.evermind` is the trained model for a build workflow).
|
|
31
|
+
*/
|
|
32
|
+
export function runWorkflow(config, opts = {}) {
|
|
33
|
+
const { registry = defaultStepRegistry, ...runOpts } = opts;
|
|
34
|
+
return runStackDiagnostic(compileWorkflow(config, registry), runOpts);
|
|
35
|
+
}
|
|
36
|
+
/** Back-compat: the 7-layer template compiled to steps (consumed by the e2e test). */
|
|
37
|
+
export function buildEvermindStackSteps() {
|
|
38
|
+
return compileWorkflow(AGENTIC_SEVEN_LAYER);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/workflow/run.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,kBAAkB,GAInB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAoB,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGrD,mFAAmF;AACnF,MAAM,UAAU,eAAe,CAAC,MAAsB,EAAE,WAA6B,mBAAmB;IACtG,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAQD,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,MAAsB,EAAE,WAA6B,mBAAmB;IACvG,MAAM,MAAM,GAA8B,EAAE,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAC;QACxE,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACxG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACf,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACnH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAMD;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAsB,EAAE,OAA2B,EAAE;IAC/E,MAAM,EAAE,QAAQ,GAAG,mBAAmB,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5D,OAAO,kBAAkB,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACxE,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,uBAAuB;IACrC,OAAO,eAAe,CAAC,mBAAmB,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow/steps.ts — the built-in step types.
|
|
3
|
+
*
|
|
4
|
+
* Two families, both compiling to a runnable {@link StackStep}:
|
|
5
|
+
* • Agent-stack layers (L1..L7) — the diagnostic checks (the 7-layer template).
|
|
6
|
+
* • LLM-creation pipeline (BUILD) — train-tokenizer → train-model → evaluate →
|
|
7
|
+
* package, which produces a trained `.evermind` artifact (a custom LLM) into
|
|
8
|
+
* `ctx.artifacts.evermind`.
|
|
9
|
+
*
|
|
10
|
+
* A custom workflow mixes these freely; new step types register the same way.
|
|
11
|
+
*/
|
|
12
|
+
import type { StepFactory, StepTypeInfo } from "./types.js";
|
|
13
|
+
interface Registered {
|
|
14
|
+
info: StepTypeInfo;
|
|
15
|
+
factory: StepFactory;
|
|
16
|
+
}
|
|
17
|
+
export declare const BUILTIN_STEPS: Record<string, Registered>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=steps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../src/workflow/steps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAYH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAsB,MAAM,YAAY,CAAC;AAgChF,UAAU,UAAU;IAClB,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAyQpD,CAAC"}
|