poke-crucible 0.1.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +192 -0
  3. package/dist/battle/pairing.d.ts +25 -0
  4. package/dist/battle/pairing.js +59 -0
  5. package/dist/battle/pairing.js.map +1 -0
  6. package/dist/battle/pool.d.ts +25 -0
  7. package/dist/battle/pool.js +97 -0
  8. package/dist/battle/pool.js.map +1 -0
  9. package/dist/battle/run-battle.d.ts +13 -0
  10. package/dist/battle/run-battle.js +49 -0
  11. package/dist/battle/run-battle.js.map +1 -0
  12. package/dist/battle/worker.d.ts +1 -0
  13. package/dist/battle/worker.js +21 -0
  14. package/dist/battle/worker.js.map +1 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.js +326 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/critic/agent-sdk-model.d.ts +27 -0
  19. package/dist/critic/agent-sdk-model.js +21 -0
  20. package/dist/critic/agent-sdk-model.js.map +1 -0
  21. package/dist/critic/critique.d.ts +21 -0
  22. package/dist/critic/critique.js +51 -0
  23. package/dist/critic/critique.js.map +1 -0
  24. package/dist/critic/evidence.d.ts +24 -0
  25. package/dist/critic/evidence.js +17 -0
  26. package/dist/critic/evidence.js.map +1 -0
  27. package/dist/critic/llm.d.ts +34 -0
  28. package/dist/critic/llm.js +23 -0
  29. package/dist/critic/llm.js.map +1 -0
  30. package/dist/critic/parse.d.ts +5 -0
  31. package/dist/critic/parse.js +84 -0
  32. package/dist/critic/parse.js.map +1 -0
  33. package/dist/critic/prompt.d.ts +14 -0
  34. package/dist/critic/prompt.js +56 -0
  35. package/dist/critic/prompt.js.map +1 -0
  36. package/dist/critic/types.d.ts +52 -0
  37. package/dist/critic/types.js +2 -0
  38. package/dist/critic/types.js.map +1 -0
  39. package/dist/designer/agent-sdk-model.d.ts +30 -0
  40. package/dist/designer/agent-sdk-model.js +62 -0
  41. package/dist/designer/agent-sdk-model.js.map +1 -0
  42. package/dist/designer/design.d.ts +12 -0
  43. package/dist/designer/design.js +218 -0
  44. package/dist/designer/design.js.map +1 -0
  45. package/dist/designer/fitness.d.ts +25 -0
  46. package/dist/designer/fitness.js +24 -0
  47. package/dist/designer/fitness.js.map +1 -0
  48. package/dist/designer/model.d.ts +14 -0
  49. package/dist/designer/model.js +27 -0
  50. package/dist/designer/model.js.map +1 -0
  51. package/dist/designer/mutate.d.ts +31 -0
  52. package/dist/designer/mutate.js +209 -0
  53. package/dist/designer/mutate.js.map +1 -0
  54. package/dist/designer/rng.d.ts +17 -0
  55. package/dist/designer/rng.js +40 -0
  56. package/dist/designer/rng.js.map +1 -0
  57. package/dist/designer/types.d.ts +103 -0
  58. package/dist/designer/types.js +2 -0
  59. package/dist/designer/types.js.map +1 -0
  60. package/dist/evaluate.d.ts +11 -0
  61. package/dist/evaluate.js +99 -0
  62. package/dist/evaluate.js.map +1 -0
  63. package/dist/gauntlet/gauntlet.d.ts +18 -0
  64. package/dist/gauntlet/gauntlet.js +41 -0
  65. package/dist/gauntlet/gauntlet.js.map +1 -0
  66. package/dist/gauntlet/teams-g1.d.ts +23 -0
  67. package/dist/gauntlet/teams-g1.js +476 -0
  68. package/dist/gauntlet/teams-g1.js.map +1 -0
  69. package/dist/gauntlet/teams-g2.d.ts +14 -0
  70. package/dist/gauntlet/teams-g2.js +725 -0
  71. package/dist/gauntlet/teams-g2.js.map +1 -0
  72. package/dist/index.d.ts +25 -0
  73. package/dist/index.js +24 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/llm/agent-query.d.ts +21 -0
  76. package/dist/llm/agent-query.js +70 -0
  77. package/dist/llm/agent-query.js.map +1 -0
  78. package/dist/pilot/damage.d.ts +34 -0
  79. package/dist/pilot/damage.js +75 -0
  80. package/dist/pilot/damage.js.map +1 -0
  81. package/dist/pilot/eval-pilot.d.ts +39 -0
  82. package/dist/pilot/eval-pilot.js +161 -0
  83. package/dist/pilot/eval-pilot.js.map +1 -0
  84. package/dist/pilot/pilot.d.ts +71 -0
  85. package/dist/pilot/pilot.js +290 -0
  86. package/dist/pilot/pilot.js.map +1 -0
  87. package/dist/ranking.d.ts +25 -0
  88. package/dist/ranking.js +40 -0
  89. package/dist/ranking.js.map +1 -0
  90. package/dist/seed.d.ts +13 -0
  91. package/dist/seed.js +42 -0
  92. package/dist/seed.js.map +1 -0
  93. package/dist/team.d.ts +29 -0
  94. package/dist/team.js +100 -0
  95. package/dist/team.js.map +1 -0
  96. package/dist/types.d.ts +77 -0
  97. package/dist/types.js +8 -0
  98. package/dist/types.js.map +1 -0
  99. package/package.json +57 -0
@@ -0,0 +1,14 @@
1
+ import type { DesignerModel } from './types.js';
2
+ export declare class StubDesignerModel implements DesignerModel {
3
+ private readonly proposals;
4
+ readonly name: string;
5
+ /** The last critique passed to proposeMutations — lets a test verify the
6
+ * Critic actually drove the proposals (User Story 11). */
7
+ lastCritique: string | undefined;
8
+ constructor(proposals?: string[], name?: string);
9
+ proposeMutations(_paste: string, critique?: string): Promise<string[]>;
10
+ nameArchetype(paste: string): Promise<{
11
+ archetype: string;
12
+ novel: boolean;
13
+ }>;
14
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Stub {@link DesignerModel} — lets the whole search loop run with no
3
+ * subscription call. It proposes no LLM mutations (the search falls back to the
4
+ * random variation operators) and names Archetypes from the lead species.
5
+ */
6
+ import { Teams } from '@pkmn/sim';
7
+ export class StubDesignerModel {
8
+ proposals;
9
+ name;
10
+ /** The last critique passed to proposeMutations — lets a test verify the
11
+ * Critic actually drove the proposals (User Story 11). */
12
+ lastCritique;
13
+ constructor(proposals = [], name = 'stub') {
14
+ this.proposals = proposals;
15
+ this.name = name;
16
+ }
17
+ async proposeMutations(_paste, critique) {
18
+ this.lastCritique = critique;
19
+ return this.proposals;
20
+ }
21
+ async nameArchetype(paste) {
22
+ const team = Teams.import(paste);
23
+ const lead = team?.[0]?.species || 'Team';
24
+ return { archetype: `${lead} core`, novel: false };
25
+ }
26
+ }
27
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/designer/model.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAGlC,MAAM,OAAO,iBAAiB;IAOT;IANV,IAAI,CAAS;IACtB;+DAC2D;IAC3D,YAAY,CAAqB;IAEjC,YACmB,YAAsB,EAAE,EACzC,IAAI,GAAG,MAAM;QADI,cAAS,GAAT,SAAS,CAAe;QAGzC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,MAAc,EAAE,QAAiB;QACtD,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAAa;QAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC;QAC1C,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACrD,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ import type { PokemonSet } from '@pkmn/sim';
2
+ import { Rng } from './rng.js';
3
+ export type Team = PokemonSet[];
4
+ export declare function isLegal(team: Team): boolean;
5
+ /** Serialize a parsed Team to paste + packed forms. */
6
+ export declare function serialize(team: Team): {
7
+ paste: string;
8
+ packed: string;
9
+ };
10
+ /** Import a paste to a parsed Team (or null). */
11
+ export declare function parse(paste: string): Team | null;
12
+ /** Deduped individual sets drawn from a set of Teams — the gene pool. */
13
+ export declare function buildGenePool(pastes: string[]): PokemonSet[];
14
+ /**
15
+ * Per-species move pool: every move any set of that species runs across the
16
+ * source Teams. Lets the move-swap operator explore real, legal move choices
17
+ * (e.g. every move a Gauntlet Tyranitar has been given) without learnset data.
18
+ */
19
+ export declare function buildMovePool(pastes: string[]): Map<string, string[]>;
20
+ export declare function shuffle<T>(items: readonly T[], rng: Rng): T[];
21
+ /** A Team of up to `size` unique-species sets drawn (shuffled) from `sets`. */
22
+ export declare function uniqueSpeciesTeam(sets: PokemonSet[], size: number, rng: Rng): Team;
23
+ /** Mutate a Team into a *legal* variant. Tries operators in a random order and
24
+ * validates each; returns the mutated Team + operator, or null if none stuck.
25
+ * When a move pool is given, a move-swap operator is added. */
26
+ export declare function mutate(team: Team, pool: PokemonSet[], rng: Rng, movePool?: Map<string, string[]>): {
27
+ team: Team;
28
+ operator: string;
29
+ } | null;
30
+ /** Breed two parents into a *legal* child (unique species, up to 6 members). */
31
+ export declare function crossover(a: Team, b: Team, rng: Rng): Team | null;
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Variation operators — legality-closed. Each mutation/crossover produces a
3
+ * candidate Team, and only a candidate that validates as legal Gen 3 OU (via the
4
+ * Slice-1 validator) is returned; illegal candidates are rejected. Operators are
5
+ * pure given an {@link Rng}, so the whole search is reproducible.
6
+ */
7
+ import { Dex, Teams, TeamValidator, toID } from '@pkmn/sim';
8
+ const gen3 = Dex.forFormat('gen3ou');
9
+ const validator = new TeamValidator('gen3ou');
10
+ /** A pool of common, legal Gen 3 OU items to mutate toward. */
11
+ const ITEMS = [
12
+ 'Leftovers', 'Choice Band', 'Lum Berry', 'Salac Berry', 'Sitrus Berry',
13
+ 'Petaya Berry', 'Liechi Berry', 'Chesto Berry',
14
+ ];
15
+ const NATURES = [
16
+ 'Adamant', 'Jolly', 'Modest', 'Timid', 'Bold', 'Impish', 'Careful', 'Calm',
17
+ 'Relaxed', 'Sassy', 'Naughty', 'Hardy',
18
+ ];
19
+ const STATS = ['hp', 'atk', 'def', 'spa', 'spd', 'spe'];
20
+ function cloneSet(s) {
21
+ return { ...s, moves: [...s.moves], evs: { ...s.evs }, ivs: s.ivs ? { ...s.ivs } : s.ivs };
22
+ }
23
+ function cloneTeam(t) {
24
+ return t.map(cloneSet);
25
+ }
26
+ function speciesOf(s) {
27
+ return gen3.species.get(s.species || s.name).name || s.species || s.name;
28
+ }
29
+ export function isLegal(team) {
30
+ const problems = validator.validateTeam(cloneTeam(team));
31
+ return !problems || problems.length === 0;
32
+ }
33
+ /** Serialize a parsed Team to paste + packed forms. */
34
+ export function serialize(team) {
35
+ return { paste: Teams.export(team), packed: Teams.pack(team) };
36
+ }
37
+ /** Import a paste to a parsed Team (or null). */
38
+ export function parse(paste) {
39
+ return Teams.import(paste);
40
+ }
41
+ /** Deduped individual sets drawn from a set of Teams — the gene pool. */
42
+ export function buildGenePool(pastes) {
43
+ const bySpecies = new Map();
44
+ for (const paste of pastes) {
45
+ const team = Teams.import(paste);
46
+ if (!team)
47
+ continue;
48
+ for (const s of team) {
49
+ const sp = speciesOf(s);
50
+ if (sp && !bySpecies.has(sp))
51
+ bySpecies.set(sp, cloneSet(s));
52
+ }
53
+ }
54
+ return [...bySpecies.values()];
55
+ }
56
+ /**
57
+ * Per-species move pool: every move any set of that species runs across the
58
+ * source Teams. Lets the move-swap operator explore real, legal move choices
59
+ * (e.g. every move a Gauntlet Tyranitar has been given) without learnset data.
60
+ */
61
+ export function buildMovePool(pastes) {
62
+ const bySpecies = new Map();
63
+ for (const paste of pastes) {
64
+ const team = Teams.import(paste);
65
+ if (!team)
66
+ continue;
67
+ for (const s of team) {
68
+ const sp = speciesOf(s);
69
+ const moves = bySpecies.get(sp) ?? new Set();
70
+ for (const m of s.moves)
71
+ moves.add(m);
72
+ bySpecies.set(sp, moves);
73
+ }
74
+ }
75
+ const out = new Map();
76
+ for (const [sp, moves] of bySpecies)
77
+ out.set(sp, [...moves]);
78
+ return out;
79
+ }
80
+ export function shuffle(items, rng) {
81
+ const a = [...items];
82
+ for (let i = a.length - 1; i > 0; i--) {
83
+ const j = rng.int(i + 1);
84
+ [a[i], a[j]] = [a[j], a[i]];
85
+ }
86
+ return a;
87
+ }
88
+ /** A Team of up to `size` unique-species sets drawn (shuffled) from `sets`. */
89
+ export function uniqueSpeciesTeam(sets, size, rng) {
90
+ const team = [];
91
+ const species = new Set();
92
+ for (const s of shuffle(sets, rng)) {
93
+ if (team.length >= size)
94
+ break;
95
+ const sp = speciesOf(s);
96
+ if (!species.has(sp)) {
97
+ team.push(cloneSet(s));
98
+ species.add(sp);
99
+ }
100
+ }
101
+ return team;
102
+ }
103
+ const swapItem = {
104
+ name: 'swap-item',
105
+ apply(team, _pool, rng) {
106
+ const t = cloneTeam(team);
107
+ const i = rng.int(t.length);
108
+ const choice = rng.pick(ITEMS.filter((x) => x !== t[i].item));
109
+ if (!choice)
110
+ return null;
111
+ t[i].item = choice;
112
+ return t;
113
+ },
114
+ };
115
+ const swapNature = {
116
+ name: 'swap-nature',
117
+ apply(team, _pool, rng) {
118
+ const t = cloneTeam(team);
119
+ const i = rng.int(t.length);
120
+ const choice = rng.pick(NATURES.filter((x) => x !== t[i].nature));
121
+ if (!choice)
122
+ return null;
123
+ t[i].nature = choice;
124
+ return t;
125
+ },
126
+ };
127
+ const reshuffleEvs = {
128
+ name: 'reshuffle-evs',
129
+ apply(team, _pool, rng) {
130
+ const t = cloneTeam(team);
131
+ const i = rng.int(t.length);
132
+ const [a, b, c] = shuffle([...STATS], rng);
133
+ const evs = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 };
134
+ evs[a] = 252;
135
+ evs[b] = 252;
136
+ evs[c] = 4;
137
+ t[i].evs = evs;
138
+ return t;
139
+ },
140
+ };
141
+ const swapAbility = {
142
+ name: 'swap-ability',
143
+ apply(team, _pool, rng) {
144
+ const t = cloneTeam(team);
145
+ const order = shuffle(t.map((_, i) => i), rng);
146
+ for (const i of order) {
147
+ const abilities = gen3.species.get(speciesOf(t[i])).abilities;
148
+ const options = Object.values(abilities).filter((a) => a && a !== t[i].ability);
149
+ const choice = rng.pick(options);
150
+ if (choice) {
151
+ t[i].ability = choice;
152
+ return t;
153
+ }
154
+ }
155
+ return null; // no member had a second ability
156
+ },
157
+ };
158
+ const swapMember = {
159
+ name: 'swap-member',
160
+ apply(team, pool, rng) {
161
+ const t = cloneTeam(team);
162
+ const i = rng.int(t.length);
163
+ const present = new Set(t.map((s, idx) => (idx === i ? '' : speciesOf(s))));
164
+ const candidates = pool.filter((s) => !present.has(speciesOf(s)));
165
+ const chosen = rng.pick(candidates);
166
+ if (!chosen)
167
+ return null;
168
+ t[i] = cloneSet(chosen);
169
+ return t;
170
+ },
171
+ };
172
+ /** Swap one move for another the same species runs elsewhere (move-pool driven). */
173
+ function makeSwapMove(movePool) {
174
+ return {
175
+ name: 'swap-move',
176
+ apply(team, _pool, rng) {
177
+ const t = cloneTeam(team);
178
+ for (const i of shuffle(t.map((_, idx) => idx), rng)) {
179
+ const options = (movePool.get(speciesOf(t[i])) ?? []).filter((m) => !t[i].moves.some((cur) => toID(cur) === toID(m)));
180
+ const choice = rng.pick(options);
181
+ if (choice) {
182
+ t[i].moves[rng.int(t[i].moves.length)] = choice;
183
+ return t;
184
+ }
185
+ }
186
+ return null; // no member had an unused pooled move
187
+ },
188
+ };
189
+ }
190
+ const OPERATORS = [swapMember, swapItem, reshuffleEvs, swapNature, swapAbility];
191
+ /** Mutate a Team into a *legal* variant. Tries operators in a random order and
192
+ * validates each; returns the mutated Team + operator, or null if none stuck.
193
+ * When a move pool is given, a move-swap operator is added. */
194
+ export function mutate(team, pool, rng, movePool) {
195
+ const operators = movePool ? [...OPERATORS, makeSwapMove(movePool)] : OPERATORS;
196
+ for (const op of shuffle(operators, rng)) {
197
+ const candidate = op.apply(team, pool, rng);
198
+ if (candidate && isLegal(candidate))
199
+ return { team: candidate, operator: op.name };
200
+ }
201
+ return null;
202
+ }
203
+ /** Breed two parents into a *legal* child (unique species, up to 6 members). */
204
+ export function crossover(a, b, rng) {
205
+ const size = Math.max(a.length, b.length, 1);
206
+ const child = uniqueSpeciesTeam([...a, ...b], size, rng);
207
+ return child.length >= 1 && isLegal(child) ? child : null;
208
+ }
209
+ //# sourceMappingURL=mutate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutate.js","sourceRoot":"","sources":["../../src/designer/mutate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAI5D,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;AACrC,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC;AAE9C,+DAA+D;AAC/D,MAAM,KAAK,GAAG;IACZ,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc;IACtE,cAAc,EAAE,cAAc,EAAE,cAAc;CAC/C,CAAC;AACF,MAAM,OAAO,GAAG;IACd,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM;IAC1E,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO;CACvC,CAAC;AACF,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAIjE,SAAS,QAAQ,CAAC,CAAa;IAC7B,OAAO,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AAC7F,CAAC;AACD,SAAS,SAAS,CAAC,CAAO;IACxB,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACzB,CAAC;AACD,SAAS,SAAS,CAAC,CAAa;IAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAU;IAChC,MAAM,QAAQ,GAAG,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,SAAS,CAAC,IAAU;IAClC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACjE,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,KAAK,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,aAAa,CAAC,MAAgB;IAC5C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAsB,CAAC;IAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,MAAgB;IAC5C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAuB,CAAC;IACjD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;YACrD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK;gBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACtC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IACxC,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,SAAS;QAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;IAC7D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,OAAO,CAAI,KAAmB,EAAE,GAAQ;IACtD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,iBAAiB,CAAC,IAAkB,EAAE,IAAY,EAAE,GAAQ;IAC1E,MAAM,IAAI,GAAS,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI;YAAE,MAAM;QAC/B,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAOD,MAAM,QAAQ,GAAa;IACzB,IAAI,EAAE,WAAW;IACjB,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG;QACpB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,GAAG,MAAM,CAAC;QACpB,OAAO,CAAC,CAAC;IACX,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,GAAa;IAC3B,IAAI,EAAE,aAAa;IACnB,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG;QACpB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,CAAC,CAAC,CAAC,CAAE,CAAC,MAAM,GAAG,MAAM,CAAC;QACtB,OAAO,CAAC,CAAC;IACX,CAAC;CACF,CAAC;AAEF,MAAM,YAAY,GAAa;IAC7B,IAAI,EAAE,eAAe;IACrB,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG;QACpB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,CAAE,CAAC,GAAG,GAAG,CAAC;QACd,GAAG,CAAC,CAAE,CAAC,GAAG,GAAG,CAAC;QACd,GAAG,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC,CAAE,CAAC,GAAG,GAAG,GAAG,CAAC;QAChB,OAAO,CAAC,CAAC;IACX,CAAC;CACF,CAAC;AAEF,MAAM,WAAW,GAAa;IAC5B,IAAI,EAAE,cAAc;IACpB,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG;QACpB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,KAAK,GAAG,OAAO,CACnB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAClB,GAAG,CACJ,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,SAA8C,CAAC;YACpG,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC;YACjF,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACjC,IAAI,MAAM,EAAE,CAAC;gBACX,CAAC,CAAC,CAAC,CAAE,CAAC,OAAO,GAAG,MAAM,CAAC;gBACvB,OAAO,CAAC,CAAC;YACX,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,CAAC,iCAAiC;IAChD,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,GAAa;IAC3B,IAAI,EAAE,aAAa;IACnB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG;QACnB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QACxB,OAAO,CAAC,CAAC;IACX,CAAC;CACF,CAAC;AAEF,oFAAoF;AACpF,SAAS,YAAY,CAAC,QAA+B;IACnD,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG;YACpB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAC1B,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;gBACrD,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAC3D,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CACzD,CAAC;gBACF,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACjC,IAAI,MAAM,EAAE,CAAC;oBACX,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC;oBAClD,OAAO,CAAC,CAAC;gBACX,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC,CAAC,sCAAsC;QACrD,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,SAAS,GAAe,CAAC,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAE5F;;gEAEgE;AAChE,MAAM,UAAU,MAAM,CACpB,IAAU,EACV,IAAkB,EAClB,GAAQ,EACR,QAAgC;IAEhC,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IACrF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,SAAS,CAAC,CAAO,EAAE,CAAO,EAAE,GAAQ;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACzD,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * A small deterministic PRNG for the search's variation and selection, seeded
3
+ * from the master seed string. Threading one RNG through the whole run (plus the
4
+ * seeded battle sub-seeds) is what makes a discovery reproducible.
5
+ */
6
+ export declare class Rng {
7
+ private state;
8
+ constructor(seed: string | number);
9
+ /** Next float in [0, 1). */
10
+ next(): number;
11
+ /** Integer in [0, n). */
12
+ int(n: number): number;
13
+ /** A uniformly-random element (undefined for an empty array). */
14
+ pick<T>(items: readonly T[]): T | undefined;
15
+ /** True with probability p. */
16
+ chance(p: number): boolean;
17
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * A small deterministic PRNG for the search's variation and selection, seeded
3
+ * from the master seed string. Threading one RNG through the whole run (plus the
4
+ * seeded battle sub-seeds) is what makes a discovery reproducible.
5
+ */
6
+ function hashString(s) {
7
+ let h = 2166136261 >>> 0;
8
+ for (let i = 0; i < s.length; i++) {
9
+ h ^= s.charCodeAt(i);
10
+ h = Math.imul(h, 16777619) >>> 0;
11
+ }
12
+ return h >>> 0;
13
+ }
14
+ export class Rng {
15
+ state;
16
+ constructor(seed) {
17
+ this.state = (typeof seed === 'number' ? seed : hashString(seed)) >>> 0;
18
+ }
19
+ /** Next float in [0, 1). */
20
+ next() {
21
+ this.state = (this.state + 0x6d2b79f5) >>> 0;
22
+ let t = this.state;
23
+ t = Math.imul(t ^ (t >>> 15), t | 1);
24
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
25
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
26
+ }
27
+ /** Integer in [0, n). */
28
+ int(n) {
29
+ return Math.floor(this.next() * n);
30
+ }
31
+ /** A uniformly-random element (undefined for an empty array). */
32
+ pick(items) {
33
+ return items.length ? items[this.int(items.length)] : undefined;
34
+ }
35
+ /** True with probability p. */
36
+ chance(p) {
37
+ return this.next() < p;
38
+ }
39
+ }
40
+ //# sourceMappingURL=rng.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rng.js","sourceRoot":"","sources":["../../src/designer/rng.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,GAAG,UAAU,KAAK,CAAC,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,OAAO,GAAG;IACN,KAAK,CAAS;IAEtB,YAAY,IAAqB;QAC/B,IAAI,CAAC,KAAK,GAAG,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;IAC1E,CAAC;IAED,4BAA4B;IAC5B,IAAI;QACF,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QACnB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACrC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC;IAC/C,CAAC;IAED,yBAAyB;IACzB,GAAG,CAAC,CAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,iEAAiE;IACjE,IAAI,CAAI,KAAmB;QACzB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClE,CAAC;IAED,+BAA+B;IAC/B,MAAM,CAAC,CAAS;QACd,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Public contract for the Designer (Slice 3): the discovery loop that invents
3
+ * novel Teams by mutating and breeding them with Strength as the fitness signal.
4
+ * The single seam is `design`; this is the structure it returns.
5
+ */
6
+ import type { MatchupResult, Submission, ValidationError } from '../types.js';
7
+ /** Weights for the composite fitness — the ADR-0004 lean correction lives here. */
8
+ export interface FitnessWeights {
9
+ /** Weight on absolute Strength vs the Gauntlet. */
10
+ gauntlet: number;
11
+ /** Weight on peer performance within the evolving population. */
12
+ peer: number;
13
+ /** Weight on the worst-matchup floor (rewards robust, flat profiles). */
14
+ robustness: number;
15
+ }
16
+ export interface DesignBudget {
17
+ /** Teams kept per generation. */
18
+ population?: number;
19
+ /** Generations to run. */
20
+ generations?: number;
21
+ /** Battles per pairing when evaluating a contender's fitness. */
22
+ battlesPerPairing?: number;
23
+ /** Cheaper first-pass battles for the adaptive screen; only the top half of a
24
+ * generation's new Teams are then re-evaluated at `battlesPerPairing`. Defaults
25
+ * to half of `battlesPerPairing`. Set equal to it to disable the screen. */
26
+ screenBattlesPerPairing?: number;
27
+ /** Hard ceiling on total Battles across the run; generations stop once hit. */
28
+ battleBudget?: number;
29
+ /** Top Teams carried unchanged into the next generation. */
30
+ elitism?: number;
31
+ weights?: FitnessWeights;
32
+ }
33
+ export type Origin = 'seed' | 'random' | 'mutation' | 'crossover';
34
+ /** How a Team came to be — its provenance in the search. */
35
+ export interface Lineage {
36
+ origin: Origin;
37
+ generation: number;
38
+ /** Parent ids (mutation: one; crossover: two). */
39
+ parents: string[];
40
+ /** The operator that produced it (e.g. `swap-item`, `swap-member`, `crossover`). */
41
+ operator?: string;
42
+ }
43
+ /** The three components of a Team's composite fitness. */
44
+ export interface FitnessParts {
45
+ gauntlet: number;
46
+ peer: number;
47
+ robustness: number;
48
+ }
49
+ /** A Team the Designer discovered. */
50
+ export interface DesignedTeam {
51
+ id: string;
52
+ paste: string;
53
+ /** Overall Strength vs the Gauntlet, in [0, 1]. */
54
+ strength: number;
55
+ /** Composite fitness the search optimised. */
56
+ fitness: number;
57
+ fitnessParts: FitnessParts;
58
+ /** LLM-assigned (or fallback) Archetype label. */
59
+ archetype: string;
60
+ /** True if the model flagged it as a novel Archetype. */
61
+ novel: boolean;
62
+ lineage: Lineage;
63
+ /** Per-Gauntlet-member win-rates (Archetype-tagged). */
64
+ matchups: MatchupResult[];
65
+ }
66
+ export interface DesignInput {
67
+ /** Starting Team(s) as Showdown text; omit to search from scratch. */
68
+ seedTeams?: string | Array<string | Submission>;
69
+ /** Gauntlet version to measure Strength against (gauntlet mode). */
70
+ gauntletVersion?: string;
71
+ budget?: DesignBudget;
72
+ /** Master seed; identical seed + inputs + stub model reproduce the run. */
73
+ seed?: string;
74
+ }
75
+ export interface DesignResult {
76
+ /** Discovered Teams, ranked by composite fitness (fittest first). */
77
+ discovered: DesignedTeam[];
78
+ /** Generations actually run (may be fewer than requested if the cap was hit). */
79
+ generations: number;
80
+ seed: string;
81
+ gauntletVersion: string;
82
+ /** Pilot identity the fitness was measured under (ADR 0002/0004). */
83
+ pilot: string;
84
+ /** The resolved budget the run used. */
85
+ budget: Required<DesignBudget>;
86
+ /** Total Battles run across the whole search. */
87
+ battlesRun: number;
88
+ /** Seed Teams that were illegal and excluded. */
89
+ errors: ValidationError[];
90
+ }
91
+ /**
92
+ * The LLM seam — stub-able so the whole search loop runs with no subscription
93
+ * call. `proposeMutations` returns candidate Team pastes (legality-checked by
94
+ * the caller); `nameArchetype` labels a Team.
95
+ */
96
+ export interface DesignerModel {
97
+ readonly name: string;
98
+ proposeMutations(paste: string, critique?: string): Promise<string[]>;
99
+ nameArchetype(paste: string, note: string): Promise<{
100
+ archetype: string;
101
+ novel: boolean;
102
+ }>;
103
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/designer/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The single public seam. `evaluate` absorbs Team parsing, legality, battle
3
+ * running, and aggregation so callers (the CLI now; the Critic/Designer later)
4
+ * never touch the sim directly. It is deterministic under a seed.
5
+ */
6
+ import { type EvaluateInput, type EvaluationResult } from './types.js';
7
+ export interface EvaluateRuntimeOptions {
8
+ /** Turn cap per Battle before a tiebreak is forced (safety net). */
9
+ maxTurns?: number;
10
+ }
11
+ export declare function evaluate(input: EvaluateInput, runtime?: EvaluateRuntimeOptions): Promise<EvaluationResult>;
@@ -0,0 +1,99 @@
1
+ import { parseAndValidate, toSubmissions } from './team.js';
2
+ import { runMatchups } from './battle/pairing.js';
3
+ import { loadGauntlet, DEFAULT_GAUNTLET_VERSION } from './gauntlet/gauntlet.js';
4
+ import { buildStrengthRow, rankRows, successes } from './ranking.js';
5
+ const DEFAULT_BATTLES = 100;
6
+ const DEFAULT_SEED = 'poke-crucible';
7
+ export async function evaluate(input, runtime = {}) {
8
+ const battlesPerPairing = input.battlesPerPairing ?? DEFAULT_BATTLES;
9
+ const seed = input.seed ?? DEFAULT_SEED;
10
+ const maxTurns = runtime.maxTurns;
11
+ const { legal, errors } = parseAndValidate(toSubmissions(input.teams));
12
+ const ranking = input.opposition.mode === 'gauntlet'
13
+ ? await evaluateGauntlet(legal, battlesPerPairing, seed, input.opposition.gauntletVersion, maxTurns)
14
+ : await evaluateRoundRobin(legal, battlesPerPairing, seed, maxTurns);
15
+ const result = {
16
+ mode: input.opposition.mode,
17
+ seed,
18
+ battlesPerPairing,
19
+ ranking: rankRows(ranking),
20
+ errors,
21
+ };
22
+ if (input.opposition.mode === 'gauntlet') {
23
+ result.gauntletVersion = input.opposition.gauntletVersion ?? DEFAULT_GAUNTLET_VERSION;
24
+ }
25
+ return result;
26
+ }
27
+ /** Absolute mode: each Team's win-rate against every Gauntlet member. */
28
+ async function evaluateGauntlet(teams, battles, master, version, maxTurns) {
29
+ const gauntlet = loadGauntlet(version);
30
+ const specs = [];
31
+ for (let t = 0; t < teams.length; t++) {
32
+ for (let o = 0; o < gauntlet.members.length; o++) {
33
+ specs.push({
34
+ key: `${t}:${o}`,
35
+ aPacked: teams[t].packed,
36
+ bPacked: gauntlet.members[o].packed,
37
+ teamIndex: t,
38
+ opponentIndex: o,
39
+ });
40
+ }
41
+ }
42
+ const records = await runMatchups(specs, battles, master, maxTurns);
43
+ return teams.map((team, t) => {
44
+ const matchups = gauntlet.members.map((member, o) => {
45
+ const rec = records.get(`${t}:${o}`);
46
+ return {
47
+ opponent: member.name,
48
+ archetype: member.archetype,
49
+ wins: rec.wins,
50
+ ties: rec.ties,
51
+ battles: rec.battles,
52
+ winRate: rec.winRate,
53
+ };
54
+ });
55
+ return buildStrengthRow(team.name, matchups);
56
+ });
57
+ }
58
+ /** Relative mode: all-play-all among the submitted Teams. */
59
+ async function evaluateRoundRobin(teams, battles, master, maxTurns) {
60
+ const matchupsByTeam = teams.map(() => []);
61
+ const specs = [];
62
+ for (let i = 0; i < teams.length; i++) {
63
+ for (let j = i + 1; j < teams.length; j++) {
64
+ specs.push({
65
+ key: `${i}:${j}`,
66
+ aPacked: teams[i].packed,
67
+ bPacked: teams[j].packed,
68
+ teamIndex: i,
69
+ opponentIndex: j,
70
+ });
71
+ }
72
+ }
73
+ const records = await runMatchups(specs, battles, master, maxTurns);
74
+ for (let i = 0; i < teams.length; i++) {
75
+ for (let j = i + 1; j < teams.length; j++) {
76
+ const rec = records.get(`${i}:${j}`);
77
+ // B's record against A is the complement of A's (ties split evenly).
78
+ const aSucc = successes(rec);
79
+ const bSucc = rec.battles - aSucc;
80
+ const bWins = rec.battles - rec.wins - rec.ties;
81
+ matchupsByTeam[i].push({
82
+ opponent: teams[j].name,
83
+ wins: rec.wins,
84
+ ties: rec.ties,
85
+ battles: rec.battles,
86
+ winRate: rec.battles > 0 ? aSucc / rec.battles : 0,
87
+ });
88
+ matchupsByTeam[j].push({
89
+ opponent: teams[i].name,
90
+ wins: bWins,
91
+ ties: rec.ties,
92
+ battles: rec.battles,
93
+ winRate: rec.battles > 0 ? bSucc / rec.battles : 0,
94
+ });
95
+ }
96
+ }
97
+ return teams.map((team, i) => buildStrengthRow(team.name, matchupsByTeam[i]));
98
+ }
99
+ //# sourceMappingURL=evaluate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../src/evaluate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { GAUNTLET_VERSION, type GauntletTeamData } from './teams-g1.js';
2
+ export { GAUNTLET_VERSION };
3
+ export declare const DEFAULT_GAUNTLET_VERSION = "g1";
4
+ export interface GauntletMember {
5
+ name: string;
6
+ archetype: string;
7
+ packed: string;
8
+ }
9
+ export interface Gauntlet {
10
+ version: string;
11
+ members: GauntletMember[];
12
+ }
13
+ export declare function knownGauntletVersions(): string[];
14
+ /** The raw Archetype-labeled Team data for a version (paste text) — the Designer
15
+ * draws its gene pool from this. */
16
+ export declare function gauntletTeamData(version?: string): GauntletTeamData[];
17
+ /** Load a Gauntlet by version (defaults to the current one), packed for the sim. */
18
+ export declare function loadGauntlet(version?: string): Gauntlet;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Gauntlet loader — resolves a versioned set of Archetype-labeled Teams to
3
+ * packed form for the runner. The Gauntlet is a fixed, in-repo artifact (ADR
4
+ * 0003); every result records which version it used.
5
+ */
6
+ import { Teams } from '@pkmn/sim';
7
+ import { GAUNTLET_G1, GAUNTLET_VERSION } from './teams-g1.js';
8
+ import { GAUNTLET_G2, GAUNTLET_G2_VERSION } from './teams-g2.js';
9
+ export { GAUNTLET_VERSION };
10
+ export const DEFAULT_GAUNTLET_VERSION = GAUNTLET_VERSION;
11
+ const REGISTRY = {
12
+ [GAUNTLET_VERSION]: GAUNTLET_G1,
13
+ [GAUNTLET_G2_VERSION]: GAUNTLET_G2, // real Smogon ADV OU sample teams (opt-in)
14
+ };
15
+ export function knownGauntletVersions() {
16
+ return Object.keys(REGISTRY);
17
+ }
18
+ /** The raw Archetype-labeled Team data for a version (paste text) — the Designer
19
+ * draws its gene pool from this. */
20
+ export function gauntletTeamData(version = DEFAULT_GAUNTLET_VERSION) {
21
+ const teams = REGISTRY[version];
22
+ if (!teams)
23
+ throw new Error(`Unknown Gauntlet version "${version}".`);
24
+ return teams;
25
+ }
26
+ /** Load a Gauntlet by version (defaults to the current one), packed for the sim. */
27
+ export function loadGauntlet(version = DEFAULT_GAUNTLET_VERSION) {
28
+ const teams = REGISTRY[version];
29
+ if (!teams) {
30
+ throw new Error(`Unknown Gauntlet version "${version}". Known versions: ${knownGauntletVersions().join(', ')}.`);
31
+ }
32
+ const members = teams.map((t) => {
33
+ const team = Teams.import(t.paste);
34
+ if (!team || team.length === 0) {
35
+ throw new Error(`Gauntlet team "${t.name}" failed to parse.`);
36
+ }
37
+ return { name: t.name, archetype: t.archetype, packed: Teams.pack(team) };
38
+ });
39
+ return { version, members };
40
+ }
41
+ //# sourceMappingURL=gauntlet.js.map