train-kit / test / types / consumer.ts
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
 * TS smoke-compile of the exported API — exercises every symbol the bot (and
 * the example trainer) uses, plus the rest of the surface: value imports,
 * `import type`, generics, `new`, getter properties, promises. Compiled by
 * `npm run check`; never executed.
 */
import {
  // the bot's import list
  CheckpointStore,
  checkpointPath,
  EpisodeWriter,
  mlpForward,
  isMlpModel,
  isTabularModel,
  pickAction,
  // the rest of the exported surface
  isModel,
  modelRev,
  modelVersion,
  mlpInit,
  readNewTransitions,
  candidatePath,
  loadModel,
  saveModel,
  ensureRow,
  qUpdate,
  netQs,
  dqnTargets,
  capReplay,
  loadTf,
  netToTf,
  tfToNet,
  fitNet,
  resolveModel,
  gatePromotion,
  expandDirs,
  ingestStatePath,
  loadIngestState,
  saveIngestState,
} from "ardegazu-train-kit";
import type {
  MlpJson,
  MlpModel,
  TabularModel,
  AnyModel,
  KeyedTransition,
  FeatureTransition,
  Transition,
  IngestState,
  TF,
} from "ardegazu-train-kit";

type Game = "valley-blocks";

// ---- model + forward -------------------------------------------------------
const net: MlpJson = mlpInit([4, 8, 1], () => 0.5);
const out: number[] = mlpForward(net, [1, 2, 3, 4]);
const a: number = pickAction(out, 0.1);
const a2: number = pickAction(out, 0.1, () => 0.5);

const unknownModel: unknown = null;
if (isMlpModel<Game>(unknownModel, "valley-blocks")) {
  const m: MlpModel<Game> = unknownModel;
  const g: Game = m.game;
  void g;
  void m.net.layers[0].w;
}
if (isTabularModel(unknownModel)) {
  const t: TabularModel = unknownModel;
  const row: number[] | undefined = t.q["s0"];
  void row;
}
if (isModel(unknownModel)) {
  const any: AnyModel = unknownModel;
  void any.episodes;
}

// ---- rev -------------------------------------------------------------------
const tabForRev: TabularModel<Game> = { v: 1, game: "valley-blocks", episodes: 7, updatedAt: 0, q: { s0: [0, 1] } };
const rev: string = modelRev(tabForRev);
const version: string = modelVersion(tabForRev);
const noModel: string = modelVersion(null);
const maybeVersion: string = modelVersion(loadModel("/models/valley-blocks.json"));
const junkVersion: string = modelVersion(JSON.parse("{}")); // total: any input, no cast
const storedRev: string | undefined = tabForRev.rev; // optional, traceability only
void rev; void version; void noModel; void maybeVersion; void junkVersion; void storedRev;

// inline import("pkg").Type — the deferred-typing form consumers use
type InlineModel = import("ardegazu-train-kit").MlpModel;
const inline: InlineModel | null = null;
void inline;

// ---- episodes --------------------------------------------------------------
const keyed: KeyedTransition<Game> = { g: "valley-blocks", s: "k", a: 0, r: 1, s2: null, done: true };
const feat: FeatureTransition<Game> = { g: "valley-blocks", f: [[1, 0]], a: 0, r: 0.5, f2: null, done: true };
const anyT: Transition = Math.random() > 0.5 ? keyed : feat;

const w = new EpisodeWriter("/data");
w.add(anyT);
const pending: number = w.pending; // getter property, not a method
w.flush();

const state: IngestState = { offsets: {} };
const fresh: Transition[] = readNewTransitions(["/data/episodes"], "valley-blocks", state);
void fresh;

// ---- checkpoint ------------------------------------------------------------
const live: string = checkpointPath("/models", "valley-blocks");
const cand: string = candidatePath("/models", "valley-blocks");
const loaded: AnyModel | null = loadModel(live);
if (loaded) saveModel(cand, loaded);

const store = new CheckpointStore(live, 30_000, (m: AnyModel) => void m.updatedAt);
const storeNoCb = new CheckpointStore(live, 0);
const current: AnyModel | null = store.model; // getter property, not a method
if (current && isMlpModel<Game>(current, "valley-blocks")) void netQs(current.net, [[1, 2, 3, 4]]);
store.close();
storeNoCb.close();

// ---- tabular ---------------------------------------------------------------
const tab: TabularModel<Game> = { v: 1, game: "valley-blocks", episodes: 0, updatedAt: 0, q: {} };
const row: number[] = ensureRow(tab, "s0", 3);
void row;
qUpdate(tab, keyed, { alpha: 0.1, gamma: 0.9, nActions: 3 });

// ---- dqn -------------------------------------------------------------------
const qs: number[] = netQs(net, [[1, 2, 3, 4]]);
const batch: readonly FeatureTransition[] = [feat];
const { xs, ys }: { xs: number[][]; ys: number[] } = dqnTargets(net, batch, 0.9);
const replay: FeatureTransition[] = [feat];
capReplay(replay, 10_000);
capReplay([1, 2, 3], 2); // generic over any element type

// ---- tf (types only — the optional peer stays load-time dynamic) -----------
async function trainOnce(): Promise<MlpJson> {
  const tf: TF = await loadTf();
  const seq = netToTf(tf, net, 0.001);
  const back: MlpJson = tfToNet(tf, seq, net.sizes);
  void back;
  return fitNet(net, xs, ys, { lr: 0.001, epochs: 10, batchSize: 128 });
}
void trainOnce;

// ---- gate + ingest ---------------------------------------------------------
const resumed: AnyModel | null = resolveModel("/models", "valley-blocks");
const wrote: string = resumed ? gatePromotion("/models", "valley-blocks", resumed, true) : "";
void wrote;

const dirs: string[] = expandDirs(["/state/*/episodes"]);
void dirs;
const isp: string = ingestStatePath("/models");
void isp;
const ist: IngestState = loadIngestState("/models");
saveIngestState("/models", ist);

void a; void a2; void pending; void qs; void ys; void out; void live;

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/train-kit.git