@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.
Files changed (108) hide show
  1. package/AGENTS.md +43 -4
  2. package/DATASETS.md +160 -0
  3. package/README.md +12 -0
  4. package/dist/example/train_base/cache.d.ts +35 -0
  5. package/dist/example/train_base/cache.js +211 -0
  6. package/dist/example/train_base/config.d.ts +21 -0
  7. package/dist/example/train_base/config.js +94 -0
  8. package/dist/example/train_base/corpora/aya.d.ts +19 -0
  9. package/dist/example/train_base/corpora/aya.js +76 -0
  10. package/dist/example/train_base/corpora/converted-parquet.d.ts +14 -0
  11. package/dist/example/train_base/corpora/converted-parquet.js +44 -0
  12. package/dist/example/train_base/corpora/genknow.d.ts +14 -0
  13. package/dist/example/train_base/corpora/genknow.js +83 -0
  14. package/dist/example/train_base/corpora/index.d.ts +29 -0
  15. package/dist/example/train_base/corpora/index.js +81 -0
  16. package/dist/example/train_base/corpora/massive.d.ts +7 -0
  17. package/dist/example/train_base/corpora/massive.js +98 -0
  18. package/dist/example/train_base/corpora/oasst2.d.ts +52 -0
  19. package/dist/example/train_base/corpora/oasst2.js +120 -0
  20. package/dist/example/train_base/corpora/smolsent.d.ts +23 -0
  21. package/dist/example/train_base/corpora/smolsent.js +156 -0
  22. package/dist/example/train_base/corpora/soda.d.ts +12 -0
  23. package/dist/example/train_base/corpora/soda.js +113 -0
  24. package/dist/example/train_base/corpora/taskmaster.d.ts +15 -0
  25. package/dist/example/train_base/corpora/taskmaster.js +144 -0
  26. package/dist/example/train_base/corpora/wiki2.d.ts +23 -0
  27. package/dist/example/train_base/corpora/wiki2.js +132 -0
  28. package/dist/example/train_base/corpus.d.ts +88 -0
  29. package/dist/example/train_base/corpus.js +65 -0
  30. package/dist/example/train_base/discovery.d.ts +48 -0
  31. package/dist/example/train_base/discovery.js +143 -0
  32. package/dist/example/train_base/http.d.ts +82 -0
  33. package/dist/example/train_base/http.js +219 -0
  34. package/dist/example/train_base/items.d.ts +46 -0
  35. package/dist/example/train_base/items.js +98 -0
  36. package/dist/example/train_base/main.d.ts +4 -0
  37. package/dist/example/train_base/main.js +207 -0
  38. package/dist/example/train_base/progress.d.ts +34 -0
  39. package/dist/example/train_base/progress.js +114 -0
  40. package/dist/example/train_base/readers.d.ts +125 -0
  41. package/dist/example/train_base/readers.js +391 -0
  42. package/dist/example/train_base/runtime.d.ts +115 -0
  43. package/dist/example/train_base/runtime.js +637 -0
  44. package/dist/example/train_base/stage.d.ts +3 -0
  45. package/dist/example/train_base/stage.js +246 -0
  46. package/dist/example/train_base/ui.d.ts +88 -0
  47. package/dist/example/train_base/ui.js +272 -0
  48. package/dist/src/geometry.d.ts +20 -0
  49. package/dist/src/geometry.js +22 -0
  50. package/dist/src/mind/attention.d.ts +6 -0
  51. package/dist/src/mind/attention.js +44 -4
  52. package/dist/src/mind/learning.js +134 -50
  53. package/dist/src/mind/mechanisms/cast.js +45 -1
  54. package/dist/src/mind/mind.d.ts +7 -2
  55. package/dist/src/mind/mind.js +15 -3
  56. package/dist/src/mind/reasoning.js +59 -5
  57. package/dist/src/mind/recognition.js +29 -3
  58. package/dist/src/mind/traverse.d.ts +16 -0
  59. package/dist/src/mind/traverse.js +18 -0
  60. package/dist/src/store-sqlite.d.ts +4 -0
  61. package/dist/src/store-sqlite.js +47 -0
  62. package/dist/src/store.d.ts +7 -0
  63. package/example/train_base/cache.ts +251 -0
  64. package/example/train_base/config.ts +128 -0
  65. package/example/train_base/corpora/aya.ts +106 -0
  66. package/example/train_base/corpora/converted-parquet.ts +64 -0
  67. package/example/train_base/corpora/genknow.ts +114 -0
  68. package/example/train_base/corpora/index.ts +88 -0
  69. package/example/train_base/corpora/massive.ts +111 -0
  70. package/example/train_base/corpora/oasst2.ts +163 -0
  71. package/example/train_base/corpora/smolsent.ts +203 -0
  72. package/example/train_base/corpora/soda.ts +130 -0
  73. package/example/train_base/corpora/taskmaster.ts +217 -0
  74. package/example/train_base/corpora/wiki2.ts +190 -0
  75. package/example/train_base/corpus.ts +150 -0
  76. package/example/train_base/discovery.ts +203 -0
  77. package/example/train_base/http.ts +284 -0
  78. package/example/train_base/items.ts +118 -0
  79. package/example/train_base/main.ts +240 -0
  80. package/example/train_base/progress.ts +149 -0
  81. package/example/train_base/readers.ts +505 -0
  82. package/example/train_base/runtime.ts +894 -0
  83. package/example/train_base/stage.ts +276 -0
  84. package/example/train_base/ui.ts +333 -0
  85. package/jsr.json +1 -1
  86. package/package.json +2 -4
  87. package/src/geometry.ts +23 -0
  88. package/src/mind/attention.ts +54 -1
  89. package/src/mind/learning.ts +137 -43
  90. package/src/mind/mechanisms/cast.ts +48 -1
  91. package/src/mind/mind.ts +13 -2
  92. package/src/mind/reasoning.ts +64 -5
  93. package/src/mind/recognition.ts +29 -3
  94. package/src/mind/traverse.ts +19 -0
  95. package/src/store-sqlite.ts +53 -0
  96. package/src/store.ts +28 -0
  97. package/test/13-conversation.test.mjs +1 -1
  98. package/test/29-counterfactual.test.mjs +43 -6
  99. package/test/77-company-saturation.test.mjs +302 -0
  100. package/test/78-atom-hub-recognition-cliff.test.mjs +135 -0
  101. package/test/84-composed-answer-honesty.test.mjs +137 -0
  102. package/test/85-answered-directly.test.mjs +126 -0
  103. package/test/86-cast-voices-committed.test.mjs +164 -0
  104. package/test/87-codominant-commitment.test.mjs +250 -0
  105. package/test/88-dependency-footprint.test.mjs +99 -0
  106. package/dist/example/train_base.d.ts +0 -93
  107. package/dist/example/train_base.js +0 -2269
  108. 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 {};