@seanhogg/builderforce-memory-engine 2026.9.33 → 2026.10.1

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 (170) hide show
  1. package/dist/evermind/delta_wire.d.ts +10 -1
  2. package/dist/evermind/delta_wire.d.ts.map +1 -1
  3. package/dist/evermind/delta_wire.js +25 -3
  4. package/dist/evermind/delta_wire.js.map +1 -1
  5. package/dist/evermind/index.d.ts +4 -4
  6. package/dist/evermind/index.d.ts.map +1 -1
  7. package/dist/evermind/index.js +2 -2
  8. package/dist/evermind/index.js.map +1 -1
  9. package/dist/evermind/merge.d.ts +25 -0
  10. package/dist/evermind/merge.d.ts.map +1 -1
  11. package/dist/evermind/merge.js +30 -0
  12. package/dist/evermind/merge.js.map +1 -1
  13. package/dist/evermind/package.d.ts +9 -0
  14. package/dist/evermind/package.d.ts.map +1 -1
  15. package/dist/evermind/package.js +20 -0
  16. package/dist/evermind/package.js.map +1 -1
  17. package/dist/index.d.ts +6 -5
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +5 -3
  20. package/dist/index.js.map +1 -1
  21. package/dist/limbic/index.d.ts +3 -0
  22. package/dist/limbic/index.d.ts.map +1 -1
  23. package/dist/limbic/index.js +3 -0
  24. package/dist/limbic/index.js.map +1 -1
  25. package/dist/limbic/limbic_task.d.ts +22 -0
  26. package/dist/limbic/limbic_task.d.ts.map +1 -0
  27. package/dist/limbic/limbic_task.js +45 -0
  28. package/dist/limbic/limbic_task.js.map +1 -0
  29. package/dist/limbic/limbic_trainer.d.ts +17 -30
  30. package/dist/limbic/limbic_trainer.d.ts.map +1 -1
  31. package/dist/limbic/limbic_trainer.js +38 -144
  32. package/dist/limbic/limbic_trainer.js.map +1 -1
  33. package/dist/ml/classical/ewma.d.ts +32 -0
  34. package/dist/ml/classical/ewma.d.ts.map +1 -0
  35. package/dist/ml/classical/ewma.js +46 -0
  36. package/dist/ml/classical/ewma.js.map +1 -0
  37. package/dist/ml/classical/gbm.d.ts +42 -0
  38. package/dist/ml/classical/gbm.d.ts.map +1 -0
  39. package/dist/ml/classical/gbm.js +116 -0
  40. package/dist/ml/classical/gbm.js.map +1 -0
  41. package/dist/ml/classical/index.d.ts +48 -0
  42. package/dist/ml/classical/index.d.ts.map +1 -0
  43. package/dist/ml/classical/index.js +45 -0
  44. package/dist/ml/classical/index.js.map +1 -0
  45. package/dist/ml/classical/isolation_forest.d.ts +37 -0
  46. package/dist/ml/classical/isolation_forest.d.ts.map +1 -0
  47. package/dist/ml/classical/isolation_forest.js +72 -0
  48. package/dist/ml/classical/isolation_forest.js.map +1 -0
  49. package/dist/ml/classical/kmeans.d.ts +31 -0
  50. package/dist/ml/classical/kmeans.d.ts.map +1 -0
  51. package/dist/ml/classical/kmeans.js +93 -0
  52. package/dist/ml/classical/kmeans.js.map +1 -0
  53. package/dist/ml/classical/knn.d.ts +48 -0
  54. package/dist/ml/classical/knn.d.ts.map +1 -0
  55. package/dist/ml/classical/knn.js +68 -0
  56. package/dist/ml/classical/knn.js.map +1 -0
  57. package/dist/ml/classical/linear.d.ts +29 -0
  58. package/dist/ml/classical/linear.d.ts.map +1 -0
  59. package/dist/ml/classical/linear.js +114 -0
  60. package/dist/ml/classical/linear.js.map +1 -0
  61. package/dist/ml/classical/logistic.d.ts +39 -0
  62. package/dist/ml/classical/logistic.d.ts.map +1 -0
  63. package/dist/ml/classical/logistic.js +103 -0
  64. package/dist/ml/classical/logistic.js.map +1 -0
  65. package/dist/ml/classical/math.d.ts +26 -0
  66. package/dist/ml/classical/math.d.ts.map +1 -0
  67. package/dist/ml/classical/math.js +90 -0
  68. package/dist/ml/classical/math.js.map +1 -0
  69. package/dist/ml/classical/naive_bayes.d.ts +24 -0
  70. package/dist/ml/classical/naive_bayes.d.ts.map +1 -0
  71. package/dist/ml/classical/naive_bayes.js +67 -0
  72. package/dist/ml/classical/naive_bayes.js.map +1 -0
  73. package/dist/ml/classical/robust_z.d.ts +30 -0
  74. package/dist/ml/classical/robust_z.d.ts.map +1 -0
  75. package/dist/ml/classical/robust_z.js +46 -0
  76. package/dist/ml/classical/robust_z.js.map +1 -0
  77. package/dist/ml/dense_head.d.ts +33 -0
  78. package/dist/ml/dense_head.d.ts.map +1 -0
  79. package/dist/ml/dense_head.js +140 -0
  80. package/dist/ml/dense_head.js.map +1 -0
  81. package/dist/ml/features.d.ts +25 -0
  82. package/dist/ml/features.d.ts.map +1 -0
  83. package/dist/ml/features.js +46 -0
  84. package/dist/ml/features.js.map +1 -0
  85. package/dist/ml/federate.d.ts +70 -0
  86. package/dist/ml/federate.d.ts.map +1 -0
  87. package/dist/ml/federate.js +122 -0
  88. package/dist/ml/federate.js.map +1 -0
  89. package/dist/ml/head_trainer.d.ts +76 -0
  90. package/dist/ml/head_trainer.d.ts.map +1 -0
  91. package/dist/ml/head_trainer.js +182 -0
  92. package/dist/ml/head_trainer.js.map +1 -0
  93. package/dist/ml/index.d.ts +23 -0
  94. package/dist/ml/index.d.ts.map +1 -0
  95. package/dist/ml/index.js +11 -0
  96. package/dist/ml/index.js.map +1 -0
  97. package/dist/ml/registry.d.ts +20 -0
  98. package/dist/ml/registry.d.ts.map +1 -0
  99. package/dist/ml/registry.js +43 -0
  100. package/dist/ml/registry.js.map +1 -0
  101. package/dist/ml/run.d.ts +94 -0
  102. package/dist/ml/run.d.ts.map +1 -0
  103. package/dist/ml/run.js +130 -0
  104. package/dist/ml/run.js.map +1 -0
  105. package/dist/ml/tasks/experience.d.ts +90 -0
  106. package/dist/ml/tasks/experience.d.ts.map +1 -0
  107. package/dist/ml/tasks/experience.js +156 -0
  108. package/dist/ml/tasks/experience.js.map +1 -0
  109. package/dist/ml/tasks/index.d.ts +10 -0
  110. package/dist/ml/tasks/index.d.ts.map +1 -0
  111. package/dist/ml/tasks/index.js +28 -0
  112. package/dist/ml/tasks/index.js.map +1 -0
  113. package/dist/ml/tasks/local_success.d.ts +55 -0
  114. package/dist/ml/tasks/local_success.d.ts.map +1 -0
  115. package/dist/ml/tasks/local_success.js +77 -0
  116. package/dist/ml/tasks/local_success.js.map +1 -0
  117. package/dist/ml/tasks/run_anomaly.d.ts +51 -0
  118. package/dist/ml/tasks/run_anomaly.d.ts.map +1 -0
  119. package/dist/ml/tasks/run_anomaly.js +60 -0
  120. package/dist/ml/tasks/run_anomaly.js.map +1 -0
  121. package/dist/ml/train.d.ts +64 -0
  122. package/dist/ml/train.d.ts.map +1 -0
  123. package/dist/ml/train.js +101 -0
  124. package/dist/ml/train.js.map +1 -0
  125. package/dist/ml/types.d.ts +112 -0
  126. package/dist/ml/types.d.ts.map +1 -0
  127. package/dist/ml/types.js +23 -0
  128. package/dist/ml/types.js.map +1 -0
  129. package/dist/moe/moe_model.d.ts.map +1 -1
  130. package/dist/moe/moe_model.js +1 -16
  131. package/dist/moe/moe_model.js.map +1 -1
  132. package/dist/training/cpu_ops.d.ts +2 -0
  133. package/dist/training/cpu_ops.d.ts.map +1 -1
  134. package/dist/training/cpu_ops.js +16 -0
  135. package/dist/training/cpu_ops.js.map +1 -1
  136. package/package.json +1 -1
  137. package/src/evermind/delta_wire.ts +148 -114
  138. package/src/evermind/index.ts +35 -32
  139. package/src/evermind/merge.ts +53 -0
  140. package/src/evermind/package.ts +488 -464
  141. package/src/index.ts +15 -1
  142. package/src/limbic/index.ts +5 -0
  143. package/src/limbic/limbic_task.ts +62 -0
  144. package/src/limbic/limbic_trainer.ts +91 -258
  145. package/src/ml/classical/ewma.ts +68 -0
  146. package/src/ml/classical/gbm.ts +143 -0
  147. package/src/ml/classical/index.ts +76 -0
  148. package/src/ml/classical/isolation_forest.ts +88 -0
  149. package/src/ml/classical/kmeans.ts +102 -0
  150. package/src/ml/classical/knn.ts +98 -0
  151. package/src/ml/classical/linear.ts +119 -0
  152. package/src/ml/classical/logistic.ts +125 -0
  153. package/src/ml/classical/math.ts +93 -0
  154. package/src/ml/classical/naive_bayes.ts +77 -0
  155. package/src/ml/classical/robust_z.ts +65 -0
  156. package/src/ml/dense_head.ts +157 -0
  157. package/src/ml/features.ts +61 -0
  158. package/src/ml/federate.ts +160 -0
  159. package/src/ml/head_trainer.ts +268 -0
  160. package/src/ml/index.ts +57 -0
  161. package/src/ml/registry.ts +44 -0
  162. package/src/ml/run.ts +178 -0
  163. package/src/ml/tasks/experience.ts +214 -0
  164. package/src/ml/tasks/index.ts +30 -0
  165. package/src/ml/tasks/local_success.ts +118 -0
  166. package/src/ml/tasks/run_anomaly.ts +90 -0
  167. package/src/ml/train.ts +136 -0
  168. package/src/ml/types.ts +132 -0
  169. package/src/moe/moe_model.ts +1 -13
  170. package/src/training/cpu_ops.ts +141 -127
@@ -0,0 +1,22 @@
1
+ import type { MlPredictor, MlTask } from "../ml/types.js";
2
+ import type { LimbicModel } from "./limbic_model.js";
3
+ export interface LimbicAffectInput {
4
+ /** Experience embedding (length = model.inputDim). */
5
+ embedding: ArrayLike<number>;
6
+ /** Current affective state (length = model.stateDim). */
7
+ state: ArrayLike<number>;
8
+ }
9
+ export interface LimbicAffectOutput {
10
+ /** Bounded affect delta in (-1, 1) per state dim. */
11
+ delta: Float32Array;
12
+ /** Reward prediction. */
13
+ reward: number;
14
+ }
15
+ export declare const LIMBIC_AFFECT_TASK: MlTask<LimbicAffectInput, LimbicAffectOutput>;
16
+ /**
17
+ * Answer `limbic.affect` with `model`. The feature vector is `[embedding, state]`;
18
+ * the hidden scratch resets per call, exactly as the trainer treats each sample.
19
+ * Confidence is 1: a deterministic regression head has no calibrated uncertainty.
20
+ */
21
+ export declare function limbicAffectPredictor(model: LimbicModel): MlPredictor;
22
+ //# sourceMappingURL=limbic_task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limbic_task.d.ts","sourceRoot":"","sources":["../../src/limbic/limbic_task.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,sDAAsD;IACtD,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7B,yDAAyD;IACzD,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,KAAK,EAAE,YAAY,CAAC;IACpB,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAa5E,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAarE"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * limbic/limbic_task.ts — `limbic.affect`, the ML catalog's first row, registered
3
+ * by limbic/ itself.
4
+ *
5
+ * Nothing about the affect head changes: the row describes it (input = experience
6
+ * embedding + affective state, output = bounded affect delta + reward), the
7
+ * predictor adapter lets the ONE runner answer with an existing `LimbicModel`, and
8
+ * training stays `LimbicTrainer` (itself a thin registration over `HeadTrainer`).
9
+ * Its flat parameters are what federate when the head travels with the model.
10
+ */
11
+ import { assignParams, flattenParams } from "../ml/head_trainer.js";
12
+ export const LIMBIC_AFFECT_TASK = {
13
+ kind: "regress",
14
+ id: "limbic.affect",
15
+ description: "How an experience moves the agent's affective state, and how rewarding it was.",
16
+ features: { numeric: (i) => [...Array.from(i.embedding), ...Array.from(i.state)] },
17
+ engines: [{ tier: "local", engine: "head", head: "mlp" }],
18
+ train: { minSamples: 1, trainedBy: "LimbicTrainer" },
19
+ output: {
20
+ decode: (p) => ({
21
+ delta: Float32Array.from(p.scores.slice(0, -1)),
22
+ reward: p.scores[p.scores.length - 1] ?? 0,
23
+ }),
24
+ },
25
+ };
26
+ /**
27
+ * Answer `limbic.affect` with `model`. The feature vector is `[embedding, state]`;
28
+ * the hidden scratch resets per call, exactly as the trainer treats each sample.
29
+ * Confidence is 1: a deterministic regression head has no calibrated uncertainty.
30
+ */
31
+ export function limbicAffectPredictor(model) {
32
+ const { inputDim, stateDim } = model.config;
33
+ return {
34
+ predict(x) {
35
+ if (x.length !== inputDim + stateDim) {
36
+ throw new Error(`limbic.affect: expected ${inputDim + stateDim} features (embedding ${inputDim} + state ${stateDim}), got ${x.length}`);
37
+ }
38
+ const f = model.forward(x.subarray(0, inputDim), model.initHidden(), x.subarray(inputDim));
39
+ return { scores: [...Array.from(f.delta), f.reward], confidence: 1 };
40
+ },
41
+ exportParams: () => flattenParams(model.parameters()),
42
+ importParams: (params) => assignParams(model.parameters(), params),
43
+ };
44
+ }
45
+ //# sourceMappingURL=limbic_task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limbic_task.js","sourceRoot":"","sources":["../../src/limbic/limbic_task.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAkBpE,MAAM,CAAC,MAAM,kBAAkB,GAAkD;IAC/E,IAAI,EAAE,SAAS;IACf,EAAE,EAAE,eAAe;IACnB,WAAW,EAAE,gFAAgF;IAC7F,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;IAClF,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzD,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE;IACpD,MAAM,EAAE;QACN,MAAM,EAAE,CAAC,CAAe,EAAE,EAAE,CAAC,CAAC;YAC5B,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC;SAC3C,CAAC;KACH;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAkB;IACtD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5C,OAAO;QACL,OAAO,CAAC,CAAe;YACrB,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,GAAG,QAAQ,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,GAAG,QAAQ,wBAAwB,QAAQ,YAAY,QAAQ,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YAC1I,CAAC;YACD,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC3F,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QACvE,CAAC;QACD,YAAY,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACrD,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,MAAM,CAAC;KACnE,CAAC;AACJ,CAAC"}
@@ -3,15 +3,16 @@
3
3
  *
4
4
  * Trains the affect head to predict affect deltas and reward from
5
5
  * (experience embedding, current state) pairs, using full-batch gradient
6
- * descent with AdamW. When a GPUDevice is supplied the optimiser step runs on
7
- * the GPU via the shared WEIGHT_UPDATE_WGSL kernel (real WebGPU training); with
8
- * no device it uses a numerically-equivalent CPU AdamW so training works
9
- * everywhere (CI, Node without @webgpu/node, etc.).
6
+ * descent with AdamW — through the shared {@link HeadTrainer} (`ml/head_trainer.ts`),
7
+ * which runs the optimiser step on the GPU via WEIGHT_UPDATE_WGSL when a device is
8
+ * supplied and on a numerically-equivalent CPU AdamW otherwise. This file is only
9
+ * the limbic registration: the head adapter and the public trainer surface.
10
10
  *
11
11
  * The objective is MSE (regression), not the cross-entropy used by the
12
12
  * language-model {@link MambaTrainer} — a limbic experience has continuous
13
13
  * targets, not a next-token distribution.
14
14
  */
15
+ import { type HeadTrainOptions, type TrainableHead } from "../ml/head_trainer.js";
15
16
  import type { LimbicModel } from "./limbic_model.js";
16
17
  /** One training example: an experience and the affect change it should produce. */
17
18
  export interface LimbicSample {
@@ -24,43 +25,29 @@ export interface LimbicSample {
24
25
  /** Observed scalar reward for the experience. */
25
26
  reward: number;
26
27
  }
27
- export interface LimbicTrainOptions {
28
- learningRate?: number;
29
- epochs?: number;
30
- weightDecay?: number;
31
- beta1?: number;
32
- beta2?: number;
33
- eps?: number;
34
- /** Max global gradient L2 norm before the optimiser step. Default 1.0. */
35
- maxGradNorm?: number;
36
- /** Per-epoch hook. `gradNorm` is the pre-clip gradient L2 norm this epoch (the
37
- * instability early-warning) — computed CPU-side so it's always available, unlike
38
- * the GPU trainer where it's opt-in. */
39
- onEpochEnd?: ((epoch: number, loss: number, gradNorm?: number) => void) | null;
40
- }
28
+ /** The limbic trainer's options are the shared head trainer's. */
29
+ export type LimbicTrainOptions = HeadTrainOptions;
30
+ /**
31
+ * The limbic model as a {@link TrainableHead}. Each sample is one experience
32
+ * appraisal: cross-experience memory flows through the affective state `s` (fed
33
+ * back by the runtime), not through the hidden scratch `h`, so the hidden state
34
+ * resets per sample. This also makes BPTT(1) exact — there is no truncated carry.
35
+ */
36
+ export declare function limbicHead(model: LimbicModel): TrainableHead<LimbicSample>;
37
+ /** Thin registration of the limbic head over the shared {@link HeadTrainer}. */
41
38
  export declare class LimbicTrainer {
42
39
  readonly model: LimbicModel;
43
40
  readonly device: GPUDevice | null;
44
- private _moments;
45
- private _step;
46
- private readonly _adamwPipeline;
41
+ private readonly _trainer;
47
42
  constructor(model: LimbicModel, device?: GPUDevice | null);
48
43
  /** Whether the optimiser step runs on the GPU. */
49
44
  get gpuTraining(): boolean;
50
- private _initMoments;
51
45
  /**
52
46
  * Train on a batch of samples for `epochs` passes. Returns the per-epoch mean
53
- * loss (monotonically decreasing on a learnable mapping). Full-batch: grads
54
- * accumulate across the whole sequence (recurrent hidden carried, reset per
55
- * epoch), are averaged, clipped, then applied once per epoch.
47
+ * loss (monotonically decreasing on a learnable mapping).
56
48
  */
57
49
  train(samples: LimbicSample[], opts?: LimbicTrainOptions): Promise<number[]>;
58
50
  /** Mean MSE loss over samples (no weight update). Hidden resets per sample. */
59
51
  evaluate(samples: LimbicSample[]): number;
60
- /** Clip grads to `maxNorm` in place; returns the PRE-clip L2 norm (the signal). */
61
- private _clipGradients;
62
- private _adamwStepCpu;
63
- /** AdamW on the GPU via the shared WEIGHT_UPDATE_WGSL kernel. Awaited per step. */
64
- private _adamwStepGpu;
65
52
  }
66
53
  //# sourceMappingURL=limbic_trainer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"limbic_trainer.d.ts","sourceRoot":"","sources":["../../src/limbic/limbic_trainer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAYH,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,mBAAmB,CAAC;AAElE,mFAAmF;AACnF,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACzB,+EAA+E;IAC/E,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACzB,uFAAuF;IACvF,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC/B,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;6CAEyC;IACzC,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CAChF;AAuBD,qBAAa,aAAa;IACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4B;gBAE/C,KAAK,EAAE,WAAW,EAAE,MAAM,GAAE,SAAS,GAAG,IAAW;IAQ/D,kDAAkD;IAClD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,OAAO,CAAC,YAAY;IAQpB;;;;;OAKG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IA6DtF,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM;IAkBzC,mFAAmF;IACnF,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,aAAa;IAqBrB,mFAAmF;YACrE,aAAa;CAkC5B"}
1
+ {"version":3,"file":"limbic_trainer.d.ts","sourceRoot":"","sources":["../../src/limbic/limbic_trainer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAe,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,mBAAmB,CAAC;AAElE,mFAAmF;AACnF,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACzB,+EAA+E;IAC/E,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACzB,uFAAuF;IACvF,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC/B,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kEAAkE;AAClE,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAAC,YAAY,CAAC,CAoB1E;AAED,gFAAgF;AAChF,qBAAa,aAAa;IACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;gBAEzC,KAAK,EAAE,WAAW,EAAE,MAAM,GAAE,SAAS,GAAG,IAAW;IAM/D,kDAAkD;IAClD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIhF,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM;CAG1C"}
@@ -3,172 +3,66 @@
3
3
  *
4
4
  * Trains the affect head to predict affect deltas and reward from
5
5
  * (experience embedding, current state) pairs, using full-batch gradient
6
- * descent with AdamW. When a GPUDevice is supplied the optimiser step runs on
7
- * the GPU via the shared WEIGHT_UPDATE_WGSL kernel (real WebGPU training); with
8
- * no device it uses a numerically-equivalent CPU AdamW so training works
9
- * everywhere (CI, Node without @webgpu/node, etc.).
6
+ * descent with AdamW — through the shared {@link HeadTrainer} (`ml/head_trainer.ts`),
7
+ * which runs the optimiser step on the GPU via WEIGHT_UPDATE_WGSL when a device is
8
+ * supplied and on a numerically-equivalent CPU AdamW otherwise. This file is only
9
+ * the limbic registration: the head adapter and the public trainer surface.
10
10
  *
11
11
  * The objective is MSE (regression), not the cross-entropy used by the
12
12
  * language-model {@link MambaTrainer} — a limbic experience has continuous
13
13
  * targets, not a next-token distribution.
14
14
  */
15
- import { createUniformBuffer, createStorageBuffer, createComputePipeline, createBindGroup, dispatchKernel, readBuffer, cdiv, } from "../utils/gpu_utils.js";
16
- import { WEIGHT_UPDATE_WGSL } from "../kernels/weight_update.js";
17
- function packAdamParams(numElements, lr, beta1, beta2, eps, weightDecay, beta1_t, beta2_t) {
18
- const buf = new ArrayBuffer(32);
19
- new Uint32Array(buf, 0, 1).set([numElements]);
20
- new Float32Array(buf, 4, 7).set([lr, beta1, beta2, eps, weightDecay, beta1_t, beta2_t]);
21
- return buf;
15
+ import { HeadTrainer } from "../ml/head_trainer.js";
16
+ /**
17
+ * The limbic model as a {@link TrainableHead}. Each sample is one experience
18
+ * appraisal: cross-experience memory flows through the affective state `s` (fed
19
+ * back by the runtime), not through the hidden scratch `h`, so the hidden state
20
+ * resets per sample. This also makes BPTT(1) exact — there is no truncated carry.
21
+ */
22
+ export function limbicHead(model) {
23
+ return {
24
+ parameters: () => model.parameters(),
25
+ gradients: () => model.gradients(),
26
+ zeroGrad: () => model.zeroGrad(),
27
+ accumulate: (s) => model.backwardStep(s.input, model.initHidden(), s.state, s.deltaTarget, s.reward).loss,
28
+ loss: (s) => {
29
+ const { rewardWeight } = model.config;
30
+ const f = model.forward(s.input, model.initHidden(), s.state);
31
+ let loss = 0;
32
+ for (let k = 0; k < f.delta.length; k++) {
33
+ const d = f.delta[k] - (s.deltaTarget[k] ?? 0);
34
+ loss += 0.5 * d * d;
35
+ }
36
+ const rd = f.reward - s.reward;
37
+ loss += 0.5 * rewardWeight * rd * rd;
38
+ return loss;
39
+ },
40
+ };
22
41
  }
42
+ /** Thin registration of the limbic head over the shared {@link HeadTrainer}. */
23
43
  export class LimbicTrainer {
24
44
  model;
25
45
  device;
26
- _moments = null;
27
- _step = 0;
28
- _adamwPipeline;
46
+ _trainer;
29
47
  constructor(model, device = null) {
30
48
  this.model = model;
31
49
  this.device = device;
32
- this._adamwPipeline = device
33
- ? createComputePipeline(device, WEIGHT_UPDATE_WGSL, "adamw_update")
34
- : null;
50
+ this._trainer = new HeadTrainer(limbicHead(model), device, "LimbicTrainer");
35
51
  }
36
52
  /** Whether the optimiser step runs on the GPU. */
37
53
  get gpuTraining() {
38
- return this.device != null && this._adamwPipeline != null;
39
- }
40
- _initMoments() {
41
- if (this._moments)
42
- return;
43
- this._moments = this.model.parameters().map((p) => ({
44
- m: new Float32Array(p.numel),
45
- v: new Float32Array(p.numel),
46
- }));
54
+ return this._trainer.gpuTraining;
47
55
  }
48
56
  /**
49
57
  * Train on a batch of samples for `epochs` passes. Returns the per-epoch mean
50
- * loss (monotonically decreasing on a learnable mapping). Full-batch: grads
51
- * accumulate across the whole sequence (recurrent hidden carried, reset per
52
- * epoch), are averaged, clipped, then applied once per epoch.
58
+ * loss (monotonically decreasing on a learnable mapping).
53
59
  */
54
- async train(samples, opts = {}) {
55
- if (samples.length === 0)
56
- throw new Error("LimbicTrainer.train: no samples");
57
- const { learningRate = 0.05, epochs = 50, weightDecay = 0.0, beta1 = 0.9, beta2 = 0.999, eps = 1e-8, maxGradNorm = 1.0, onEpochEnd = null, } = opts;
58
- this._initMoments();
59
- const losses = [];
60
- for (let epoch = 0; epoch < epochs; epoch++) {
61
- this.model.zeroGrad();
62
- let epochLoss = 0;
63
- // Each sample is one experience appraisal: cross-experience memory flows
64
- // through the affective state `s` (fed back by the runtime), not through
65
- // the hidden scratch `h`, so the hidden state resets per sample. This also
66
- // makes BPTT(1) exact — there is no truncated carry.
67
- for (const s of samples) {
68
- const { loss } = this.model.backwardStep(s.input, this.model.initHidden(), s.state, s.deltaTarget, s.reward);
69
- epochLoss += loss;
70
- }
71
- // Average gradients over the batch.
72
- const grads = this.model.gradients();
73
- const invN = 1 / samples.length;
74
- for (const g of grads) {
75
- for (let i = 0; i < g.data.length; i++)
76
- g.data[i] *= invN;
77
- }
78
- const gradNorm = this._clipGradients(grads, maxGradNorm);
79
- this._step++;
80
- const beta1_t = Math.pow(beta1, this._step);
81
- const beta2_t = Math.pow(beta2, this._step);
82
- const hp = { learningRate, weightDecay, beta1, beta2, eps, beta1_t, beta2_t };
83
- if (this.gpuTraining) {
84
- await this._adamwStepGpu(grads, hp);
85
- }
86
- else {
87
- this._adamwStepCpu(grads, hp);
88
- }
89
- const avg = epochLoss / samples.length;
90
- losses.push(avg);
91
- if (onEpochEnd)
92
- onEpochEnd(epoch + 1, avg, gradNorm);
93
- }
94
- return losses;
60
+ train(samples, opts = {}) {
61
+ return this._trainer.train(samples, opts);
95
62
  }
96
63
  /** Mean MSE loss over samples (no weight update). Hidden resets per sample. */
97
64
  evaluate(samples) {
98
- if (samples.length === 0)
99
- return 0;
100
- let total = 0;
101
- const { rewardWeight } = this.model.config;
102
- for (const s of samples) {
103
- const f = this.model.forward(s.input, this.model.initHidden(), s.state);
104
- let loss = 0;
105
- for (let k = 0; k < f.delta.length; k++) {
106
- const d = f.delta[k] - (s.deltaTarget[k] ?? 0);
107
- loss += 0.5 * d * d;
108
- }
109
- const rd = f.reward - s.reward;
110
- loss += 0.5 * rewardWeight * rd * rd;
111
- total += loss;
112
- }
113
- return total / samples.length;
114
- }
115
- /** Clip grads to `maxNorm` in place; returns the PRE-clip L2 norm (the signal). */
116
- _clipGradients(grads, maxNorm) {
117
- let normSq = 0;
118
- for (const g of grads)
119
- for (let i = 0; i < g.data.length; i++)
120
- normSq += g.data[i] * g.data[i];
121
- const norm = Math.sqrt(normSq);
122
- if (norm > maxNorm && norm > 0) {
123
- const scale = maxNorm / norm;
124
- for (const g of grads)
125
- for (let i = 0; i < g.data.length; i++)
126
- g.data[i] *= scale;
127
- }
128
- return norm;
129
- }
130
- _adamwStepCpu(grads, hp) {
131
- const params = this.model.parameters();
132
- const { learningRate: lr, weightDecay: wd, beta1, beta2, eps, beta1_t, beta2_t } = hp;
133
- for (let pi = 0; pi < params.length; pi++) {
134
- const p = params[pi].data;
135
- const g = grads[pi].data;
136
- const mom = this._moments[pi];
137
- for (let i = 0; i < p.length; i++) {
138
- const gi = g[i];
139
- mom.m[i] = beta1 * mom.m[i] + (1 - beta1) * gi;
140
- mom.v[i] = beta2 * mom.v[i] + (1 - beta2) * gi * gi;
141
- const mHat = mom.m[i] / (1 - beta1_t);
142
- const vHat = mom.v[i] / (1 - beta2_t);
143
- p[i] = p[i] * (1 - lr * wd) - (lr * mHat) / (Math.sqrt(vHat) + eps);
144
- }
145
- }
146
- }
147
- /** AdamW on the GPU via the shared WEIGHT_UPDATE_WGSL kernel. Awaited per step. */
148
- async _adamwStepGpu(grads, hp) {
149
- const device = this.device;
150
- const pipeline = this._adamwPipeline;
151
- const params = this.model.parameters();
152
- const { learningRate: lr, weightDecay: wd, beta1, beta2, eps, beta1_t, beta2_t } = hp;
153
- for (let pi = 0; pi < params.length; pi++) {
154
- const p = params[pi];
155
- const mom = this._moments[pi];
156
- const paramBuf = createStorageBuffer(device, p.data, true);
157
- const gradBuf = createStorageBuffer(device, grads[pi].data, false);
158
- const mBuf = createStorageBuffer(device, mom.m, true);
159
- const vBuf = createStorageBuffer(device, mom.v, true);
160
- const uni = createUniformBuffer(device, packAdamParams(p.numel, lr, beta1, beta2, eps, wd, beta1_t, beta2_t));
161
- const bg = createBindGroup(device, pipeline, [uni, paramBuf, gradBuf, mBuf, vBuf]);
162
- dispatchKernel(device, pipeline, bg, [cdiv(p.numel, 256), 1, 1]);
163
- p.data.set((await readBuffer(device, paramBuf, p.numel * 4)).subarray(0, p.numel));
164
- mom.m.set((await readBuffer(device, mBuf, p.numel * 4)).subarray(0, p.numel));
165
- mom.v.set((await readBuffer(device, vBuf, p.numel * 4)).subarray(0, p.numel));
166
- paramBuf.destroy();
167
- gradBuf.destroy();
168
- mBuf.destroy();
169
- vBuf.destroy();
170
- uni.destroy();
171
- }
65
+ return this._trainer.evaluate(samples);
172
66
  }
173
67
  }
174
68
  //# sourceMappingURL=limbic_trainer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"limbic_trainer.js","sourceRoot":"","sources":["../../src/limbic/limbic_trainer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"limbic_trainer.js","sourceRoot":"","sources":["../../src/limbic/limbic_trainer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,WAAW,EAA6C,MAAM,uBAAuB,CAAC;AAkB/F;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,KAAkB;IAC3C,OAAO;QACL,UAAU,EAAE,GAAkB,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE;QACnD,SAAS,EAAE,GAAkB,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE;QACjD,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE;QAChC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAChB,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI;QACxF,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;YACV,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;YACtC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAC9D,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;gBAChD,IAAI,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,CAAC;YACD,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;YAC/B,IAAI,IAAI,GAAG,GAAG,YAAY,GAAG,EAAE,GAAG,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,OAAO,aAAa;IACf,KAAK,CAAc;IACnB,MAAM,CAAmB;IACjB,QAAQ,CAA4B;IAErD,YAAY,KAAkB,EAAE,SAA2B,IAAI;QAC7D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IAC9E,CAAC;IAED,kDAAkD;IAClD,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAuB,EAAE,OAA2B,EAAE;QAC1D,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,+EAA+E;IAC/E,QAAQ,CAAC,OAAuB;QAC9B,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;CACF"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * ml/classical/ewma.ts — exponentially-weighted moving average + variance, for
3
+ * drift anomalies in an ordered series (a run's cost creeping up over the week).
4
+ *
5
+ * Per feature, over the history IN ORDER: diff = x − μ; μ += α·diff;
6
+ * σ² = (1 − α)(σ² + α·diff²). A new point scores z = |x − μ| / σ against the
7
+ * state BEFORE it is folded in. Prediction: `scores[0] = max_i z_i / threshold`.
8
+ */
9
+ import type { MlPrediction, MlPredictor, MlSample } from "../types.js";
10
+ export interface EwmaOptions {
11
+ /** Smoothing factor in (0, 1]. Default 0.3. */
12
+ alpha?: number;
13
+ /** z at which a feature counts as anomalous. Default 3. */
14
+ threshold?: number;
15
+ /** Smallest σ per feature, as a fraction of |μ| (plus 1e-9). Default 0.01. */
16
+ minScaleFraction?: number;
17
+ }
18
+ export declare class EwmaModel implements MlPredictor {
19
+ readonly mean: Float64Array;
20
+ readonly variance: Float64Array;
21
+ readonly alpha: number;
22
+ readonly threshold: number;
23
+ readonly minScaleFraction: number;
24
+ constructor(mean: Float64Array, variance: Float64Array, alpha: number, threshold: number, minScaleFraction: number);
25
+ zScores(x: ArrayLike<number>): number[];
26
+ /** Fold one observation into the running state. */
27
+ update(x: ArrayLike<number>): void;
28
+ predict(x: Float32Array): MlPrediction;
29
+ }
30
+ /** Fit over `samples` in the given (chronological) order. */
31
+ export declare function fitEwma(samples: readonly MlSample[], opts?: EwmaOptions): EwmaModel;
32
+ //# sourceMappingURL=ewma.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ewma.d.ts","sourceRoot":"","sources":["../../../src/ml/classical/ewma.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvE,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,SAAU,YAAW,WAAW;IAEzC,QAAQ,CAAC,IAAI,EAAE,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,YAAY;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,MAAM;gBAJxB,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,YAAY,EACtB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM;IAKnC,OAAO,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;IAOvC,mDAAmD;IACnD,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI;IASlC,OAAO,CAAC,CAAC,EAAE,YAAY,GAAG,YAAY;CAIvC;AAED,6DAA6D;AAC7D,wBAAgB,OAAO,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,EAAE,IAAI,GAAE,WAAgB,GAAG,SAAS,CAWvF"}
@@ -0,0 +1,46 @@
1
+ import { featureDim } from "./math.js";
2
+ import { anomalyConfidence } from "./robust_z.js";
3
+ export class EwmaModel {
4
+ mean;
5
+ variance;
6
+ alpha;
7
+ threshold;
8
+ minScaleFraction;
9
+ constructor(mean, variance, alpha, threshold, minScaleFraction) {
10
+ this.mean = mean;
11
+ this.variance = variance;
12
+ this.alpha = alpha;
13
+ this.threshold = threshold;
14
+ this.minScaleFraction = minScaleFraction;
15
+ if (!(alpha > 0 && alpha <= 1))
16
+ throw new Error(`EwmaModel: alpha must be in (0, 1] (got ${alpha})`);
17
+ }
18
+ zScores(x) {
19
+ return Array.from(this.mean, (m, i) => {
20
+ const sd = Math.max(Math.sqrt(this.variance[i]), this.minScaleFraction * Math.abs(m) + 1e-9);
21
+ return Math.abs((x[i] ?? 0) - m) / sd;
22
+ });
23
+ }
24
+ /** Fold one observation into the running state. */
25
+ update(x) {
26
+ for (let i = 0; i < this.mean.length; i++) {
27
+ const diff = (x[i] ?? 0) - this.mean[i];
28
+ const incr = this.alpha * diff;
29
+ this.mean[i] = this.mean[i] + incr;
30
+ this.variance[i] = (1 - this.alpha) * (this.variance[i] + diff * incr);
31
+ }
32
+ }
33
+ predict(x) {
34
+ const score = Math.max(0, ...this.zScores(x)) / this.threshold;
35
+ return { scores: [score], confidence: anomalyConfidence(score) };
36
+ }
37
+ }
38
+ /** Fit over `samples` in the given (chronological) order. */
39
+ export function fitEwma(samples, opts = {}) {
40
+ const d = featureDim(samples.map((s) => s.x));
41
+ const model = new EwmaModel(Float64Array.from(samples[0].x), new Float64Array(d), opts.alpha ?? 0.3, opts.threshold ?? 3, opts.minScaleFraction ?? 0.01);
42
+ for (let i = 1; i < samples.length; i++)
43
+ model.update(samples[i].x);
44
+ return model;
45
+ }
46
+ //# sourceMappingURL=ewma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ewma.js","sourceRoot":"","sources":["../../../src/ml/classical/ewma.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * ml/classical/gbm.ts — a small gradient-boosted tree ensemble.
3
+ *
4
+ * Depth-limited regression trees fitted to the loss gradient, one after another,
5
+ * shrunk by a learning rate. Objectives: `binary` (log-loss, Newton leaf values)
6
+ * and `regression` (squared error). Exhaustive split search over midpoints —
7
+ * fine for the catalog's small numeric feature sets, not for wide embeddings.
8
+ */
9
+ import type { MlPrediction, MlPredictor, MlSample } from "../types.js";
10
+ import { type Vec } from "./math.js";
11
+ export type GbmObjective = "binary" | "regression";
12
+ export interface GbmOptions {
13
+ objective?: GbmObjective;
14
+ trees?: number;
15
+ maxDepth?: number;
16
+ learningRate?: number;
17
+ /** Minimum summed sample weight in a leaf. Default 1. */
18
+ minLeafWeight?: number;
19
+ /** L2 on leaf values (Newton denominator). Default 1. */
20
+ lambda?: number;
21
+ }
22
+ type RTree = {
23
+ value: number;
24
+ } | {
25
+ feature: number;
26
+ split: number;
27
+ left: RTree;
28
+ right: RTree;
29
+ };
30
+ export declare class GbmModel implements MlPredictor {
31
+ readonly objective: GbmObjective;
32
+ readonly base: number;
33
+ readonly trees: readonly RTree[];
34
+ readonly learningRate: number;
35
+ constructor(objective: GbmObjective, base: number, trees: readonly RTree[], learningRate: number);
36
+ /** The raw additive score (log-odds for `binary`). */
37
+ margin(x: Vec): number;
38
+ predict(x: Float32Array): MlPrediction;
39
+ }
40
+ export declare function fitGbm(samples: readonly MlSample[], opts?: GbmOptions): GbmModel;
41
+ export {};
42
+ //# sourceMappingURL=gbm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gbm.d.ts","sourceRoot":"","sources":["../../../src/ml/classical/gbm.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAuB,KAAK,GAAG,EAAE,MAAM,WAAW,CAAC;AAE1D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,KAAK,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAkE/F,qBAAa,QAAS,YAAW,WAAW;IAExC,QAAQ,CAAC,SAAS,EAAE,YAAY;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,KAAK,EAAE;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM;gBAHpB,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,KAAK,EAAE,EACvB,YAAY,EAAE,MAAM;IAG/B,sDAAsD;IACtD,MAAM,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM;IAMtB,OAAO,CAAC,CAAC,EAAE,YAAY,GAAG,YAAY;CAMvC;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,EAAE,IAAI,GAAE,UAAe,GAAG,QAAQ,CA6BpF"}