@tangle-network/starter-foundry 0.5.3 → 0.5.4

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 (121) hide show
  1. package/README.md +49 -0
  2. package/corpus/ideasai-prompts.json +119 -58
  3. package/dist/cli.js +28 -2
  4. package/dist/cli.js.map +1 -1
  5. package/dist/lib/agent-context.js +34 -22
  6. package/dist/lib/agent-context.js.map +1 -1
  7. package/dist/lib/build-plan.d.ts +18 -0
  8. package/dist/lib/build-plan.js +72 -0
  9. package/dist/lib/build-plan.js.map +1 -1
  10. package/dist/lib/buildout-traces.d.ts +113 -0
  11. package/dist/lib/buildout-traces.js +83 -0
  12. package/dist/lib/buildout-traces.js.map +1 -0
  13. package/dist/lib/capability-inferrer.d.ts +40 -0
  14. package/dist/lib/capability-inferrer.js +82 -0
  15. package/dist/lib/capability-inferrer.js.map +1 -0
  16. package/dist/lib/context-pack.d.ts +6 -1
  17. package/dist/lib/context-pack.js +9 -3
  18. package/dist/lib/context-pack.js.map +1 -1
  19. package/dist/lib/keywords.js +71 -18
  20. package/dist/lib/keywords.js.map +1 -1
  21. package/dist/lib/llm.d.ts +9 -0
  22. package/dist/lib/llm.js +70 -0
  23. package/dist/lib/llm.js.map +1 -0
  24. package/dist/lib/planner/contracts.d.ts +11 -0
  25. package/dist/lib/planner/contracts.js +119 -0
  26. package/dist/lib/planner/contracts.js.map +1 -0
  27. package/dist/lib/planner/detectors.d.ts +14 -0
  28. package/dist/lib/planner/detectors.js +195 -0
  29. package/dist/lib/planner/detectors.js.map +1 -0
  30. package/dist/lib/planner/helpers.d.ts +2 -0
  31. package/dist/lib/planner/helpers.js +135 -0
  32. package/dist/lib/planner/helpers.js.map +1 -0
  33. package/dist/lib/planner/implicit-caps.d.ts +1 -0
  34. package/dist/lib/planner/implicit-caps.js +91 -0
  35. package/dist/lib/planner/implicit-caps.js.map +1 -0
  36. package/dist/lib/planner/projects.d.ts +13 -0
  37. package/dist/lib/planner/projects.js +181 -0
  38. package/dist/lib/planner/projects.js.map +1 -0
  39. package/dist/lib/planner/signals.d.ts +17 -0
  40. package/dist/lib/planner/signals.js +324 -0
  41. package/dist/lib/planner/signals.js.map +1 -0
  42. package/dist/lib/product-brief.d.ts +25 -0
  43. package/dist/lib/product-brief.js +129 -0
  44. package/dist/lib/product-brief.js.map +1 -0
  45. package/dist/lib/prompt-planner.d.ts +5 -1
  46. package/dist/lib/prompt-planner.js +59 -622
  47. package/dist/lib/prompt-planner.js.map +1 -1
  48. package/dist/lib/prompt-rewriter.d.ts +21 -0
  49. package/dist/lib/prompt-rewriter.js +118 -0
  50. package/dist/lib/prompt-rewriter.js.map +1 -0
  51. package/dist/lib/selection.js +170 -36
  52. package/dist/lib/selection.js.map +1 -1
  53. package/dist/lib/telemetry.d.ts +0 -11
  54. package/dist/lib/telemetry.js +3 -3
  55. package/dist/lib/telemetry.js.map +1 -1
  56. package/dist/lib/vb-outcomes.d.ts +61 -0
  57. package/dist/lib/vb-outcomes.js +88 -0
  58. package/dist/lib/vb-outcomes.js.map +1 -0
  59. package/dist/training/variant_b/brief-loader.d.ts +5 -0
  60. package/dist/training/variant_b/brief-loader.js +263 -0
  61. package/dist/training/variant_b/brief-loader.js.map +1 -0
  62. package/dist/training/variant_b/flow.d.ts +56 -0
  63. package/dist/training/variant_b/flow.js +80 -0
  64. package/dist/training/variant_b/flow.js.map +1 -0
  65. package/dist/training/variant_b/generate.d.ts +7 -0
  66. package/dist/training/variant_b/generate.js +70 -0
  67. package/dist/training/variant_b/generate.js.map +1 -0
  68. package/dist/training/variant_b/judge.d.ts +8 -0
  69. package/dist/training/variant_b/judge.js +24 -0
  70. package/dist/training/variant_b/judge.js.map +1 -0
  71. package/dist/training/variant_b/nodes/collect.d.ts +31 -0
  72. package/dist/training/variant_b/nodes/collect.js +122 -0
  73. package/dist/training/variant_b/nodes/collect.js.map +1 -0
  74. package/dist/training/variant_b/nodes/generate.d.ts +22 -0
  75. package/dist/training/variant_b/nodes/generate.js +171 -0
  76. package/dist/training/variant_b/nodes/generate.js.map +1 -0
  77. package/dist/training/variant_b/nodes/judge.d.ts +26 -0
  78. package/dist/training/variant_b/nodes/judge.js +64 -0
  79. package/dist/training/variant_b/nodes/judge.js.map +1 -0
  80. package/dist/training/variant_b/nodes/promote.d.ts +15 -0
  81. package/dist/training/variant_b/nodes/promote.js +64 -0
  82. package/dist/training/variant_b/nodes/promote.js.map +1 -0
  83. package/dist/training/variant_b/nodes/rank.d.ts +12 -0
  84. package/dist/training/variant_b/nodes/rank.js +46 -0
  85. package/dist/training/variant_b/nodes/rank.js.map +1 -0
  86. package/dist/training/variant_b/nodes/train.d.ts +34 -0
  87. package/dist/training/variant_b/nodes/train.js +209 -0
  88. package/dist/training/variant_b/nodes/train.js.map +1 -0
  89. package/dist/training/variant_b/run-flow.d.ts +11 -0
  90. package/dist/training/variant_b/run-flow.js +21 -0
  91. package/dist/training/variant_b/run-flow.js.map +1 -0
  92. package/dist/training/variant_b/train.d.ts +15 -0
  93. package/dist/training/variant_b/train.js +37 -0
  94. package/dist/training/variant_b/train.js.map +1 -0
  95. package/dist/types.d.ts +16 -0
  96. package/package.json +6 -2
  97. package/registry/families/browser-extension-ts/files/package.json +4 -1
  98. package/registry/families/cli-ts/files/package.json +5 -0
  99. package/registry/families/electron-desktop-ts/files/package.json +3 -1
  100. package/registry/families/expo-react-native-ts/files/package.json +4 -0
  101. package/registry/families/fhenix-contracts/files/package.json +1 -1
  102. package/registry/families/fhevm-contracts/files/package.json +1 -1
  103. package/registry/families/fullstack-ts/files/package.json +3 -1
  104. package/registry/families/hardhat-contracts/files/package.json +3 -1
  105. package/registry/families/nextjs-ts/files/package.json +3 -1
  106. package/registry/families/react-vite-ts/files/package.json +11 -1
  107. package/registry/families/react-vite-ts/files/src/components/ui/badge.tsx +9 -0
  108. package/registry/families/react-vite-ts/files/src/components/ui/button.tsx +18 -0
  109. package/registry/families/react-vite-ts/files/src/components/ui/card.tsx +22 -0
  110. package/registry/families/react-vite-ts/manifest.json +14 -2
  111. package/registry/families/remix-ts/files/package.json +9 -1
  112. package/registry/families/sveltekit-ts/files/package.json +9 -1
  113. package/registry/families/tauri-desktop/files/package.json +3 -1
  114. package/registry/families/vue-ts/files/package.json +9 -1
  115. package/registry/layers/framework/expo-react-native-ts/files/tsconfig.json +2 -1
  116. package/registry/layers/framework/forge-foundation/files/foundry.toml +22 -1
  117. package/registry/layers/framework/fullstack-node-ts/files/personalize.json +5 -5
  118. package/registry/layers/framework/tangle-blueprint/files/TOOLCHAIN.md +16 -0
  119. package/registry/layers/framework/tangle-blueprint/files/rust-toolchain.toml +1 -1
  120. package/registry/layers/framework/tangle-blueprint/manifest.json +4 -0
  121. package/registry/package-to-capability.json +57 -0
@@ -0,0 +1,64 @@
1
+ // promote node: takes top ranked candidates that passed the judge and writes
2
+ // them as minimal capability manifests under registry/layers/capability/<id>/.
3
+ // Stops at top-K promotable-only. Idempotent — won't overwrite existing
4
+ // manifests. The registry is the system of record.
5
+ //
6
+ // Swap strategy: replace the manifest writer with a PR-opener or a dry-run
7
+ // committer without changing the node contract.
8
+ import { mkdir, writeFile, access } from 'node:fs/promises';
9
+ import path from 'node:path';
10
+ async function exists(p) {
11
+ try {
12
+ await access(p);
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ export async function promoteNode(input) {
20
+ const promoted = [];
21
+ const skipped = [];
22
+ const max = input.maxPromotions ?? 8;
23
+ const candidates = input.ranked.filter((c) => c.score.promotable).slice(0, max);
24
+ for (const c of candidates) {
25
+ const dir = path.join(input.registryRoot, 'layers', 'capability', c.candidate.id);
26
+ if (await exists(dir)) {
27
+ skipped.push({ id: c.candidate.id, reason: 'already-exists' });
28
+ continue;
29
+ }
30
+ const manifest = {
31
+ id: c.candidate.id,
32
+ description: c.candidate.description,
33
+ appliesTo: [c.candidate.family],
34
+ defaults: {},
35
+ files: [],
36
+ contextHints: {
37
+ extensionPoints: [],
38
+ notes: `Promoted by variant_b flow (rank=${c.rank}, composite=${c.score.composite.toFixed(3)}).`,
39
+ },
40
+ keywords: c.candidate.promptKeywords,
41
+ buildHints: {
42
+ capabilityBundle: c.candidate.capabilities,
43
+ rationale: c.candidate.rationale,
44
+ },
45
+ // variant_b metadata so a future reviewer can filter promoted
46
+ // archetypes and audit the loop's output.
47
+ provenance: {
48
+ generatedBy: 'variant_b',
49
+ source: c.candidate.source,
50
+ scores: c.score,
51
+ promotedAt: new Date().toISOString(),
52
+ },
53
+ };
54
+ if (input.dryRun) {
55
+ promoted.push(c.candidate.id);
56
+ continue;
57
+ }
58
+ await mkdir(dir, { recursive: true });
59
+ await writeFile(path.join(dir, 'manifest.json'), JSON.stringify(manifest, null, 2));
60
+ promoted.push(c.candidate.id);
61
+ }
62
+ return { promoted, skipped };
63
+ }
64
+ //# sourceMappingURL=promote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promote.js","sourceRoot":"","sources":["../../../../src/training/variant_b/nodes/promote.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ScoredCandidate } from './judge.js';
2
+ export interface RankedCandidate extends ScoredCandidate {
3
+ rank: number;
4
+ paretoFrontier: boolean;
5
+ }
6
+ export interface RankInput {
7
+ scored: ScoredCandidate[];
8
+ }
9
+ export interface RankOutput {
10
+ ranked: RankedCandidate[];
11
+ }
12
+ export declare function rankNode(input: RankInput): Promise<RankOutput>;
@@ -0,0 +1,46 @@
1
+ // rank node: Pareto-rank scored candidates across (utility, specificity,
2
+ // novelty, rubric). Dominated candidates are dropped. Non-dominated frontier
3
+ // is ordered by composite score. This is a swap point — could be replaced
4
+ // with Borda count, ELO, or a learned ranker without touching the nodes
5
+ // upstream or downstream.
6
+ function dominates(a, b) {
7
+ const dims = [
8
+ [a.score.utility, b.score.utility],
9
+ [a.score.specificity, b.score.specificity],
10
+ [a.score.novelty, b.score.novelty],
11
+ [a.score.rubric, b.score.rubric],
12
+ ];
13
+ let strictlyBetter = false;
14
+ for (const [x, y] of dims) {
15
+ if (x < y)
16
+ return false;
17
+ if (x > y)
18
+ strictlyBetter = true;
19
+ }
20
+ return strictlyBetter;
21
+ }
22
+ export async function rankNode(input) {
23
+ const ranked = [];
24
+ for (const c of input.scored) {
25
+ let isDominated = false;
26
+ for (const other of input.scored) {
27
+ if (other === c)
28
+ continue;
29
+ if (dominates(other, c)) {
30
+ isDominated = true;
31
+ break;
32
+ }
33
+ }
34
+ ranked.push({ ...c, rank: 0, paretoFrontier: !isDominated });
35
+ }
36
+ ranked.sort((a, b) => {
37
+ if (a.paretoFrontier !== b.paretoFrontier)
38
+ return a.paretoFrontier ? -1 : 1;
39
+ return b.score.composite - a.score.composite;
40
+ });
41
+ ranked.forEach((c, i) => {
42
+ c.rank = i + 1;
43
+ });
44
+ return { ranked };
45
+ }
46
+ //# sourceMappingURL=rank.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rank.js","sourceRoot":"","sources":["../../../../src/training/variant_b/nodes/rank.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,6EAA6E;AAC7E,0EAA0E;AAC1E,wEAAwE;AACxE,0BAA0B;AAiB1B,SAAS,SAAS,CAAC,CAAkB,EAAE,CAAkB;IACvD,MAAM,IAAI,GAA4B;QACpC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QAClC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC;QAC1C,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QAClC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;KACjC,CAAA;IACD,IAAI,cAAc,GAAG,KAAK,CAAA;IAC1B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAA;QACvB,IAAI,CAAC,GAAG,CAAC;YAAE,cAAc,GAAG,IAAI,CAAA;IAClC,CAAC;IACD,OAAO,cAAc,CAAA;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAgB;IAC7C,MAAM,MAAM,GAAsB,EAAE,CAAA;IACpC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,WAAW,GAAG,KAAK,CAAA;QACvB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,KAAK,KAAK,CAAC;gBAAE,SAAQ;YACzB,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;gBACxB,WAAW,GAAG,IAAI,CAAA;gBAClB,MAAK;YACP,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;IAC9D,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACnB,IAAI,CAAC,CAAC,cAAc,KAAK,CAAC,CAAC,cAAc;YAAE,OAAO,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3E,OAAO,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAA;IAC9C,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtB,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;IAChB,CAAC,CAAC,CAAA;IACF,OAAO,EAAE,MAAM,EAAE,CAAA;AACnB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { AxAIService } from '@ax-llm/ax';
2
+ import type { Trace } from './collect.js';
3
+ export interface TrainInput {
4
+ traces: Trace[];
5
+ outPath: string;
6
+ llm: AxAIService;
7
+ maxRounds?: number;
8
+ auto?: 'light' | 'medium' | 'heavy';
9
+ }
10
+ export interface SerializedOptimizedProgram {
11
+ optimizerType: string;
12
+ bestScore: number;
13
+ instruction?: string;
14
+ instructionMap?: Record<string, string>;
15
+ demos?: unknown[];
16
+ modelConfig?: Record<string, unknown>;
17
+ optimizationTime: number;
18
+ totalRounds: number;
19
+ converged: boolean;
20
+ scoreHistory?: number[];
21
+ artifactFormatVersion?: number;
22
+ signature: string;
23
+ promptShape: 'brief';
24
+ trainedAt: string;
25
+ trainingTraceCount: number;
26
+ knownFamilies: string[];
27
+ knownCapabilities: string[];
28
+ }
29
+ export interface TrainOutput {
30
+ optimizedProgram: SerializedOptimizedProgram;
31
+ outPath: string;
32
+ }
33
+ export declare function trainNode(input: TrainInput): Promise<TrainOutput>;
34
+ export declare function buildCorpusMinedInstruction(trainables: Trace[], knownCapabilities: string[]): string;
@@ -0,0 +1,209 @@
1
+ // train node: takes traces, runs AxMiPRO over the brief signature to find an
2
+ // instruction that biases the brief agent toward producing canonicalPrompts
3
+ // that route correctly through the deterministic planner. The optimized
4
+ // artifact is serialized to JSON at outPath as an AxOptimizedProgram.
5
+ //
6
+ // Swap strategy: replace `AxMiPRO` with `AxBootstrapFewShot` or `AxGEPA` by
7
+ // changing only this file. The TrainOutput contract stays fixed.
8
+ import { writeFile, mkdir } from 'node:fs/promises';
9
+ import path from 'node:path';
10
+ import { ax, AxMiPRO } from '@ax-llm/ax';
11
+ import { loadRegistry } from '../../../lib/registry.js';
12
+ import { planPrompt } from '../../../lib/prompt-planner.js';
13
+ const BRIEF_SIGNATURE = '"Turn a user product prompt into a structured product brief that drives a deterministic scaffold pipeline downstream. The canonicalPrompt must be a keyword-rich expansion that names concrete technologies drawn from knownFamilies (e.g. nextjs-ts, fullstack-ts, agent-service-ts, go-api, python-api, forge-contracts, solana-program) and concrete UI/infra capabilities drawn from knownCapabilities (e.g. capability:ai-chat-ui, capability:layout-dashboard, capability:saas-billing). It MUST be longer and more specific than the user prompt. Preserve the user intent exactly. Each list field should have 3-8 items." ' +
14
+ 'userPrompt:string, knownFamilies:string[], knownCapabilities:string[] -> ' +
15
+ 'canonicalPrompt:string, vision:string, taskChecklist:string[], milestones:string[], testingPlan:string[], e2ePlan:string[], securityConcerns:string[], openQuestions:string[], confidence:number';
16
+ function jaccard(a, b) {
17
+ const A = new Set(a);
18
+ const B = new Set(b);
19
+ if (A.size === 0 && B.size === 0)
20
+ return 1;
21
+ let inter = 0;
22
+ for (const x of A)
23
+ if (B.has(x))
24
+ inter++;
25
+ const union = A.size + B.size - inter;
26
+ return union === 0 ? 1 : inter / union;
27
+ }
28
+ async function buildKnownLists() {
29
+ const registry = await loadRegistry();
30
+ const knownFamilies = [...registry.families.keys()];
31
+ const knownCapabilities = [];
32
+ for (const [key] of registry.layers) {
33
+ if (key.startsWith('capability:'))
34
+ knownCapabilities.push(key);
35
+ }
36
+ return { knownFamilies, knownCapabilities };
37
+ }
38
+ // Build a metric: for each predicted canonicalPrompt, re-route through the
39
+ // deterministic planner and measure capability-jaccard vs the expected
40
+ // capabilities from the training example. This is exactly what downstream
41
+ // eval will measure, so we optimize the metric that matters.
42
+ function makeMetric(expectedByPrompt) {
43
+ return async ({ prediction, example }) => {
44
+ const pred = prediction;
45
+ const canonical = (pred.canonicalPrompt ?? '').trim();
46
+ if (!canonical)
47
+ return 0;
48
+ const ex = example;
49
+ const userPrompt = typeof ex['userPrompt'] === 'string' ? ex['userPrompt'] : '';
50
+ const expected = expectedByPrompt.get(userPrompt) ?? [];
51
+ if (expected.length === 0) {
52
+ // no expected caps — reward length + diversity as a weak proxy
53
+ return canonical.length > userPrompt.length ? 0.5 : 0;
54
+ }
55
+ let plan = null;
56
+ try {
57
+ plan = await planPrompt({ prompt: canonical });
58
+ }
59
+ catch {
60
+ return 0;
61
+ }
62
+ const p = plan;
63
+ const actual = p?.kind === 'starter'
64
+ ? p.spec?.layers ?? []
65
+ : (p?.spec?.projects ?? []).flatMap((proj) => proj.layers ?? []);
66
+ return jaccard(actual, expected);
67
+ };
68
+ }
69
+ export async function trainNode(input) {
70
+ const { knownFamilies, knownCapabilities } = await buildKnownLists();
71
+ // Only train on ideasai traces that have expected capabilities. held-out is
72
+ // measurement, not training. We also skip traces where capabilityHit was
73
+ // already 1.0 (nothing to learn).
74
+ const trainables = input.traces.filter((t) => t.corpus === 'ideasai' && t.expectedCapabilities.length > 0 && t.capabilityHit < 1.0);
75
+ const examples = trainables.slice(0, 30).map((t) => ({
76
+ userPrompt: t.prompt,
77
+ knownFamilies,
78
+ knownCapabilities,
79
+ }));
80
+ const expectedByPrompt = new Map();
81
+ for (const t of trainables)
82
+ expectedByPrompt.set(t.prompt, t.expectedCapabilities);
83
+ const briefProgram = ax(BRIEF_SIGNATURE);
84
+ const metric = makeMetric(expectedByPrompt);
85
+ let bestScore = 0;
86
+ let instruction;
87
+ let instructionMap;
88
+ let demos;
89
+ let modelConfig;
90
+ let optimizerType = 'variant_b.fallback';
91
+ let optimizationTime = 0;
92
+ let totalRounds = 0;
93
+ let converged = false;
94
+ let scoreHistory;
95
+ if (examples.length >= 3) {
96
+ try {
97
+ const optimizer = new AxMiPRO({
98
+ studentAI: input.llm,
99
+ numTrials: 3,
100
+ numCandidates: 3,
101
+ minibatch: true,
102
+ minibatchSize: Math.min(6, examples.length),
103
+ verbose: false,
104
+ seed: 42,
105
+ });
106
+ optimizer.configureAuto(input.auto ?? 'light');
107
+ const t0 = Date.now();
108
+ const result = await optimizer.compile(briefProgram, examples, metric, {
109
+ maxMetricCalls: Math.max(examples.length * 2, 12),
110
+ auto: input.auto ?? 'light',
111
+ verbose: false,
112
+ });
113
+ optimizationTime = Date.now() - t0;
114
+ const opt = result.optimizedProgram;
115
+ if (opt) {
116
+ bestScore = opt.bestScore;
117
+ instruction = opt.instruction;
118
+ instructionMap = opt.instructionMap;
119
+ demos = opt.demos;
120
+ modelConfig = opt.modelConfig;
121
+ optimizerType = opt.optimizerType;
122
+ totalRounds = opt.totalRounds;
123
+ converged = opt.converged;
124
+ scoreHistory = opt.scoreHistory;
125
+ }
126
+ else if (result.bestScore !== undefined) {
127
+ bestScore = result.bestScore;
128
+ }
129
+ }
130
+ catch (err) {
131
+ // Rate-limits, provider blips — fall back to the corpus-mined instruction
132
+ // so the variant still produces an artifact.
133
+ // eslint-disable-next-line no-console
134
+ console.warn('[variant_b/train] AxMiPRO failed, using fallback:', err instanceof Error ? err.message : err);
135
+ }
136
+ }
137
+ // Always attach a corpus-mined instruction as a floor. This is the part that
138
+ // reliably moves capHit because it surfaces the exact vocabulary the
139
+ // deterministic planner keys off. Real optimization can only improve on it.
140
+ if (!instruction) {
141
+ instruction = buildCorpusMinedInstruction(trainables, knownCapabilities);
142
+ optimizerType = optimizerType === 'variant_b.fallback' ? 'variant_b.corpus-mined' : optimizerType;
143
+ }
144
+ const artifact = {
145
+ optimizerType,
146
+ bestScore,
147
+ instruction,
148
+ instructionMap,
149
+ demos: Array.isArray(demos) ? demos.slice(0, 8) : demos,
150
+ modelConfig,
151
+ optimizationTime,
152
+ totalRounds,
153
+ converged,
154
+ scoreHistory,
155
+ artifactFormatVersion: 1,
156
+ signature: BRIEF_SIGNATURE,
157
+ promptShape: 'brief',
158
+ trainedAt: new Date().toISOString(),
159
+ trainingTraceCount: trainables.length,
160
+ knownFamilies,
161
+ knownCapabilities,
162
+ };
163
+ await mkdir(path.dirname(input.outPath), { recursive: true });
164
+ await writeFile(input.outPath, JSON.stringify(artifact, null, 2));
165
+ return { optimizedProgram: artifact, outPath: input.outPath };
166
+ }
167
+ // Mine the training traces to learn the high-signal vocabulary. For each
168
+ // expected capability that was missed, collect the keywords from the original
169
+ // prompt that co-occur with it. Build those into a tight instruction that
170
+ // tells the brief agent to SURFACE the capability name explicitly when it
171
+ // sees those keywords. This is the deterministic floor the optimizer must
172
+ // beat. In practice it already lifts ideasaiCapHit materially because the
173
+ // brief's canonicalPrompt will contain the exact layer IDs the planner scans.
174
+ export function buildCorpusMinedInstruction(trainables, knownCapabilities) {
175
+ const capToKeywords = new Map();
176
+ for (const t of trainables) {
177
+ const words = t.prompt
178
+ .toLowerCase()
179
+ .replace(/[^a-z0-9\s-]/g, ' ')
180
+ .split(/\s+/)
181
+ .filter((w) => w.length >= 4);
182
+ for (const cap of t.expectedCapabilities) {
183
+ if (t.actualCapabilities.includes(cap))
184
+ continue; // already hit, no lesson
185
+ if (!capToKeywords.has(cap))
186
+ capToKeywords.set(cap, new Map());
187
+ const m = capToKeywords.get(cap);
188
+ for (const w of words)
189
+ m.set(w, (m.get(w) ?? 0) + 1);
190
+ }
191
+ }
192
+ const lines = [];
193
+ lines.push('ALWAYS name the capability IDs explicitly in canonicalPrompt when the user prompt matches.');
194
+ lines.push('For ambiguous AI-saas prompts, prefer fullstack-ts or nextjs-ts family.');
195
+ lines.push('Route rules (ordered):');
196
+ const entries = [...capToKeywords.entries()]
197
+ .map(([cap, m]) => ({ cap, top: [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, 6).map(([w]) => w) }))
198
+ .filter((e) => knownCapabilities.includes(e.cap))
199
+ .slice(0, 12);
200
+ for (const { cap, top } of entries) {
201
+ lines.push(`- If prompt mentions any of [${top.join(', ')}] include "${cap}" in canonicalPrompt.`);
202
+ }
203
+ lines.push('ALWAYS include capability:tailwind for any UI that renders pages.');
204
+ lines.push('ALWAYS include capability:layout-dashboard when prompt describes analytics, tracking, monitoring, or multiple views.');
205
+ lines.push('ALWAYS include capability:layout-chat when prompt describes messaging, conversation, or companion UX.');
206
+ lines.push('ALWAYS include capability:ai-chat-ui when the product is AI-driven or talks to the user.');
207
+ return lines.join('\n');
208
+ }
209
+ //# sourceMappingURL=train.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"train.js","sourceRoot":"","sources":["../../../../src/training/variant_b/nodes/train.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,4EAA4E;AAC5E,wEAAwE;AACxE,sEAAsE;AACtE,EAAE;AACF,4EAA4E;AAC5E,iEAAiE;AAEjE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAY,MAAM,kBAAkB,CAAA;AAC7D,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAqC3D,MAAM,eAAe,GACnB,qmBAAqmB;IACrmB,2EAA2E;IAC3E,kMAAkM,CAAA;AAepM,SAAS,OAAO,CAAC,CAAW,EAAE,CAAW;IACvC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;IACpB,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;IACpB,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IAC1C,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,CAAC,IAAI,CAAC;QAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,KAAK,EAAE,CAAA;IACxC,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,GAAG,KAAK,CAAA;IACrC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAA;AACxC,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAA;IACrC,MAAM,aAAa,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IACnD,MAAM,iBAAiB,GAAa,EAAE,CAAA;IACtC,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC;YAAE,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChE,CAAC;IACD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,CAAA;AAC7C,CAAC;AAED,2EAA2E;AAC3E,uEAAuE;AACvE,0EAA0E;AAC1E,6DAA6D;AAC7D,SAAS,UAAU,CAAC,gBAAuC;IACzD,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,UAA6B,CAAA;QAC1C,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QACrD,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,CAAA;QACxB,MAAM,EAAE,GAAG,OAAkC,CAAA;QAC7C,MAAM,UAAU,GAAG,OAAO,EAAE,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,EAAE,CAAC,YAAY,CAAY,CAAC,CAAC,CAAC,EAAE,CAAA;QAC3F,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAA;QACvD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,+DAA+D;YAC/D,OAAO,SAAS,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACvD,CAAC;QACD,IAAI,IAAI,GAAY,IAAI,CAAA;QACxB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAA;QACV,CAAC;QACD,MAAM,CAAC,GAAG,IAAuG,CAAA;QACjH,MAAM,MAAM,GAAG,CAAC,EAAE,IAAI,KAAK,SAAS;YAClC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE;YACtB,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAA;QAClE,OAAO,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAClC,CAAC,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAiB;IAC/C,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,GAAG,MAAM,eAAe,EAAE,CAAA;IAEpE,4EAA4E;IAC5E,yEAAyE;IACzE,kCAAkC;IAClC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,aAAa,GAAG,GAAG,CAC5F,CAAA;IAED,MAAM,QAAQ,GAAwC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxF,UAAU,EAAE,CAAC,CAAC,MAAM;QACpB,aAAa;QACb,iBAAiB;KAClB,CAAC,CAAC,CAAA;IAEH,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAoB,CAAA;IACpD,KAAK,MAAM,CAAC,IAAI,UAAU;QAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAA;IAElF,MAAM,YAAY,GAAG,EAAE,CAAC,eAAe,CAAC,CAAA;IACxC,MAAM,MAAM,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAE3C,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,IAAI,WAA+B,CAAA;IACnC,IAAI,cAAkD,CAAA;IACtD,IAAI,KAA4B,CAAA;IAChC,IAAI,WAAgD,CAAA;IACpD,IAAI,aAAa,GAAG,oBAAoB,CAAA;IACxC,IAAI,gBAAgB,GAAG,CAAC,CAAA;IACxB,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,IAAI,SAAS,GAAG,KAAK,CAAA;IACrB,IAAI,YAAkC,CAAA;IAEtC,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,OAAO,CAAC;gBAC5B,SAAS,EAAE,KAAK,CAAC,GAAG;gBACpB,SAAS,EAAE,CAAC;gBACZ,aAAa,EAAE,CAAC;gBAChB,SAAS,EAAE,IAAI;gBACf,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC;gBAC3C,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,EAAE;aACT,CAAC,CAAA;YACF,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,CAAA;YAE9C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YACrB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE;gBACrE,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC;gBACjD,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,OAAO;gBAC3B,OAAO,EAAE,KAAK;aACf,CAAC,CAAA;YACF,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAA;YAElC,MAAM,GAAG,GAAG,MAAM,CAAC,gBAAmE,CAAA;YACtF,IAAI,GAAG,EAAE,CAAC;gBACR,SAAS,GAAG,GAAG,CAAC,SAAS,CAAA;gBACzB,WAAW,GAAG,GAAG,CAAC,WAAW,CAAA;gBAC7B,cAAc,GAAG,GAAG,CAAC,cAAc,CAAA;gBACnC,KAAK,GAAG,GAAG,CAAC,KAA8B,CAAA;gBAC1C,WAAW,GAAG,GAAG,CAAC,WAAW,CAAA;gBAC7B,aAAa,GAAG,GAAG,CAAC,aAAa,CAAA;gBACjC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAA;gBAC7B,SAAS,GAAG,GAAG,CAAC,SAAS,CAAA;gBACzB,YAAY,GAAG,GAAG,CAAC,YAAY,CAAA;YACjC,CAAC;iBAAM,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC1C,SAAS,GAAG,MAAM,CAAC,SAAS,CAAA;YAC9B,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,0EAA0E;YAC1E,6CAA6C;YAC7C,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,mDAAmD,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC7G,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,qEAAqE;IACrE,4EAA4E;IAC5E,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,GAAG,2BAA2B,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA;QACxE,aAAa,GAAG,aAAa,KAAK,oBAAoB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,aAAa,CAAA;IACnG,CAAC;IAED,MAAM,QAAQ,GAA+B;QAC3C,aAAa;QACb,SAAS;QACT,WAAW;QACX,cAAc;QACd,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK;QACvD,WAAW;QACX,gBAAgB;QAChB,WAAW;QACX,SAAS;QACT,YAAY;QACZ,qBAAqB,EAAE,CAAC;QACxB,SAAS,EAAE,eAAe;QAC1B,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,kBAAkB,EAAE,UAAU,CAAC,MAAM;QACrC,aAAa;QACb,iBAAiB;KAClB,CAAA;IAED,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7D,MAAM,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAEjE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;AAC/D,CAAC;AAED,yEAAyE;AACzE,8EAA8E;AAC9E,0EAA0E;AAC1E,0EAA0E;AAC1E,0EAA0E;AAC1E,0EAA0E;AAC1E,8EAA8E;AAC9E,MAAM,UAAU,2BAA2B,CAAC,UAAmB,EAAE,iBAA2B;IAC1F,MAAM,aAAa,GAAG,IAAI,GAAG,EAA+B,CAAA;IAC5D,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM;aACnB,WAAW,EAAE;aACb,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC;aAC7B,KAAK,CAAC,KAAK,CAAC;aACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAA;QAC/B,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC;YACzC,IAAI,CAAC,CAAC,kBAAkB,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,SAAQ,CAAC,yBAAyB;YAC1E,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;YAC9D,MAAM,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAE,CAAA;YACjC,KAAK,MAAM,CAAC,IAAI,KAAK;gBAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACtD,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,CAAC,IAAI,CAAC,4FAA4F,CAAC,CAAA;IACxG,KAAK,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAA;IACrF,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;IACpC,MAAM,OAAO,GAAG,CAAC,GAAG,aAAa,CAAC,OAAO,EAAE,CAAC;SACzC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC3G,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SAChD,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACf,KAAK,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,OAAO,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,gCAAgC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,uBAAuB,CAAC,CAAA;IACpG,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAA;IAC/E,KAAK,CAAC,IAAI,CAAC,sHAAsH,CAAC,CAAA;IAClI,KAAK,CAAC,IAAI,CAAC,uGAAuG,CAAC,CAAA;IACnH,KAAK,CAAC,IAAI,CAAC,0FAA0F,CAAC,CAAA;IACtG,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { FlowOutput } from './flow.js';
2
+ export interface RunFullFlowInput {
3
+ corpusPath?: string;
4
+ registryRoot?: string;
5
+ tracesDir?: string;
6
+ optimizedPath?: string;
7
+ ideasPath?: string;
8
+ judgePath?: string;
9
+ iterations?: number;
10
+ }
11
+ export declare function runFullFlow(input?: RunFullFlowInput): Promise<FlowOutput>;
@@ -0,0 +1,21 @@
1
+ // runFullFlow: runs the entire AxFlow pipeline end-to-end. Used by the
2
+ // variant_b-flow.mjs script and by the integration test. This is the
3
+ // one-shot "do everything" entrypoint.
4
+ import { buildVariantBFlow } from './flow.js';
5
+ import { createLLM } from '../../lib/llm.js';
6
+ export async function runFullFlow(input = {}) {
7
+ const llm = createLLM();
8
+ const flowInstance = buildVariantBFlow();
9
+ const result = await flowInstance.forward(llm, {
10
+ corpusPath: input.corpusPath ?? 'corpus/ideasai-prompts.json',
11
+ registryRoot: input.registryRoot ?? 'registry',
12
+ tracesDir: input.tracesDir ?? '.evolve/traces',
13
+ optimizedPath: input.optimizedPath ?? '.evolve/optimized/brief-variant_b.json',
14
+ ideasPath: input.ideasPath ?? '.evolve/ideas/variant_b.json',
15
+ judgePath: input.judgePath ?? '.evolve/judge/variant_b.jsonl',
16
+ iterations: input.iterations ?? 1,
17
+ llm,
18
+ });
19
+ return result;
20
+ }
21
+ //# sourceMappingURL=run-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-flow.js","sourceRoot":"","sources":["../../../src/training/variant_b/run-flow.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,qEAAqE;AACrE,uCAAuC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAa5C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAA0B,EAAE;IAC5D,MAAM,GAAG,GAAG,SAAS,EAAE,CAAA;IACvB,MAAM,YAAY,GAAG,iBAAiB,EAAE,CAAA;IACxC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE;QAC7C,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,6BAA6B;QAC7D,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,UAAU;QAC9C,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,gBAAgB;QAC9C,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,wCAAwC;QAC9E,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,8BAA8B;QAC5D,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,+BAA+B;QAC7D,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,CAAC;QACjC,GAAG;KACJ,CAAC,CAAA;IACF,OAAO,MAAoB,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { SerializedOptimizedProgram } from './nodes/train.js';
2
+ export interface RunTrainingLoopInput {
3
+ corpusPath: string;
4
+ outPath: string;
5
+ tracesDir?: string;
6
+ auto?: 'light' | 'medium' | 'heavy';
7
+ limit?: number;
8
+ }
9
+ export interface RunTrainingLoopResult {
10
+ optimizedProgram: SerializedOptimizedProgram;
11
+ outPath: string;
12
+ traceCount: number;
13
+ tracesFile: string;
14
+ }
15
+ export declare function runTrainingLoop(input: RunTrainingLoopInput): Promise<RunTrainingLoopResult>;
@@ -0,0 +1,37 @@
1
+ // Public entrypoint: runTrainingLoop({ corpusPath, outPath })
2
+ //
3
+ // Contract (see scripts/multi-pursue-eval.mjs):
4
+ // - Read corpusPath (defaults to corpus/ideasai-prompts.json)
5
+ // - Synthesize traces via the collect node
6
+ // - Run the train node, which compiles AxMiPRO on the brief signature
7
+ // - Write serialized AxOptimizedProgram JSON to outPath
8
+ //
9
+ // This wraps exactly the first two nodes of the flow. The full flow lives in
10
+ // run-flow.ts. Training is separated so the eval harness can run it without
11
+ // paying for generate/judge/rank/promote.
12
+ import { createLLM } from '../../lib/llm.js';
13
+ import { collectNode } from './nodes/collect.js';
14
+ import { trainNode } from './nodes/train.js';
15
+ export async function runTrainingLoop(input) {
16
+ const tracesDir = input.tracesDir ?? '.evolve/traces';
17
+ const collect = await collectNode({
18
+ corpusPath: input.corpusPath,
19
+ tracesDir,
20
+ limit: input.limit,
21
+ includeHeldOut: true,
22
+ });
23
+ const llm = createLLM();
24
+ const train = await trainNode({
25
+ traces: collect.traces,
26
+ outPath: input.outPath,
27
+ llm,
28
+ auto: input.auto ?? 'light',
29
+ });
30
+ return {
31
+ optimizedProgram: train.optimizedProgram,
32
+ outPath: train.outPath,
33
+ traceCount: collect.traces.length,
34
+ tracesFile: collect.tracesFile,
35
+ };
36
+ }
37
+ //# sourceMappingURL=train.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"train.js","sourceRoot":"","sources":["../../../src/training/variant_b/train.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,gDAAgD;AAChD,gEAAgE;AAChE,6CAA6C;AAC7C,wEAAwE;AACxE,0DAA0D;AAC1D,EAAE;AACF,6EAA6E;AAC7E,4EAA4E;AAC5E,0CAA0C;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAkB5C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAA2B;IAC/D,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,gBAAgB,CAAA;IACrD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC;QAChC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,SAAS;QACT,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,cAAc,EAAE,IAAI;KACrB,CAAC,CAAA;IACF,MAAM,GAAG,GAAG,SAAS,EAAE,CAAA;IACvB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC;QAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG;QACH,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,OAAO;KAC5B,CAAC,CAAA;IACF,OAAO;QACL,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM;QACjC,UAAU,EAAE,OAAO,CAAC,UAAU;KAC/B,CAAA;AACH,CAAC"}
package/dist/types.d.ts CHANGED
@@ -132,6 +132,18 @@ export interface BuildPlan {
132
132
  designDirective: string | null;
133
133
  /** shadcn preset code for `pnpm dlx shadcn@latest init --preset <code>` */
134
134
  presetCode?: string | null;
135
+ /** Vision statement (2-4 sentences) — only populated when a product brief was generated. */
136
+ vision?: string;
137
+ /** Ordered major phases with success criteria. Populated from product brief. */
138
+ milestones?: string[];
139
+ /** Unit/integration test plan items. Populated from product brief. */
140
+ testingPlan?: string[];
141
+ /** End-to-end user-journey coverage items. Populated from product brief. */
142
+ e2ePlan?: string[];
143
+ /** Red-team / audit surface concerns. Populated from product brief. */
144
+ securityConcerns?: string[];
145
+ /** Things the user should clarify. Populated from product brief. */
146
+ openQuestions?: string[];
135
147
  }
136
148
  export interface BuildHints {
137
149
  pages?: string[];
@@ -205,12 +217,16 @@ export interface StarterPromptPlan {
205
217
  confidence: Confidence;
206
218
  reasons: string[];
207
219
  spec: ComposeSpec;
220
+ /** Opaque product brief object attached when planPrompt was called with brief: true. */
221
+ brief?: unknown;
208
222
  }
209
223
  export interface WorkspacePromptPlan {
210
224
  kind: 'workspace';
211
225
  confidence: Confidence;
212
226
  reasons: string[];
213
227
  spec: WorkspaceSpec;
228
+ /** Opaque product brief object attached when planPrompt was called with brief: true. */
229
+ brief?: unknown;
214
230
  }
215
231
  export type PromptPlan = StarterPromptPlan | WorkspacePromptPlan;
216
232
  export interface ComposeComponents {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/starter-foundry",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "Deterministic project scaffold engine for AI coding platforms",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -38,7 +38,7 @@
38
38
  "scripts": {
39
39
  "build": "tsc",
40
40
  "prepublishOnly": "tsc",
41
- "test": "tsc && tsc -p tsconfig.test.json && node --test dist-tests/*.test.js",
41
+ "test": "tsc && tsc -p tsconfig.test.json && node --test --test-concurrency=1 dist-tests/*.test.js",
42
42
  "catalog": "node dist/cli.js catalog",
43
43
  "select": "node dist/cli.js select",
44
44
  "compose": "node dist/cli.js compose",
@@ -65,6 +65,10 @@
65
65
  "typescript": "^5.7.0"
66
66
  },
67
67
  "dependencies": {
68
+ "@ax-llm/ax": "^19.0.45",
68
69
  "@huggingface/transformers": "^4.0.0"
70
+ },
71
+ "optionalDependencies": {
72
+ "@opentelemetry/api": "^1.9.0"
69
73
  }
70
74
  }
@@ -7,6 +7,9 @@
7
7
  "validate": "node validate-types.mjs"
8
8
  },
9
9
  "devDependencies": {
10
- "vite": "^6.2.0"
10
+ "vite": "^6.2.0",
11
+ "typescript": "^5.7.0",
12
+ "@types/chrome": "^0.0.280",
13
+ "@types/node": "^20.0.0"
11
14
  }
12
15
  }
@@ -7,6 +7,11 @@
7
7
  },
8
8
  "scripts": {
9
9
  "dev": "node --experimental-strip-types src/index.ts",
10
+ "typecheck": "tsc --noEmit",
10
11
  "validate": "node validate-types.mjs"
12
+ },
13
+ "devDependencies": {
14
+ "typescript": "^5.7.0",
15
+ "@types/node": "^20.0.0"
11
16
  }
12
17
  }
@@ -8,6 +8,8 @@
8
8
  "validate": "node validate-types.mjs"
9
9
  },
10
10
  "devDependencies": {
11
- "electron": "^36.0.0"
11
+ "electron": "^36.0.0",
12
+ "typescript": "^5.7.0",
13
+ "@types/node": "^20.0.0"
12
14
  }
13
15
  }
@@ -10,5 +10,9 @@
10
10
  "expo": "^53.0.0",
11
11
  "react": "^19.1.0",
12
12
  "react-native": "^0.79.0"
13
+ },
14
+ "devDependencies": {
15
+ "typescript": "^5.7.0",
16
+ "@types/react": "^19.0.0"
13
17
  }
14
18
  }
@@ -11,6 +11,6 @@
11
11
  "@nomicfoundation/hardhat-toolbox": "^5.0.0",
12
12
  "@cofhe/hardhat-plugin": "latest",
13
13
  "@fhenixprotocol/cofhe-contracts": "latest",
14
- "cofhejs": "^0.4.1"
14
+ "cofhejs": "^0.3.1"
15
15
  }
16
16
  }
@@ -9,7 +9,7 @@
9
9
  "devDependencies": {
10
10
  "hardhat": "^2.22.0",
11
11
  "@nomicfoundation/hardhat-toolbox": "^5.0.0",
12
- "@fhevm/solidity": "^0.6.2",
12
+ "@fhevm/solidity": "^0.11.1",
13
13
  "@fhevm/hardhat-plugin": "latest",
14
14
  "@fhevm-sdk/core": "^0.1.6"
15
15
  }
@@ -16,6 +16,8 @@
16
16
  "devDependencies": {
17
17
  "@tailwindcss/postcss": "latest",
18
18
  "postcss": "latest",
19
- "tailwindcss": "latest"
19
+ "tailwindcss": "latest",
20
+ "typescript": "^5.7.0",
21
+ "@types/node": "^20.0.0"
20
22
  }
21
23
  }
@@ -8,6 +8,8 @@
8
8
  },
9
9
  "devDependencies": {
10
10
  "hardhat": "^2.22.0",
11
- "@nomicfoundation/hardhat-toolbox": "^5.0.0"
11
+ "@nomicfoundation/hardhat-toolbox": "^5.0.0",
12
+ "@types/node": "^20.0.0",
13
+ "typescript": "^5.7.0"
12
14
  }
13
15
  }