@openfluke/welvet 0.2.0 → 0.74.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/dist/index.js CHANGED
@@ -1,95 +1,181 @@
1
1
  /**
2
- * @openfluke/welvet - Isomorphic WASM Wrapper
2
+ * @openfluke/welvet — M-POLY-VTD AI Engine
3
3
  *
4
- * Direct wrapper around Loom WASM that mirrors main.go exports exactly.
5
- * Provides the same API in both Node.js and browser environments.
4
+ * Isomorphic TypeScript wrapper for the Loom v0.73.0 WASM module.
5
+ * Supports Node.js and browser environments.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { init, createNetwork, DType } from "@openfluke/welvet";
10
+ *
11
+ * await init();
12
+ *
13
+ * const net = createNetwork({
14
+ * layers: [
15
+ * { type: "dense", input_height: 4, output_height: 8 },
16
+ * { type: "dense", input_height: 8, output_height: 2 },
17
+ * ]
18
+ * });
19
+ *
20
+ * const output = net.sequentialForward(new Float32Array([1, 0, 0, 1]));
21
+ * console.log(output); // Float32Array [...]
22
+ * ```
6
23
  */
7
- import { loadLoomWASM } from "./loader.js";
8
24
  import { loadLoomWASMBrowser } from "./loader.browser.js";
25
+ // Re-export all types and constants
9
26
  export * from "./types.js";
10
- export { loadLoomWASM, loadLoomWASMBrowser };
27
+ export { loadLoomWASMBrowser };
28
+ // ──────────────────────────────────────────────────────────────────────────────
29
+ // Initialization
30
+ // ──────────────────────────────────────────────────────────────────────────────
11
31
  /**
12
- * Initialize WASM for Node.js environment
32
+ * Initialize the welvet WASM module.
33
+ * Auto-detects Node.js vs browser environment.
34
+ *
35
+ * @param wasmUrl Optional custom URL for browser WASM loading (default: /dist/main.wasm)
13
36
  */
14
- export async function init() {
15
- await loadLoomWASM();
37
+ export async function init(wasmUrl) {
38
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
39
+ return loadLoomWASMBrowser(wasmUrl);
40
+ }
41
+ const mod = await import("./loader.js");
42
+ return mod.loadLoomWASM();
16
43
  }
17
44
  /**
18
- * Initialize WASM for Browser environment
45
+ * Initialize explicitly for browser environments.
46
+ * @param wasmUrl Optional custom URL for WASM binary
19
47
  */
20
- export async function initBrowser() {
21
- await loadLoomWASMBrowser();
48
+ export async function initBrowser(wasmUrl) {
49
+ return loadLoomWASMBrowser(wasmUrl);
22
50
  }
51
+ // ──────────────────────────────────────────────────────────────────────────────
52
+ // Network Lifecycle
53
+ // ──────────────────────────────────────────────────────────────────────────────
23
54
  /**
24
- * Create a network from JSON config
25
- * Wrapper around the global createLoomNetwork function exposed by WASM
55
+ * Build a VolumetricNetwork from a JSON configuration object or string.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const net = createNetwork({
60
+ * layers: [
61
+ * { type: "dense", input_height: 784, output_height: 256 },
62
+ * { type: "dense", input_height: 256, output_height: 10, activation: "silu" },
63
+ * ]
64
+ * });
65
+ * ```
26
66
  */
27
67
  export function createNetwork(config) {
28
- const jsonConfig = typeof config === "string"
29
- ? config
30
- : JSON.stringify(config);
68
+ const jsonConfig = typeof config === "string" ? config : JSON.stringify(config);
31
69
  return createLoomNetwork(jsonConfig);
32
70
  }
33
71
  /**
34
- * Create a network handle for grafting
72
+ * Load a pre-trained network from a SafeTensors file path.
73
+ * (Node.js only — requires file system access)
74
+ *
75
+ * @param path Absolute or relative path to a .safetensors file
35
76
  */
36
- export function createKHandle(config) {
37
- const jsonConfig = typeof config === "string" ? config : JSON.stringify(config);
38
- return createNetworkForGraft(jsonConfig);
77
+ export function loadNetwork(path) {
78
+ return loadLoomNetwork(path);
39
79
  }
80
+ // ──────────────────────────────────────────────────────────────────────────────
81
+ // WebGPU
82
+ // ──────────────────────────────────────────────────────────────────────────────
40
83
  /**
41
- * Graft multiple networks together
84
+ * Initialize WebGPU (browser only).
85
+ * Sets window.webgpuAdapter, window.webgpuDevice, window.webgpuQueue.
42
86
  */
43
- export function graft(ids, combineMode) {
44
- const idsJSON = JSON.stringify(ids);
45
- const resJSON = graftNetworks(idsJSON, combineMode);
46
- return JSON.parse(resJSON);
87
+ export async function setupWebGPU() {
88
+ // @ts-ignore setupWebGPU is injected by the WASM module
89
+ return setupWebGPU();
47
90
  }
91
+ // ──────────────────────────────────────────────────────────────────────────────
92
+ // DNA / Introspection
93
+ // ──────────────────────────────────────────────────────────────────────────────
48
94
  /**
49
- * Perform K-Means Clustering
95
+ * Compare the architectural DNA of two networks.
96
+ *
97
+ * @param dnaA JSON string from network.extractDNA()
98
+ * @param dnaB JSON string from network.extractDNA()
99
+ * @returns DNACompareResult
50
100
  */
51
- export function kmeans(data, k, iter) {
52
- const resJSON = kmeansCluster(JSON.stringify(data), k, iter);
53
- return JSON.parse(resJSON);
101
+ export function compareDNA(dnaA, dnaB) {
102
+ return JSON.parse(compareLoomDNA(dnaA, dnaB));
54
103
  }
55
104
  /**
56
- * Compute Correlation Matrix
105
+ * Get the default TargetPropConfig.
57
106
  */
58
- export function correlation(matrixA, matrixB) {
59
- const jsonA = JSON.stringify(matrixA);
60
- const jsonB = matrixB ? JSON.stringify(matrixB) : "null"; // Use "null" string for nil
61
- const resJSON = computeCorrelation(jsonA, jsonB);
62
- const raw = JSON.parse(resJSON);
63
- // Transform to match interface
64
- return {
65
- pearson: raw.correlation?.matrix || raw.Correlation?.Matrix || raw.matrix || [],
66
- spearman: raw.spearman?.matrix || raw.Spearman?.Matrix || []
67
- };
107
+ export function defaultTargetPropConfig() {
108
+ return JSON.parse(getDefaultTargetPropConfig());
68
109
  }
110
+ // ──────────────────────────────────────────────────────────────────────────────
111
+ // Training Helpers
112
+ // ──────────────────────────────────────────────────────────────────────────────
69
113
  /**
70
- * Find Complementary Ensemble Matches
114
+ * Convenience wrapper for network.train() that handles JSON serialization.
115
+ *
116
+ * @param network The network to train
117
+ * @param batches Array of {input, target} training pairs
118
+ * @param epochs Number of training epochs
119
+ * @param lr Learning rate
71
120
  */
72
- export function ensemble(models, minCoverage) {
73
- const resJSON = findComplementaryMatches(JSON.stringify(models), minCoverage);
74
- return JSON.parse(resJSON);
121
+ export function trainNetwork(network, batches, epochs, lr) {
122
+ const serialized = batches.map((b) => {
123
+ const inp = b.input instanceof Float32Array ? b.input : new Float32Array(b.input);
124
+ const tgt = b.target instanceof Float32Array ? b.target : new Float32Array(b.target);
125
+ const inShape = b.inputShape ?? [1, inp.length];
126
+ const tgtShape = b.targetShape ?? [1, tgt.length];
127
+ return {
128
+ input: { shape: inShape, data: Array.from(inp) },
129
+ target: { shape: tgtShape, data: Array.from(tgt) },
130
+ };
131
+ });
132
+ return JSON.parse(network.train(JSON.stringify(serialized), epochs, lr));
75
133
  }
76
- /**
77
- * Create Adaptation Tracker
78
- */
79
- export function tracker(windowMs, totalMs) {
80
- return createAdaptationTracker(windowMs, totalMs);
134
+ // ──────────────────────────────────────────────────────────────────────────────
135
+ // Evolution / DNA
136
+ // ──────────────────────────────────────────────────────────────────────────────
137
+ /** Get the default SpliceConfig as a plain object. */
138
+ export function getSpliceConfig() {
139
+ return JSON.parse(globalThis["defaultSpliceConfig"]());
140
+ }
141
+ /** Get the default NEATConfig as a plain object. */
142
+ export function getNEATConfig(dModel) {
143
+ return JSON.parse(globalThis["defaultNEATConfig"](dModel));
81
144
  }
82
145
  /**
83
- * Default export with all functions
146
+ * Create a NEAT population from a seed network.
147
+ * @param network Seed network (its _id is used)
148
+ * @param size Population size
149
+ * @param cfg NEATConfig object or JSON string (defaults to getNEATConfig(64))
84
150
  */
151
+ export function createNEATPopulation(network, size, cfg) {
152
+ const cfgJSON = cfg
153
+ ? (typeof cfg === "string" ? cfg : JSON.stringify(cfg))
154
+ : globalThis["defaultNEATConfig"](64);
155
+ return globalThis["createLoomNEATPopulation"](network._id, size, cfgJSON);
156
+ }
157
+ // ──────────────────────────────────────────────────────────────────────────────
158
+ // Default export
159
+ // ──────────────────────────────────────────────────────────────────────────────
85
160
  export default {
86
161
  init,
87
162
  initBrowser,
88
163
  createNetwork,
89
- createKHandle,
90
- graft,
91
- kmeans,
92
- correlation,
93
- ensemble,
94
- tracker
164
+ loadNetwork,
165
+ setupWebGPU,
166
+ compareDNA,
167
+ defaultTargetPropConfig,
168
+ trainNetwork,
169
+ getSpliceConfig,
170
+ getNEATConfig,
171
+ createNEATPopulation,
172
+ // Re-export constants for convenience
173
+ DType: {
174
+ FLOAT64: 0, FLOAT32: 1, FLOAT16: 2, BFLOAT16: 3,
175
+ FP8_E4M3: 4, FP8_E5M2: 5,
176
+ INT64: 6, INT32: 7, INT16: 8, INT8: 9,
177
+ UINT64: 10, UINT32: 11, UINT16: 12, UINT8: 13,
178
+ INT4: 14, UINT4: 15, FP4: 16,
179
+ INT2: 17, UINT2: 18, TERNARY: 19, BINARY: 20,
180
+ },
95
181
  };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * LOOM WASM Browser Loader
3
- * Browser-only version without Node.js dependencies
2
+ * welvet WASM Browser Loader
3
+ * Loads the Go runtime and WASM module in a browser environment.
4
4
  */
5
- export declare function loadLoomWASMBrowser(): Promise<void>;
5
+ export declare function loadLoomWASMBrowser(wasmUrl?: string): Promise<void>;
@@ -1,11 +1,10 @@
1
1
  /**
2
- * LOOM WASM Browser Loader
3
- * Browser-only version without Node.js dependencies
2
+ * welvet WASM Browser Loader
3
+ * Loads the Go runtime and WASM module in a browser environment.
4
4
  */
5
- export async function loadLoomWASMBrowser() {
6
- // For browser environments - load wasm_exec.js first if not already loaded
7
- if (typeof globalThis.Go === "undefined") {
8
- // Load wasm_exec.js dynamically from /dist/
5
+ export async function loadLoomWASMBrowser(wasmUrl) {
6
+ // Inject wasm_exec.js if the Go runtime is not yet available
7
+ if (typeof globalThis["Go"] === "undefined") {
9
8
  const script = document.createElement("script");
10
9
  script.src = "/dist/wasm_exec.js";
11
10
  await new Promise((resolve, reject) => {
@@ -14,12 +13,12 @@ export async function loadLoomWASMBrowser() {
14
13
  document.head.appendChild(script);
15
14
  });
16
15
  }
17
- const response = await fetch("/dist/main.wasm");
16
+ const response = await fetch(wasmUrl ?? "/dist/main.wasm");
18
17
  const wasmBuffer = await response.arrayBuffer();
19
- // @ts-ignore - Go is defined by wasm_exec.js
18
+ // @ts-ignore Go is injected by wasm_exec.js
20
19
  const go = new Go();
21
20
  const { instance } = await WebAssembly.instantiate(wasmBuffer, go.importObject);
22
21
  go.run(instance);
23
- // Wait for initialization
22
+ // Allow Go goroutines to settle
24
23
  await new Promise((resolve) => setTimeout(resolve, 100));
25
24
  }
package/dist/loader.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * LOOM WASM Loader
3
- * Loads and initializes the LOOM WebAssembly module (Node.js only)
2
+ * welvet WASM Loader — Node.js
3
+ * Loads and initializes the welvet WebAssembly module.
4
4
  */
5
5
  export declare function loadLoomWASM(): Promise<void>;
package/dist/loader.js CHANGED
@@ -1,38 +1,26 @@
1
1
  /**
2
- * LOOM WASM Loader
3
- * Loads and initializes the LOOM WebAssembly module (Node.js only)
2
+ * welvet WASM Loader — Node.js
3
+ * Loads and initializes the welvet WebAssembly module.
4
4
  */
5
- import { readFileSync } from "fs";
6
- import { fileURLToPath } from "url";
7
- import { dirname, join } from "path";
8
- const __filename = fileURLToPath(import.meta.url);
9
- const __dirname = dirname(__filename);
10
5
  export async function loadLoomWASM() {
11
- // __dirname points to:
12
- // - dist/ → in production
13
- // - src/ → when running via Bun, ts-node, or example files
14
- let root;
15
- if (__dirname.endsWith("dist")) {
16
- // Normal production layout
17
- root = __dirname;
18
- }
19
- else {
20
- // Running from src/ or example/
21
- // Point to project’s dist/ directory
22
- root = join(__dirname, "..", "dist");
23
- }
24
- // Load wasm_exec.js
25
- const wasmExecPath = join(root, "wasm_exec.js");
26
- const wasmExecCode = readFileSync(wasmExecPath, "utf-8");
27
- // Execute wasm_exec.js to get the Go runtime
6
+ const fs = await import("fs");
7
+ const url = await import("url");
8
+ const path = await import("path");
9
+ const __filename = url.fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+ // Resolve root: dist/ in production, or one level up from src/
12
+ const root = __dirname.endsWith("dist")
13
+ ? __dirname
14
+ : path.join(__dirname, "..", "dist");
15
+ // Bootstrap Go runtime
16
+ const wasmExecCode = fs.readFileSync(path.join(root, "wasm_exec.js"), "utf-8");
28
17
  eval(wasmExecCode);
29
- // Load main.wasm
30
- const wasmPath = join(root, "main.wasm");
31
- const wasmBuffer = readFileSync(wasmPath);
32
- // @ts-ignore - Go runtime from wasm_exec.js
18
+ // Load and instantiate the WASM module
19
+ const wasmBuffer = fs.readFileSync(path.join(root, "main.wasm"));
20
+ // @ts-ignore Go is injected by wasm_exec.js
33
21
  const go = new Go();
34
22
  const { instance } = await WebAssembly.instantiate(wasmBuffer, go.importObject);
35
23
  go.run(instance);
36
- // Wait for WASM runtime to finish bootstrapping
24
+ // Allow Go goroutines to settle
37
25
  await new Promise((resolve) => setTimeout(resolve, 100));
38
26
  }
package/dist/main.wasm CHANGED
Binary file
@@ -0,0 +1,135 @@
1
+ /**
2
+ * @openfluke/welvet — M-POLY-VTD AI Engine
3
+ *
4
+ * Isomorphic TypeScript wrapper for the Loom v0.73.0 WASM module.
5
+ * Supports Node.js and browser environments.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { init, createNetwork, DType } from "@openfluke/welvet";
10
+ *
11
+ * await init();
12
+ *
13
+ * const net = createNetwork({
14
+ * layers: [
15
+ * { type: "dense", input_height: 4, output_height: 8 },
16
+ * { type: "dense", input_height: 8, output_height: 2 },
17
+ * ]
18
+ * });
19
+ *
20
+ * const output = net.sequentialForward(new Float32Array([1, 0, 0, 1]));
21
+ * console.log(output); // Float32Array [...]
22
+ * ```
23
+ */
24
+ import type { Network, NEATPopulation, SystolicState, TargetPropState, TrainingBatch, TrainingResult, DNACompareResult } from "./types.js";
25
+ import { loadLoomWASMBrowser } from "./loader.browser.js";
26
+ export * from "./types.js";
27
+ export { loadLoomWASMBrowser };
28
+ /**
29
+ * Initialize the welvet WASM module.
30
+ * Auto-detects Node.js vs browser environment.
31
+ *
32
+ * @param wasmUrl Optional custom URL for browser WASM loading (default: /dist/main.wasm)
33
+ */
34
+ export declare function init(wasmUrl?: string): Promise<void>;
35
+ /**
36
+ * Initialize explicitly for browser environments.
37
+ * @param wasmUrl Optional custom URL for WASM binary
38
+ */
39
+ export declare function initBrowser(wasmUrl?: string): Promise<void>;
40
+ /**
41
+ * Build a VolumetricNetwork from a JSON configuration object or string.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * const net = createNetwork({
46
+ * layers: [
47
+ * { type: "dense", input_height: 784, output_height: 256 },
48
+ * { type: "dense", input_height: 256, output_height: 10, activation: "silu" },
49
+ * ]
50
+ * });
51
+ * ```
52
+ */
53
+ export declare function createNetwork(config: object | string): Network;
54
+ /**
55
+ * Load a pre-trained network from a SafeTensors file path.
56
+ * (Node.js only — requires file system access)
57
+ *
58
+ * @param path Absolute or relative path to a .safetensors file
59
+ */
60
+ export declare function loadNetwork(path: string): Network;
61
+ /**
62
+ * Initialize WebGPU (browser only).
63
+ * Sets window.webgpuAdapter, window.webgpuDevice, window.webgpuQueue.
64
+ */
65
+ export declare function setupWebGPU(): Promise<string>;
66
+ /**
67
+ * Compare the architectural DNA of two networks.
68
+ *
69
+ * @param dnaA JSON string from network.extractDNA()
70
+ * @param dnaB JSON string from network.extractDNA()
71
+ * @returns DNACompareResult
72
+ */
73
+ export declare function compareDNA(dnaA: string, dnaB: string): DNACompareResult;
74
+ /**
75
+ * Get the default TargetPropConfig.
76
+ */
77
+ export declare function defaultTargetPropConfig(): object;
78
+ /**
79
+ * Convenience wrapper for network.train() that handles JSON serialization.
80
+ *
81
+ * @param network The network to train
82
+ * @param batches Array of {input, target} training pairs
83
+ * @param epochs Number of training epochs
84
+ * @param lr Learning rate
85
+ */
86
+ export declare function trainNetwork(network: Network, batches: TrainingBatch[], epochs: number, lr: number): TrainingResult;
87
+ /** Get the default SpliceConfig as a plain object. */
88
+ export declare function getSpliceConfig(): object;
89
+ /** Get the default NEATConfig as a plain object. */
90
+ export declare function getNEATConfig(dModel: number): object;
91
+ /**
92
+ * Create a NEAT population from a seed network.
93
+ * @param network Seed network (its _id is used)
94
+ * @param size Population size
95
+ * @param cfg NEATConfig object or JSON string (defaults to getNEATConfig(64))
96
+ */
97
+ export declare function createNEATPopulation(network: Network, size: number, cfg?: object | string): NEATPopulation;
98
+ declare const _default: {
99
+ init: typeof init;
100
+ initBrowser: typeof initBrowser;
101
+ createNetwork: typeof createNetwork;
102
+ loadNetwork: typeof loadNetwork;
103
+ setupWebGPU: typeof setupWebGPU;
104
+ compareDNA: typeof compareDNA;
105
+ defaultTargetPropConfig: typeof defaultTargetPropConfig;
106
+ trainNetwork: typeof trainNetwork;
107
+ getSpliceConfig: typeof getSpliceConfig;
108
+ getNEATConfig: typeof getNEATConfig;
109
+ createNEATPopulation: typeof createNEATPopulation;
110
+ DType: {
111
+ FLOAT64: number;
112
+ FLOAT32: number;
113
+ FLOAT16: number;
114
+ BFLOAT16: number;
115
+ FP8_E4M3: number;
116
+ FP8_E5M2: number;
117
+ INT64: number;
118
+ INT32: number;
119
+ INT16: number;
120
+ INT8: number;
121
+ UINT64: number;
122
+ UINT32: number;
123
+ UINT16: number;
124
+ UINT8: number;
125
+ INT4: number;
126
+ UINT4: number;
127
+ FP4: number;
128
+ INT2: number;
129
+ UINT2: number;
130
+ TERNARY: number;
131
+ BINARY: number;
132
+ };
133
+ };
134
+ export default _default;
135
+ export type { Network, NEATPopulation, SystolicState, TargetPropState, TrainingBatch, TrainingResult, DNACompareResult };
@@ -0,0 +1,181 @@
1
+ /**
2
+ * @openfluke/welvet — M-POLY-VTD AI Engine
3
+ *
4
+ * Isomorphic TypeScript wrapper for the Loom v0.73.0 WASM module.
5
+ * Supports Node.js and browser environments.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { init, createNetwork, DType } from "@openfluke/welvet";
10
+ *
11
+ * await init();
12
+ *
13
+ * const net = createNetwork({
14
+ * layers: [
15
+ * { type: "dense", input_height: 4, output_height: 8 },
16
+ * { type: "dense", input_height: 8, output_height: 2 },
17
+ * ]
18
+ * });
19
+ *
20
+ * const output = net.sequentialForward(new Float32Array([1, 0, 0, 1]));
21
+ * console.log(output); // Float32Array [...]
22
+ * ```
23
+ */
24
+ import { loadLoomWASMBrowser } from "./loader.browser.js";
25
+ // Re-export all types and constants
26
+ export * from "./types.js";
27
+ export { loadLoomWASMBrowser };
28
+ // ──────────────────────────────────────────────────────────────────────────────
29
+ // Initialization
30
+ // ──────────────────────────────────────────────────────────────────────────────
31
+ /**
32
+ * Initialize the welvet WASM module.
33
+ * Auto-detects Node.js vs browser environment.
34
+ *
35
+ * @param wasmUrl Optional custom URL for browser WASM loading (default: /dist/main.wasm)
36
+ */
37
+ export async function init(wasmUrl) {
38
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
39
+ return loadLoomWASMBrowser(wasmUrl);
40
+ }
41
+ const mod = await import("./loader.js");
42
+ return mod.loadLoomWASM();
43
+ }
44
+ /**
45
+ * Initialize explicitly for browser environments.
46
+ * @param wasmUrl Optional custom URL for WASM binary
47
+ */
48
+ export async function initBrowser(wasmUrl) {
49
+ return loadLoomWASMBrowser(wasmUrl);
50
+ }
51
+ // ──────────────────────────────────────────────────────────────────────────────
52
+ // Network Lifecycle
53
+ // ──────────────────────────────────────────────────────────────────────────────
54
+ /**
55
+ * Build a VolumetricNetwork from a JSON configuration object or string.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const net = createNetwork({
60
+ * layers: [
61
+ * { type: "dense", input_height: 784, output_height: 256 },
62
+ * { type: "dense", input_height: 256, output_height: 10, activation: "silu" },
63
+ * ]
64
+ * });
65
+ * ```
66
+ */
67
+ export function createNetwork(config) {
68
+ const jsonConfig = typeof config === "string" ? config : JSON.stringify(config);
69
+ return createLoomNetwork(jsonConfig);
70
+ }
71
+ /**
72
+ * Load a pre-trained network from a SafeTensors file path.
73
+ * (Node.js only — requires file system access)
74
+ *
75
+ * @param path Absolute or relative path to a .safetensors file
76
+ */
77
+ export function loadNetwork(path) {
78
+ return loadLoomNetwork(path);
79
+ }
80
+ // ──────────────────────────────────────────────────────────────────────────────
81
+ // WebGPU
82
+ // ──────────────────────────────────────────────────────────────────────────────
83
+ /**
84
+ * Initialize WebGPU (browser only).
85
+ * Sets window.webgpuAdapter, window.webgpuDevice, window.webgpuQueue.
86
+ */
87
+ export async function setupWebGPU() {
88
+ // @ts-ignore — setupWebGPU is injected by the WASM module
89
+ return setupWebGPU();
90
+ }
91
+ // ──────────────────────────────────────────────────────────────────────────────
92
+ // DNA / Introspection
93
+ // ──────────────────────────────────────────────────────────────────────────────
94
+ /**
95
+ * Compare the architectural DNA of two networks.
96
+ *
97
+ * @param dnaA JSON string from network.extractDNA()
98
+ * @param dnaB JSON string from network.extractDNA()
99
+ * @returns DNACompareResult
100
+ */
101
+ export function compareDNA(dnaA, dnaB) {
102
+ return JSON.parse(compareLoomDNA(dnaA, dnaB));
103
+ }
104
+ /**
105
+ * Get the default TargetPropConfig.
106
+ */
107
+ export function defaultTargetPropConfig() {
108
+ return JSON.parse(getDefaultTargetPropConfig());
109
+ }
110
+ // ──────────────────────────────────────────────────────────────────────────────
111
+ // Training Helpers
112
+ // ──────────────────────────────────────────────────────────────────────────────
113
+ /**
114
+ * Convenience wrapper for network.train() that handles JSON serialization.
115
+ *
116
+ * @param network The network to train
117
+ * @param batches Array of {input, target} training pairs
118
+ * @param epochs Number of training epochs
119
+ * @param lr Learning rate
120
+ */
121
+ export function trainNetwork(network, batches, epochs, lr) {
122
+ const serialized = batches.map((b) => {
123
+ const inp = b.input instanceof Float32Array ? b.input : new Float32Array(b.input);
124
+ const tgt = b.target instanceof Float32Array ? b.target : new Float32Array(b.target);
125
+ const inShape = b.inputShape ?? [1, inp.length];
126
+ const tgtShape = b.targetShape ?? [1, tgt.length];
127
+ return {
128
+ input: { shape: inShape, data: Array.from(inp) },
129
+ target: { shape: tgtShape, data: Array.from(tgt) },
130
+ };
131
+ });
132
+ return JSON.parse(network.train(JSON.stringify(serialized), epochs, lr));
133
+ }
134
+ // ──────────────────────────────────────────────────────────────────────────────
135
+ // Evolution / DNA
136
+ // ──────────────────────────────────────────────────────────────────────────────
137
+ /** Get the default SpliceConfig as a plain object. */
138
+ export function getSpliceConfig() {
139
+ return JSON.parse(globalThis["defaultSpliceConfig"]());
140
+ }
141
+ /** Get the default NEATConfig as a plain object. */
142
+ export function getNEATConfig(dModel) {
143
+ return JSON.parse(globalThis["defaultNEATConfig"](dModel));
144
+ }
145
+ /**
146
+ * Create a NEAT population from a seed network.
147
+ * @param network Seed network (its _id is used)
148
+ * @param size Population size
149
+ * @param cfg NEATConfig object or JSON string (defaults to getNEATConfig(64))
150
+ */
151
+ export function createNEATPopulation(network, size, cfg) {
152
+ const cfgJSON = cfg
153
+ ? (typeof cfg === "string" ? cfg : JSON.stringify(cfg))
154
+ : globalThis["defaultNEATConfig"](64);
155
+ return globalThis["createLoomNEATPopulation"](network._id, size, cfgJSON);
156
+ }
157
+ // ──────────────────────────────────────────────────────────────────────────────
158
+ // Default export
159
+ // ──────────────────────────────────────────────────────────────────────────────
160
+ export default {
161
+ init,
162
+ initBrowser,
163
+ createNetwork,
164
+ loadNetwork,
165
+ setupWebGPU,
166
+ compareDNA,
167
+ defaultTargetPropConfig,
168
+ trainNetwork,
169
+ getSpliceConfig,
170
+ getNEATConfig,
171
+ createNEATPopulation,
172
+ // Re-export constants for convenience
173
+ DType: {
174
+ FLOAT64: 0, FLOAT32: 1, FLOAT16: 2, BFLOAT16: 3,
175
+ FP8_E4M3: 4, FP8_E5M2: 5,
176
+ INT64: 6, INT32: 7, INT16: 8, INT8: 9,
177
+ UINT64: 10, UINT32: 11, UINT16: 12, UINT8: 13,
178
+ INT4: 14, UINT4: 15, FP4: 16,
179
+ INT2: 17, UINT2: 18, TERNARY: 19, BINARY: 20,
180
+ },
181
+ };