Spaces:
Runtime error
Runtime error
Upload 4 files
Browse files- src/stages/buildStage.js +44 -0
- src/stages/generateStage.js +22 -0
- src/stages/scoreStage.js +25 -0
- src/stages/scoutStage.js +22 -0
src/stages/buildStage.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Stage } from '../core/Stage.js';
|
| 2 |
+
import { config } from '../config.js';
|
| 3 |
+
|
| 4 |
+
/**
|
| 5 |
+
* BuildStage only produces a concrete BUILD SPEC — it does not itself write
|
| 6 |
+
* game code, generate video assets, or publish anything. That's intentional:
|
| 7 |
+
* build (generate the artifact) and publish (put it live) should be separate
|
| 8 |
+
* gates. Wire this spec into Claude Code / your codegen tool of choice, or
|
| 9 |
+
* a video/asset pipeline, once you're ready to actually produce the artifact.
|
| 10 |
+
*/
|
| 11 |
+
export class BuildStage extends Stage {
|
| 12 |
+
constructor() {
|
| 13 |
+
super({ name: 'build', model: config.models.build, temperature: 0.4, maxTokens: 900, jsonMode: true });
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
buildPrompt(scoreOutput) {
|
| 17 |
+
const system = `You are a Build-Spec agent. Given a greenlit concept, produce
|
| 18 |
+
a concrete, unambiguous build spec that a coding agent or a human could execute
|
| 19 |
+
without further clarification. Do not write full code — write the spec.
|
| 20 |
+
Output strict JSON, no markdown fences.`;
|
| 21 |
+
|
| 22 |
+
const user = `Greenlit concept: ${JSON.stringify(scoreOutput.greenlight)}
|
| 23 |
+
|
| 24 |
+
Return JSON:
|
| 25 |
+
{
|
| 26 |
+
"title": "...",
|
| 27 |
+
"format": "browser_game | mobile_app | video_script | other",
|
| 28 |
+
"core_loop_or_structure": "the single most important mechanic/structure, described concretely",
|
| 29 |
+
"build_steps": ["ordered, concrete steps a coding agent could follow"],
|
| 30 |
+
"estimated_effort": "S | M | L",
|
| 31 |
+
"monetization": "how this specific artifact makes money (ads, affiliate, IAP, none)",
|
| 32 |
+
"publish_checklist": ["things to verify before this goes live, e.g. store policy checks"]
|
| 33 |
+
}`;
|
| 34 |
+
return { system, user };
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
parseOutput(rawText) {
|
| 38 |
+
try {
|
| 39 |
+
return JSON.parse(rawText);
|
| 40 |
+
} catch {
|
| 41 |
+
return { kill: true, reason: 'build output was not valid JSON', raw: rawText };
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
}
|
src/stages/generateStage.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Stage } from '../core/Stage.js';
|
| 2 |
+
import { generatePrompt } from '../prompts/generate.js';
|
| 3 |
+
import { config } from '../config.js';
|
| 4 |
+
|
| 5 |
+
export class GenerateStage extends Stage {
|
| 6 |
+
constructor() {
|
| 7 |
+
super({ name: 'generate', model: config.models.generate, temperature: 1.0, maxTokens: 700, jsonMode: true });
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
buildPrompt(brief) {
|
| 11 |
+
return generatePrompt(brief);
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
parseOutput(rawText, brief) {
|
| 15 |
+
try {
|
| 16 |
+
const parsed = JSON.parse(rawText);
|
| 17 |
+
return { ...parsed, target_format: brief.target_format };
|
| 18 |
+
} catch {
|
| 19 |
+
return { kill: true, reason: 'generate output was not valid JSON', raw: rawText };
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
}
|
src/stages/scoreStage.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Stage } from '../core/Stage.js';
|
| 2 |
+
import { scorePrompt } from '../prompts/score.js';
|
| 3 |
+
import { config } from '../config.js';
|
| 4 |
+
|
| 5 |
+
export class ScoreStage extends Stage {
|
| 6 |
+
constructor() {
|
| 7 |
+
super({ name: 'score', model: config.models.score, temperature: 0.3, maxTokens: 600, jsonMode: true });
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
buildPrompt(genOutput) {
|
| 11 |
+
return scorePrompt(genOutput);
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
parseOutput(rawText) {
|
| 15 |
+
try {
|
| 16 |
+
const parsed = JSON.parse(rawText);
|
| 17 |
+
if (parsed.kill || !parsed.greenlight?.title) {
|
| 18 |
+
return { kill: true, reason: parsed.reason || 'no concept cleared the bar', scored: parsed.scored };
|
| 19 |
+
}
|
| 20 |
+
return parsed; // { scored, greenlight, kill: false }
|
| 21 |
+
} catch {
|
| 22 |
+
return { kill: true, reason: 'score output was not valid JSON', raw: rawText };
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
src/stages/scoutStage.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Stage } from '../core/Stage.js';
|
| 2 |
+
import { scoutPrompt } from '../prompts/scout.js';
|
| 3 |
+
import { config } from '../config.js';
|
| 4 |
+
|
| 5 |
+
export class ScoutStage extends Stage {
|
| 6 |
+
constructor() {
|
| 7 |
+
super({ name: 'scout', model: config.models.scout, temperature: 0.6, maxTokens: 400, jsonMode: true });
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
buildPrompt(input) {
|
| 11 |
+
// input: { niche, rawSignal }
|
| 12 |
+
return scoutPrompt(input);
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
parseOutput(rawText) {
|
| 16 |
+
try {
|
| 17 |
+
return JSON.parse(rawText);
|
| 18 |
+
} catch {
|
| 19 |
+
return { kill: true, reason: 'scout output was not valid JSON', raw: rawText };
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
}
|