@hviana/sema 0.5.8 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +43 -4
- package/DATASETS.md +160 -0
- package/README.md +12 -0
- package/dist/example/train_base/cache.d.ts +35 -0
- package/dist/example/train_base/cache.js +211 -0
- package/dist/example/train_base/config.d.ts +21 -0
- package/dist/example/train_base/config.js +94 -0
- package/dist/example/train_base/corpora/aya.d.ts +19 -0
- package/dist/example/train_base/corpora/aya.js +76 -0
- package/dist/example/train_base/corpora/converted-parquet.d.ts +14 -0
- package/dist/example/train_base/corpora/converted-parquet.js +44 -0
- package/dist/example/train_base/corpora/genknow.d.ts +14 -0
- package/dist/example/train_base/corpora/genknow.js +83 -0
- package/dist/example/train_base/corpora/index.d.ts +29 -0
- package/dist/example/train_base/corpora/index.js +81 -0
- package/dist/example/train_base/corpora/massive.d.ts +7 -0
- package/dist/example/train_base/corpora/massive.js +98 -0
- package/dist/example/train_base/corpora/oasst2.d.ts +52 -0
- package/dist/example/train_base/corpora/oasst2.js +120 -0
- package/dist/example/train_base/corpora/smolsent.d.ts +23 -0
- package/dist/example/train_base/corpora/smolsent.js +156 -0
- package/dist/example/train_base/corpora/soda.d.ts +12 -0
- package/dist/example/train_base/corpora/soda.js +113 -0
- package/dist/example/train_base/corpora/taskmaster.d.ts +15 -0
- package/dist/example/train_base/corpora/taskmaster.js +144 -0
- package/dist/example/train_base/corpora/wiki2.d.ts +23 -0
- package/dist/example/train_base/corpora/wiki2.js +132 -0
- package/dist/example/train_base/corpus.d.ts +88 -0
- package/dist/example/train_base/corpus.js +65 -0
- package/dist/example/train_base/discovery.d.ts +48 -0
- package/dist/example/train_base/discovery.js +143 -0
- package/dist/example/train_base/http.d.ts +82 -0
- package/dist/example/train_base/http.js +219 -0
- package/dist/example/train_base/items.d.ts +46 -0
- package/dist/example/train_base/items.js +98 -0
- package/dist/example/train_base/main.d.ts +4 -0
- package/dist/example/train_base/main.js +207 -0
- package/dist/example/train_base/progress.d.ts +34 -0
- package/dist/example/train_base/progress.js +114 -0
- package/dist/example/train_base/readers.d.ts +125 -0
- package/dist/example/train_base/readers.js +391 -0
- package/dist/example/train_base/runtime.d.ts +115 -0
- package/dist/example/train_base/runtime.js +637 -0
- package/dist/example/train_base/stage.d.ts +3 -0
- package/dist/example/train_base/stage.js +246 -0
- package/dist/example/train_base/ui.d.ts +88 -0
- package/dist/example/train_base/ui.js +272 -0
- package/dist/src/geometry.d.ts +20 -0
- package/dist/src/geometry.js +22 -0
- package/dist/src/mind/attention.d.ts +6 -0
- package/dist/src/mind/attention.js +44 -4
- package/dist/src/mind/learning.js +134 -50
- package/dist/src/mind/mechanisms/cast.js +45 -1
- package/dist/src/mind/mind.d.ts +7 -2
- package/dist/src/mind/mind.js +15 -3
- package/dist/src/mind/reasoning.js +59 -5
- package/dist/src/mind/recognition.js +29 -3
- package/dist/src/mind/traverse.d.ts +16 -0
- package/dist/src/mind/traverse.js +18 -0
- package/dist/src/store-sqlite.d.ts +4 -0
- package/dist/src/store-sqlite.js +47 -0
- package/dist/src/store.d.ts +7 -0
- package/example/train_base/cache.ts +251 -0
- package/example/train_base/config.ts +128 -0
- package/example/train_base/corpora/aya.ts +106 -0
- package/example/train_base/corpora/converted-parquet.ts +64 -0
- package/example/train_base/corpora/genknow.ts +114 -0
- package/example/train_base/corpora/index.ts +88 -0
- package/example/train_base/corpora/massive.ts +111 -0
- package/example/train_base/corpora/oasst2.ts +163 -0
- package/example/train_base/corpora/smolsent.ts +203 -0
- package/example/train_base/corpora/soda.ts +130 -0
- package/example/train_base/corpora/taskmaster.ts +217 -0
- package/example/train_base/corpora/wiki2.ts +190 -0
- package/example/train_base/corpus.ts +150 -0
- package/example/train_base/discovery.ts +203 -0
- package/example/train_base/http.ts +284 -0
- package/example/train_base/items.ts +118 -0
- package/example/train_base/main.ts +240 -0
- package/example/train_base/progress.ts +149 -0
- package/example/train_base/readers.ts +505 -0
- package/example/train_base/runtime.ts +894 -0
- package/example/train_base/stage.ts +276 -0
- package/example/train_base/ui.ts +333 -0
- package/jsr.json +1 -1
- package/package.json +2 -4
- package/src/geometry.ts +23 -0
- package/src/mind/attention.ts +54 -1
- package/src/mind/learning.ts +137 -43
- package/src/mind/mechanisms/cast.ts +48 -1
- package/src/mind/mind.ts +13 -2
- package/src/mind/reasoning.ts +64 -5
- package/src/mind/recognition.ts +29 -3
- package/src/mind/traverse.ts +19 -0
- package/src/store-sqlite.ts +53 -0
- package/src/store.ts +28 -0
- package/test/13-conversation.test.mjs +1 -1
- package/test/29-counterfactual.test.mjs +43 -6
- package/test/77-company-saturation.test.mjs +302 -0
- package/test/78-atom-hub-recognition-cliff.test.mjs +135 -0
- package/test/84-composed-answer-honesty.test.mjs +137 -0
- package/test/85-answered-directly.test.mjs +126 -0
- package/test/86-cast-voices-committed.test.mjs +164 -0
- package/test/87-codominant-commitment.test.mjs +250 -0
- package/test/88-dependency-footprint.test.mjs +99 -0
- package/dist/example/train_base.d.ts +0 -93
- package/dist/example/train_base.js +0 -2269
- package/example/train_base.ts +0 -2735
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// 88 — the dependency footprint is a PRODUCT PROPERTY, so it is tested.
|
|
2
|
+
//
|
|
3
|
+
// AGENTS.md §6: "do not add runtime dependencies casually — the near-zero-
|
|
4
|
+
// dependency footprint is a product feature." A feature stated only in prose
|
|
5
|
+
// erodes; this suite pins it at the two places it can actually break.
|
|
6
|
+
//
|
|
7
|
+
// 1. The BUILT LIBRARY imports nothing outside `node:`. Not the source — the
|
|
8
|
+
// built output, because that is what a consumer loads.
|
|
9
|
+
// 2. The PACKAGE declares no runtime `dependencies`. A package can be
|
|
10
|
+
// import-clean and still force installs on every consumer; that is exactly
|
|
11
|
+
// how `hyparquet` — used only by example/train_base, never by src/ — came
|
|
12
|
+
// to be installed by everyone who depended on Sema.
|
|
13
|
+
//
|
|
14
|
+
// The trainer example is deliberately NOT covered: it may use whatever it
|
|
15
|
+
// needs, as a dev dependency, loaded lazily (see example/train_base/readers.ts).
|
|
16
|
+
|
|
17
|
+
import { test } from "node:test";
|
|
18
|
+
import assert from "node:assert/strict";
|
|
19
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
|
|
22
|
+
const ROOT = new URL("..", import.meta.url).pathname;
|
|
23
|
+
|
|
24
|
+
/** Every built .js file of the library itself. */
|
|
25
|
+
function libFiles(dir = join(ROOT, "dist/src"), out = []) {
|
|
26
|
+
for (const name of readdirSync(dir)) {
|
|
27
|
+
const p = join(dir, name);
|
|
28
|
+
if (statSync(p).isDirectory()) libFiles(p, out);
|
|
29
|
+
else if (name.endsWith(".js")) out.push(p);
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Module specifiers of static imports/exports and dynamic import() calls. */
|
|
35
|
+
function specifiersOf(src) {
|
|
36
|
+
const out = [];
|
|
37
|
+
const patterns = [
|
|
38
|
+
/(?:^|\s)(?:import|export)\s[^;]*?from\s*["']([^"']+)["']/g,
|
|
39
|
+
/(?:^|\s)import\s*["']([^"']+)["']/g,
|
|
40
|
+
/\bimport\s*\(\s*["']([^"']+)["']\s*\)/g,
|
|
41
|
+
/\brequire\s*\(\s*["']([^"']+)["']\s*\)/g,
|
|
42
|
+
];
|
|
43
|
+
for (const re of patterns) {
|
|
44
|
+
for (const m of src.matchAll(re)) out.push(m[1]);
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
test("the built library imports nothing outside node: builtins", () => {
|
|
50
|
+
const files = libFiles();
|
|
51
|
+
assert.ok(files.length > 0, "dist/src is empty — run `npm run build` first");
|
|
52
|
+
|
|
53
|
+
const foreign = [];
|
|
54
|
+
for (const file of files) {
|
|
55
|
+
for (const spec of specifiersOf(readFileSync(file, "utf8"))) {
|
|
56
|
+
const ok = spec.startsWith("./") || spec.startsWith("../") ||
|
|
57
|
+
spec.startsWith("node:");
|
|
58
|
+
if (!ok) foreign.push(`${file.slice(ROOT.length)} → ${spec}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
assert.deepEqual(
|
|
62
|
+
foreign,
|
|
63
|
+
[],
|
|
64
|
+
"the library gained a third-party import; keep it in an example instead",
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("the package forces no runtime dependencies on consumers", () => {
|
|
69
|
+
const pkg = JSON.parse(
|
|
70
|
+
readFileSync(join(ROOT, "package.json"), "utf8"),
|
|
71
|
+
);
|
|
72
|
+
const deps = Object.keys(pkg.dependencies ?? {});
|
|
73
|
+
assert.deepEqual(
|
|
74
|
+
deps,
|
|
75
|
+
[],
|
|
76
|
+
"a package a consumer installs must not carry dependencies only an " +
|
|
77
|
+
"example needs — declare them under devDependencies",
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("the published entry points resolve inside dist/src", () => {
|
|
82
|
+
// A `main`/`exports` that reached outside dist/src would drag the example —
|
|
83
|
+
// and its dev dependencies — into a consumer's module graph.
|
|
84
|
+
const pkg = JSON.parse(readFileSync(join(ROOT, "package.json"), "utf8"));
|
|
85
|
+
const entries = [
|
|
86
|
+
pkg.main,
|
|
87
|
+
pkg.types,
|
|
88
|
+
pkg.exports?.["."]?.default,
|
|
89
|
+
pkg.exports?.["."]?.types,
|
|
90
|
+
].filter(Boolean);
|
|
91
|
+
assert.ok(entries.length > 0, "no entry points declared");
|
|
92
|
+
for (const e of entries) {
|
|
93
|
+
assert.match(
|
|
94
|
+
e,
|
|
95
|
+
/^(\.\/)?dist\/src\//,
|
|
96
|
+
`entry point "${e}" escapes dist/src`,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
export interface Episode {
|
|
2
|
-
context: string;
|
|
3
|
-
continuation: string;
|
|
4
|
-
}
|
|
5
|
-
export type TrainingItem = string | Episode;
|
|
6
|
-
/** Dedup + trim a concept's items: drop empty/degenerate pairs and exact
|
|
7
|
-
* repeats so a concept never deposits the same form twice. */
|
|
8
|
-
export declare function refineItems(items: TrainingItem[]): TrainingItem[];
|
|
9
|
-
/** One normalized SmolSent row. */
|
|
10
|
-
export interface SmolSentRow {
|
|
11
|
-
src: string;
|
|
12
|
-
trg: string;
|
|
13
|
-
sl: string;
|
|
14
|
-
tl: string;
|
|
15
|
-
}
|
|
16
|
-
/** Normalize a raw datasets-server row into a SmolSentRow, or null when it lacks
|
|
17
|
-
* both sides or a side is implausibly large (a dump, not a sentence). */
|
|
18
|
-
export declare function toSmolSentRow(row: unknown): SmolSentRow | null;
|
|
19
|
-
/** Translate ONE SmolSent pair into SEMA facts: the two sentences are one
|
|
20
|
-
* meaning in two languages, so bind them BOTH ways. refineItems drops the
|
|
21
|
-
* degenerate case where src === trg. */
|
|
22
|
-
export declare function smolSentRowToItems(row: SmolSentRow): TrainingItem[];
|
|
23
|
-
/** One normalized Aya row. */
|
|
24
|
-
export interface AyaRow {
|
|
25
|
-
inputs: string;
|
|
26
|
-
targets: string;
|
|
27
|
-
language: string;
|
|
28
|
-
}
|
|
29
|
-
/** Normalize a raw datasets-server row object into an AyaRow, or null when it
|
|
30
|
-
* lacks a usable prompt/answer or a field is implausibly large (a dump, not a
|
|
31
|
-
* cognitive example). Trims surrounding whitespace; keeps inner text verbatim
|
|
32
|
-
* (human prose, possibly multi-paragraph). */
|
|
33
|
-
export declare function toAyaRow(row: unknown): AyaRow | null;
|
|
34
|
-
/** Translate ONE Aya row into SEMA training items. A row is a single human
|
|
35
|
-
* (question → answer) exchange — exactly one FACT, the (inputs → targets) edge.
|
|
36
|
-
* No standalone-answer experience and no one-exchange "cumulative" walk: a lone
|
|
37
|
-
* Q→A is not multi-turn, and both would only replicate the same edge. */
|
|
38
|
-
export declare function ayaRowToItems(row: AyaRow): TrainingItem[];
|
|
39
|
-
/** A single oasst2 message node (the fields we use; the tree nests via replies). */
|
|
40
|
-
interface OasstNode {
|
|
41
|
-
role?: string;
|
|
42
|
-
text?: string;
|
|
43
|
-
rank?: number | null;
|
|
44
|
-
deleted?: boolean;
|
|
45
|
-
replies?: OasstNode[];
|
|
46
|
-
}
|
|
47
|
-
/** One conversational turn extracted from a tree. */
|
|
48
|
-
export interface OasstTurn {
|
|
49
|
-
role: string;
|
|
50
|
-
text: string;
|
|
51
|
-
}
|
|
52
|
-
/** Collapse a conversation tree to ONE linear path: at each node, descend into
|
|
53
|
-
* its best-ranked, non-deleted reply (rank 0 preferred; unranked sorts last).
|
|
54
|
-
* Returns the ordered turns (already strictly alternating in this corpus). */
|
|
55
|
-
export declare function bestOasstPath(root: OasstNode): OasstTurn[];
|
|
56
|
-
/** Translate ONE multi-turn oasst2 conversation into SEMA training items.
|
|
57
|
-
*
|
|
58
|
-
* This is the ONE stage where cumulative continuous context is truly necessary:
|
|
59
|
-
* the data is a real multi-turn dialogue, and what must be learned is how each
|
|
60
|
-
* turn follows from the WHOLE conversation so far — not from the previous turn
|
|
61
|
-
* alone. The conversation is emitted ONLY as the accumulated walk; standalone
|
|
62
|
-
* turn experiences and local adjacent-pair facts are NOT emitted (they are
|
|
63
|
-
* subsumed by it and would merely replicate the content).
|
|
64
|
-
*
|
|
65
|
-
* The walk is the pattern proven in test/13-conversation.test.mjs
|
|
66
|
-
* ("teachConversation"): each turn is the continuation of all prior turns,
|
|
67
|
-
* with BARE turn text — NO "User:/Assistant:" labels. The SHAPE is identical
|
|
68
|
-
* (cumulative context → next turn); the join string is not, and does not need
|
|
69
|
-
* to be — that file joins with nothing and this corpus joins with "\n" (see
|
|
70
|
-
* `accumulate`). Saying "byte-for-byte", as this comment used to, invites the
|
|
71
|
-
* reading that the two must agree on a separator. They must not agree,
|
|
72
|
-
* because there is nothing to agree about: turn boundaries are offsets, and
|
|
73
|
-
* the join string is just corpus text. Roles already
|
|
74
|
-
* alternate by position in an oasst2 best-path (the root is a prompter), so a
|
|
75
|
-
* label adds nothing the position does not, while a clean continuation matches
|
|
76
|
-
* the test's recall (predictNext queries bare prior turns) and lets a turn share
|
|
77
|
-
* its gist with the same text elsewhere (e.g. an Aya question stored bare).
|
|
78
|
-
*
|
|
79
|
-
* Returns [] for a conversation below the multi-turn threshold, so callers can
|
|
80
|
-
* simply skip empties. */
|
|
81
|
-
export declare function oasstConversationToItems(turns: OasstTurn[]): TrainingItem[];
|
|
82
|
-
/** One normalized General-Knowledge row. */
|
|
83
|
-
export interface GenKnowRow {
|
|
84
|
-
question: string;
|
|
85
|
-
answer: string;
|
|
86
|
-
}
|
|
87
|
-
/** Normalize a raw datasets-server row into a GenKnowRow, or null when it lacks
|
|
88
|
-
* a usable question/answer or a side is implausibly large (corruption). */
|
|
89
|
-
export declare function toGenKnowRow(row: unknown): GenKnowRow | null;
|
|
90
|
-
/** Translate ONE General-Knowledge row into SEMA items: exactly one
|
|
91
|
-
* (question → answer) FACT. refineItems drops a degenerate question === answer. */
|
|
92
|
-
export declare function genKnowRowToItems(row: GenKnowRow): TrainingItem[];
|
|
93
|
-
export {};
|