@req2rank/core 0.1.0-r7
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.
- package/LICENSE +21 -0
- package/dist/adaptive-calibration.d.ts +13 -0
- package/dist/adaptive-calibration.d.ts.map +1 -0
- package/dist/adaptive-calibration.js +39 -0
- package/dist/adaptive-calibration.js.map +1 -0
- package/dist/adaptive-calibration.test.d.ts +2 -0
- package/dist/adaptive-calibration.test.d.ts.map +1 -0
- package/dist/adaptive-calibration.test.js +20 -0
- package/dist/adaptive-calibration.test.js.map +1 -0
- package/dist/checkpoint-key.d.ts +3 -0
- package/dist/checkpoint-key.d.ts.map +1 -0
- package/dist/checkpoint-key.js +29 -0
- package/dist/checkpoint-key.js.map +1 -0
- package/dist/checkpoint-key.test.d.ts +2 -0
- package/dist/checkpoint-key.test.d.ts.map +1 -0
- package/dist/checkpoint-key.test.js +32 -0
- package/dist/checkpoint-key.test.js.map +1 -0
- package/dist/config.d.ts +205 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +85 -0
- package/dist/config.js.map +1 -0
- package/dist/domain-taxonomy.d.ts +13 -0
- package/dist/domain-taxonomy.d.ts.map +1 -0
- package/dist/domain-taxonomy.js +12 -0
- package/dist/domain-taxonomy.js.map +1 -0
- package/dist/evaluation-panel.d.ts +27 -0
- package/dist/evaluation-panel.d.ts.map +1 -0
- package/dist/evaluation-panel.js +158 -0
- package/dist/evaluation-panel.js.map +1 -0
- package/dist/evaluation-panel.test.d.ts +2 -0
- package/dist/evaluation-panel.test.d.ts.map +1 -0
- package/dist/evaluation-panel.test.js +185 -0
- package/dist/evaluation-panel.test.js.map +1 -0
- package/dist/evidence-chain.d.ts +11 -0
- package/dist/evidence-chain.d.ts.map +1 -0
- package/dist/evidence-chain.js +33 -0
- package/dist/evidence-chain.js.map +1 -0
- package/dist/evidence-chain.test.d.ts +2 -0
- package/dist/evidence-chain.test.d.ts.map +1 -0
- package/dist/evidence-chain.test.js +16 -0
- package/dist/evidence-chain.test.js.map +1 -0
- package/dist/execution-engine.d.ts +29 -0
- package/dist/execution-engine.d.ts.map +1 -0
- package/dist/execution-engine.js +102 -0
- package/dist/execution-engine.js.map +1 -0
- package/dist/execution-engine.test.d.ts +2 -0
- package/dist/execution-engine.test.d.ts.map +1 -0
- package/dist/execution-engine.test.js +86 -0
- package/dist/execution-engine.test.js.map +1 -0
- package/dist/hub-client.d.ts +21 -0
- package/dist/hub-client.d.ts.map +1 -0
- package/dist/hub-client.js +99 -0
- package/dist/hub-client.js.map +1 -0
- package/dist/hub-client.test.d.ts +2 -0
- package/dist/hub-client.test.d.ts.map +1 -0
- package/dist/hub-client.test.js +129 -0
- package/dist/hub-client.test.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/leaderboard-query.d.ts +29 -0
- package/dist/leaderboard-query.d.ts.map +1 -0
- package/dist/leaderboard-query.js +59 -0
- package/dist/leaderboard-query.js.map +1 -0
- package/dist/leaderboard-query.test.d.ts +2 -0
- package/dist/leaderboard-query.test.d.ts.map +1 -0
- package/dist/leaderboard-query.test.js +34 -0
- package/dist/leaderboard-query.test.js.map +1 -0
- package/dist/local-store.d.ts +18 -0
- package/dist/local-store.d.ts.map +1 -0
- package/dist/local-store.js +181 -0
- package/dist/local-store.js.map +1 -0
- package/dist/local-store.test.d.ts +2 -0
- package/dist/local-store.test.d.ts.map +1 -0
- package/dist/local-store.test.js +153 -0
- package/dist/local-store.test.js.map +1 -0
- package/dist/pipeline-stage-handoff.test.d.ts +2 -0
- package/dist/pipeline-stage-handoff.test.d.ts.map +1 -0
- package/dist/pipeline-stage-handoff.test.js +290 -0
- package/dist/pipeline-stage-handoff.test.js.map +1 -0
- package/dist/pipeline.d.ts +67 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +493 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/providers/anthropic.d.ts +8 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +45 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/base.d.ts +36 -0
- package/dist/providers/base.d.ts.map +1 -0
- package/dist/providers/base.js +47 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/custom.d.ts +6 -0
- package/dist/providers/custom.d.ts.map +1 -0
- package/dist/providers/custom.js +6 -0
- package/dist/providers/custom.js.map +1 -0
- package/dist/providers/google.d.ts +8 -0
- package/dist/providers/google.d.ts.map +1 -0
- package/dist/providers/google.js +48 -0
- package/dist/providers/google.js.map +1 -0
- package/dist/providers/index.d.ts +31 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +63 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai.d.ts +18 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +111 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/providers.test.d.ts +2 -0
- package/dist/providers/providers.test.d.ts.map +1 -0
- package/dist/providers/providers.test.js +71 -0
- package/dist/providers/providers.test.js.map +1 -0
- package/dist/requirement-generator.d.ts +29 -0
- package/dist/requirement-generator.d.ts.map +1 -0
- package/dist/requirement-generator.js +358 -0
- package/dist/requirement-generator.js.map +1 -0
- package/dist/requirement-generator.test.d.ts +2 -0
- package/dist/requirement-generator.test.d.ts.map +1 -0
- package/dist/requirement-generator.test.js +182 -0
- package/dist/requirement-generator.test.js.map +1 -0
- package/dist/sandbox.d.ts +32 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +124 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/sandbox.test.d.ts +2 -0
- package/dist/sandbox.test.d.ts.map +1 -0
- package/dist/sandbox.test.js +20 -0
- package/dist/sandbox.test.js.map +1 -0
- package/dist/scoring-engine.d.ts +15 -0
- package/dist/scoring-engine.d.ts.map +1 -0
- package/dist/scoring-engine.js +109 -0
- package/dist/scoring-engine.js.map +1 -0
- package/dist/scoring-engine.test.d.ts +2 -0
- package/dist/scoring-engine.test.d.ts.map +1 -0
- package/dist/scoring-engine.test.js +137 -0
- package/dist/scoring-engine.test.js.map +1 -0
- package/dist/submit-payload-builder.d.ts +9 -0
- package/dist/submit-payload-builder.d.ts.map +1 -0
- package/dist/submit-payload-builder.js +23 -0
- package/dist/submit-payload-builder.js.map +1 -0
- package/dist/submit-payload-builder.test.d.ts +2 -0
- package/dist/submit-payload-builder.test.d.ts.map +1 -0
- package/dist/submit-payload-builder.test.js +75 -0
- package/dist/submit-payload-builder.test.js.map +1 -0
- package/dist/submitter-types.d.ts +54 -0
- package/dist/submitter-types.d.ts.map +1 -0
- package/dist/submitter-types.js +2 -0
- package/dist/submitter-types.js.map +1 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { DOMAIN_NAMES, DOMAIN_TAXONOMY } from "./domain-taxonomy.js";
|
|
2
|
+
const DEFAULT_SEEDS = [
|
|
3
|
+
{
|
|
4
|
+
id: "seed-cli-transformer",
|
|
5
|
+
template: "Build a {artifact} tool for {scenario} with {constraint}",
|
|
6
|
+
skills: ["data-processing", "error-handling"],
|
|
7
|
+
complexity: "C1",
|
|
8
|
+
slots: {
|
|
9
|
+
artifact: ["CLI", "pipeline", "parser"],
|
|
10
|
+
scenario: ["CSV cleaning", "log normalization", "JSON validation"],
|
|
11
|
+
constraint: ["strict input validation", "retry-safe processing", "clear error summaries"]
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: "seed-api-workflow",
|
|
16
|
+
template: "Design a {scope} API for {domainObject} including {constraint}",
|
|
17
|
+
skills: ["api-design", "testing", "error-handling"],
|
|
18
|
+
complexity: "C2",
|
|
19
|
+
slots: {
|
|
20
|
+
scope: ["REST", "resource workflow", "state transition"],
|
|
21
|
+
domainObject: ["orders", "tickets", "subscriptions"],
|
|
22
|
+
constraint: ["idempotency", "rate-limited retries", "role-based permissions"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: "seed-service-orchestration",
|
|
27
|
+
template: "Implement a {artifact} orchestration for {domain} with {constraint}",
|
|
28
|
+
skills: ["distributed-systems", "api-design", "observability"],
|
|
29
|
+
complexity: "C3",
|
|
30
|
+
slots: {
|
|
31
|
+
artifact: ["multi-service workflow", "event-driven coordinator", "saga executor"],
|
|
32
|
+
constraint: ["exactly-once semantics", "compensating actions", "partial-failure recovery"]
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "seed-platform-governance",
|
|
37
|
+
template: "Design a {artifact} platform for {domain} requiring {constraint}",
|
|
38
|
+
skills: ["security", "governance", "testing"],
|
|
39
|
+
complexity: "C4",
|
|
40
|
+
slots: {
|
|
41
|
+
artifact: ["tenant-isolated runtime", "compliance-grade audit system", "policy-driven execution mesh"],
|
|
42
|
+
constraint: ["formal rollback strategy", "cross-region consistency", "regulated data retention controls"]
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "seed-ai-evaluation-suite",
|
|
47
|
+
template: "Build a {artifact} for {scenario} with {constraint}",
|
|
48
|
+
skills: ["evaluation", "data-processing", "error-handling"],
|
|
49
|
+
complexity: "C3",
|
|
50
|
+
slots: {
|
|
51
|
+
artifact: ["benchmark harness", "evaluation aggregator", "trace replay runner"],
|
|
52
|
+
scenario: ["model ranking", "regression gating", "failure clustering"],
|
|
53
|
+
constraint: ["deterministic replay", "parallel isolation", "reproducible scoring"]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
class SeededRng {
|
|
58
|
+
state;
|
|
59
|
+
constructor(seed) {
|
|
60
|
+
this.state = hashSeed(seed);
|
|
61
|
+
}
|
|
62
|
+
next() {
|
|
63
|
+
this.state = (1664525 * this.state + 1013904223) % 4294967296;
|
|
64
|
+
return this.state / 4294967296;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function hashSeed(seed) {
|
|
68
|
+
let hash = 2166136261;
|
|
69
|
+
for (let i = 0; i < seed.length; i += 1) {
|
|
70
|
+
hash ^= seed.charCodeAt(i);
|
|
71
|
+
hash = Math.imul(hash, 16777619);
|
|
72
|
+
}
|
|
73
|
+
return hash >>> 0;
|
|
74
|
+
}
|
|
75
|
+
function pickOne(items, rng) {
|
|
76
|
+
if (items.length === 0) {
|
|
77
|
+
throw new Error("Cannot pick from empty list.");
|
|
78
|
+
}
|
|
79
|
+
const index = Math.floor(rng.next() * items.length);
|
|
80
|
+
return items[index];
|
|
81
|
+
}
|
|
82
|
+
function chooseSeed(input, seeds, rng) {
|
|
83
|
+
const candidates = seeds.filter((seed) => seed.complexity === input.complexity && seed.skills.some((skill) => input.skills.includes(skill)));
|
|
84
|
+
if (candidates.length > 0) {
|
|
85
|
+
return pickOne(candidates, rng);
|
|
86
|
+
}
|
|
87
|
+
return pickOne(seeds.filter((seed) => seed.complexity === input.complexity), rng);
|
|
88
|
+
}
|
|
89
|
+
function fillTemplate(seed, input, rng) {
|
|
90
|
+
const mutationLog = [];
|
|
91
|
+
let text = seed.template;
|
|
92
|
+
for (const [slotKey, slotValues] of Object.entries(seed.slots)) {
|
|
93
|
+
const value = pickOne(slotValues, rng);
|
|
94
|
+
text = text.replace(`{${slotKey}}`, value);
|
|
95
|
+
mutationLog.push(`slot:${slotKey}=${value}`);
|
|
96
|
+
}
|
|
97
|
+
text = text.replace("{domain}", input.domain).replace("{scenario}", input.scenario);
|
|
98
|
+
mutationLog.push(`domain:${input.domain}`);
|
|
99
|
+
mutationLog.push(`scenario:${input.scenario}`);
|
|
100
|
+
if (input.extraConstraints && input.extraConstraints.length > 0) {
|
|
101
|
+
mutationLog.push(`extra-constraints:${input.extraConstraints.join("|")}`);
|
|
102
|
+
}
|
|
103
|
+
return { text, mutationLog };
|
|
104
|
+
}
|
|
105
|
+
function parseJsonObject(raw) {
|
|
106
|
+
try {
|
|
107
|
+
const parsed = JSON.parse(raw);
|
|
108
|
+
if (parsed && typeof parsed === "object") {
|
|
109
|
+
return parsed;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// continue with fence fallback
|
|
114
|
+
}
|
|
115
|
+
const jsonFence = raw.match(/```json\r?\n([\s\S]*?)```/i);
|
|
116
|
+
if (jsonFence) {
|
|
117
|
+
try {
|
|
118
|
+
const parsed = JSON.parse(jsonFence[1]);
|
|
119
|
+
if (parsed && typeof parsed === "object") {
|
|
120
|
+
return parsed;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
function normalizePriority(value) {
|
|
130
|
+
if (value === "must" || value === "should" || value === "nice-to-have") {
|
|
131
|
+
return value;
|
|
132
|
+
}
|
|
133
|
+
return "must";
|
|
134
|
+
}
|
|
135
|
+
function buildDefaultFunctionalRequirements(description) {
|
|
136
|
+
return [
|
|
137
|
+
{
|
|
138
|
+
id: "FR-1",
|
|
139
|
+
description: `Implement the core flow: ${description}`,
|
|
140
|
+
acceptanceCriteria: "Core flow behaves as specified for valid input.",
|
|
141
|
+
priority: "must"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: "FR-2",
|
|
145
|
+
description: "Handle at least one edge case with deterministic behavior.",
|
|
146
|
+
acceptanceCriteria: "Edge-case path is explicitly handled and testable.",
|
|
147
|
+
priority: "must"
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
function toProjectRequirementDraft(parsed, fallbackDescription) {
|
|
152
|
+
const functionalRequirements = Array.isArray(parsed.functionalRequirements)
|
|
153
|
+
? parsed.functionalRequirements
|
|
154
|
+
.filter((item) => item && typeof item === "object")
|
|
155
|
+
.map((item, index) => {
|
|
156
|
+
const record = item;
|
|
157
|
+
return {
|
|
158
|
+
id: typeof record.id === "string" && record.id.length > 0 ? record.id : `FR-${index + 1}`,
|
|
159
|
+
description: typeof record.description === "string" && record.description.length > 0
|
|
160
|
+
? record.description
|
|
161
|
+
: "Implement specified feature",
|
|
162
|
+
acceptanceCriteria: typeof record.acceptanceCriteria === "string" && record.acceptanceCriteria.length > 0
|
|
163
|
+
? record.acceptanceCriteria
|
|
164
|
+
: "Behavior is verifiable with pass/fail criteria",
|
|
165
|
+
priority: normalizePriority(record.priority)
|
|
166
|
+
};
|
|
167
|
+
})
|
|
168
|
+
: [];
|
|
169
|
+
const normalizedFunctionalRequirements = functionalRequirements.length >= 2
|
|
170
|
+
? functionalRequirements
|
|
171
|
+
: [...functionalRequirements, ...buildDefaultFunctionalRequirements(fallbackDescription)].slice(0, 2);
|
|
172
|
+
const evaluationGuidanceInput = parsed.evaluationGuidance && typeof parsed.evaluationGuidance === "object"
|
|
173
|
+
? parsed.evaluationGuidance
|
|
174
|
+
: undefined;
|
|
175
|
+
return {
|
|
176
|
+
title: typeof parsed.title === "string" && parsed.title.length > 0 ? parsed.title : "Generated Requirement",
|
|
177
|
+
description: typeof parsed.description === "string" && parsed.description.length > 0 ? parsed.description : fallbackDescription,
|
|
178
|
+
functionalRequirements: normalizedFunctionalRequirements,
|
|
179
|
+
constraints: Array.isArray(parsed.constraints) ? parsed.constraints.filter((item) => typeof item === "string") : [],
|
|
180
|
+
expectedDeliverables: Array.isArray(parsed.expectedDeliverables)
|
|
181
|
+
? parsed.expectedDeliverables.filter((item) => typeof item === "string")
|
|
182
|
+
: ["source code", "tests"],
|
|
183
|
+
exampleIO: Array.isArray(parsed.exampleIO)
|
|
184
|
+
? parsed.exampleIO
|
|
185
|
+
.filter((item) => item && typeof item === "object")
|
|
186
|
+
.map((item) => {
|
|
187
|
+
const record = item;
|
|
188
|
+
return {
|
|
189
|
+
input: typeof record.input === "string" ? record.input : "",
|
|
190
|
+
expectedOutput: typeof record.expectedOutput === "string" ? record.expectedOutput : ""
|
|
191
|
+
};
|
|
192
|
+
})
|
|
193
|
+
.filter((item) => item.input.length > 0 && item.expectedOutput.length > 0)
|
|
194
|
+
: undefined,
|
|
195
|
+
evaluationGuidance: {
|
|
196
|
+
keyDifferentiators: Array.isArray(evaluationGuidanceInput?.keyDifferentiators)
|
|
197
|
+
? evaluationGuidanceInput.keyDifferentiators.filter((item) => typeof item === "string")
|
|
198
|
+
: ["requirement coverage", "clarity", "edge-case handling"],
|
|
199
|
+
commonPitfalls: Array.isArray(evaluationGuidanceInput?.commonPitfalls)
|
|
200
|
+
? evaluationGuidanceInput.commonPitfalls.filter((item) => typeof item === "string")
|
|
201
|
+
: ["missing validation", "incomplete acceptance criteria"],
|
|
202
|
+
edgeCases: Array.isArray(evaluationGuidanceInput?.edgeCases)
|
|
203
|
+
? evaluationGuidanceInput.edgeCases.filter((item) => typeof item === "string")
|
|
204
|
+
: ["empty input", "invalid parameter"]
|
|
205
|
+
},
|
|
206
|
+
selfReviewPassed: Boolean(parsed.selfReviewPassed)
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function buildStageOnePrompt(input, generatedSeedText) {
|
|
210
|
+
return [
|
|
211
|
+
"You are a senior software PM. Draft a project requirement document.",
|
|
212
|
+
"",
|
|
213
|
+
`Skills: ${input.skills.join(", ")}`,
|
|
214
|
+
`Complexity: ${input.complexity}`,
|
|
215
|
+
`Domain: ${input.domain}`,
|
|
216
|
+
`Scenario: ${input.scenario}`,
|
|
217
|
+
`Tech stack: ${input.techStack.join(", ")}`,
|
|
218
|
+
`Seed requirement skeleton: ${generatedSeedText}`,
|
|
219
|
+
input.extraConstraints && input.extraConstraints.length > 0
|
|
220
|
+
? `Additional constraints: ${input.extraConstraints.join("; ")}`
|
|
221
|
+
: "Additional constraints: none",
|
|
222
|
+
"",
|
|
223
|
+
"Requirements:",
|
|
224
|
+
"1. Produce concrete, testable functional requirements.",
|
|
225
|
+
"2. Include at least one explicit edge case.",
|
|
226
|
+
"3. Keep scope aligned with the complexity.",
|
|
227
|
+
"4. Include delivery expectations (code/tests/docs)."
|
|
228
|
+
].join("\n");
|
|
229
|
+
}
|
|
230
|
+
function buildStageTwoPrompt(draftRequirement, complexity) {
|
|
231
|
+
return [
|
|
232
|
+
"You are a QA reviewer. Audit and improve this requirement draft.",
|
|
233
|
+
"",
|
|
234
|
+
"Checklist:",
|
|
235
|
+
"1. Remove ambiguity.",
|
|
236
|
+
"2. Ensure each requirement has pass/fail acceptance criteria.",
|
|
237
|
+
"3. Confirm technical feasibility.",
|
|
238
|
+
`4. Keep difficulty at complexity ${complexity}.`,
|
|
239
|
+
"5. Resolve conflicting constraints.",
|
|
240
|
+
"",
|
|
241
|
+
"Draft:",
|
|
242
|
+
draftRequirement
|
|
243
|
+
].join("\n");
|
|
244
|
+
}
|
|
245
|
+
function buildStageThreePrompt(reviewedRequirement) {
|
|
246
|
+
return [
|
|
247
|
+
"Convert the reviewed requirement into strict JSON.",
|
|
248
|
+
"Return only JSON object with keys:",
|
|
249
|
+
"title, description, functionalRequirements[], constraints[], expectedDeliverables[], exampleIO[{input,expectedOutput}], evaluationGuidance{keyDifferentiators[], commonPitfalls[], edgeCases[]}, selfReviewPassed",
|
|
250
|
+
"Each functional requirement must include id, description, acceptanceCriteria, priority.",
|
|
251
|
+
"",
|
|
252
|
+
"Reviewed requirement:",
|
|
253
|
+
reviewedRequirement
|
|
254
|
+
].join("\n");
|
|
255
|
+
}
|
|
256
|
+
export class RequirementGenerator {
|
|
257
|
+
seeds;
|
|
258
|
+
constructor(seeds = DEFAULT_SEEDS) {
|
|
259
|
+
this.seeds = seeds;
|
|
260
|
+
}
|
|
261
|
+
async generate(input, modelConfig) {
|
|
262
|
+
const seedValue = input.seed ?? `${input.domain}:${input.scenario}:${Date.now()}`;
|
|
263
|
+
const rng = new SeededRng(seedValue);
|
|
264
|
+
const selectedSeed = chooseSeed(input, this.seeds, rng);
|
|
265
|
+
const shouldSampleTaxonomy = input.domain.trim().toLowerCase() === "generic" || input.scenario.trim().toLowerCase() === "pipeline-eval";
|
|
266
|
+
const sampledDomain = shouldSampleTaxonomy ? pickOne(DOMAIN_NAMES, rng) : input.domain;
|
|
267
|
+
const sampledScenario = shouldSampleTaxonomy && sampledDomain in DOMAIN_TAXONOMY
|
|
268
|
+
? pickOne([...DOMAIN_TAXONOMY[sampledDomain]], rng)
|
|
269
|
+
: input.scenario;
|
|
270
|
+
const normalizedInput = {
|
|
271
|
+
...input,
|
|
272
|
+
domain: sampledDomain,
|
|
273
|
+
scenario: sampledScenario
|
|
274
|
+
};
|
|
275
|
+
const generated = fillTemplate(selectedSeed, normalizedInput, rng);
|
|
276
|
+
const stageOne = await modelConfig.provider.chat({
|
|
277
|
+
model: modelConfig.model,
|
|
278
|
+
temperature: 0.4,
|
|
279
|
+
maxTokens: 2_048,
|
|
280
|
+
messages: [
|
|
281
|
+
{
|
|
282
|
+
role: "system",
|
|
283
|
+
content: "You produce high-quality, unambiguous software project requirements."
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
role: "user",
|
|
287
|
+
content: buildStageOnePrompt(normalizedInput, generated.text)
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
});
|
|
291
|
+
const stageTwo = await modelConfig.provider.chat({
|
|
292
|
+
model: modelConfig.model,
|
|
293
|
+
temperature: 0.2,
|
|
294
|
+
maxTokens: 2_048,
|
|
295
|
+
messages: [
|
|
296
|
+
{
|
|
297
|
+
role: "system",
|
|
298
|
+
content: "You are a strict QA reviewer for software requirements."
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
role: "user",
|
|
302
|
+
content: buildStageTwoPrompt(stageOne.content, normalizedInput.complexity)
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
});
|
|
306
|
+
const stageThree = await modelConfig.provider.chat({
|
|
307
|
+
model: modelConfig.model,
|
|
308
|
+
temperature: 0,
|
|
309
|
+
maxTokens: 2_048,
|
|
310
|
+
responseFormat: "json",
|
|
311
|
+
messages: [
|
|
312
|
+
{
|
|
313
|
+
role: "system",
|
|
314
|
+
content: "Return strictly valid JSON with no markdown."
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
role: "user",
|
|
318
|
+
content: buildStageThreePrompt(stageTwo.content)
|
|
319
|
+
}
|
|
320
|
+
]
|
|
321
|
+
});
|
|
322
|
+
const parsed = parseJsonObject(stageThree.content);
|
|
323
|
+
const normalized = toProjectRequirementDraft(parsed ?? {}, stageTwo.content);
|
|
324
|
+
const requirementId = `req-${Math.floor(rng.next() * 1_000_000)}`;
|
|
325
|
+
const constraints = [
|
|
326
|
+
`Complexity constrained to ${input.complexity}`,
|
|
327
|
+
...normalized.constraints
|
|
328
|
+
];
|
|
329
|
+
if (input.extraConstraints) {
|
|
330
|
+
constraints.push(...input.extraConstraints);
|
|
331
|
+
}
|
|
332
|
+
return {
|
|
333
|
+
id: requirementId,
|
|
334
|
+
version: "1.0",
|
|
335
|
+
title: normalized.title,
|
|
336
|
+
description: normalized.description,
|
|
337
|
+
functionalRequirements: normalized.functionalRequirements,
|
|
338
|
+
constraints,
|
|
339
|
+
expectedDeliverables: normalized.expectedDeliverables,
|
|
340
|
+
exampleIO: normalized.exampleIO,
|
|
341
|
+
metadata: {
|
|
342
|
+
skills: input.skills,
|
|
343
|
+
complexity: input.complexity,
|
|
344
|
+
domain: normalizedInput.domain,
|
|
345
|
+
scenario: normalizedInput.scenario,
|
|
346
|
+
techStack: input.techStack,
|
|
347
|
+
seedId: selectedSeed.id,
|
|
348
|
+
mutationLog: generated.mutationLog
|
|
349
|
+
},
|
|
350
|
+
evaluationGuidance: normalized.evaluationGuidance,
|
|
351
|
+
generatedBy: "req2rank-requirement-generator",
|
|
352
|
+
generatedAt: new Date().toISOString(),
|
|
353
|
+
selfReviewPassed: normalized.selfReviewPassed
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
export const defaultSeeds = DEFAULT_SEEDS;
|
|
358
|
+
//# sourceMappingURL=requirement-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirement-generator.js","sourceRoot":"","sources":["../src/requirement-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirement-generator.test.d.ts","sourceRoot":"","sources":["../src/requirement-generator.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { RequirementGenerator } from "./requirement-generator.js";
|
|
3
|
+
class StubProvider {
|
|
4
|
+
id = "stub";
|
|
5
|
+
name = "Stub";
|
|
6
|
+
callCount = 0;
|
|
7
|
+
async chat() {
|
|
8
|
+
this.callCount += 1;
|
|
9
|
+
if (this.callCount === 1) {
|
|
10
|
+
return {
|
|
11
|
+
content: "Draft requirement text.",
|
|
12
|
+
usage: { promptTokens: 10, completionTokens: 20 },
|
|
13
|
+
latencyMs: 5
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (this.callCount === 2) {
|
|
17
|
+
return {
|
|
18
|
+
content: "Reviewed requirement text.",
|
|
19
|
+
usage: { promptTokens: 11, completionTokens: 21 },
|
|
20
|
+
latencyMs: 6
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
content: JSON.stringify({
|
|
25
|
+
title: "Generated requirement",
|
|
26
|
+
description: "Detailed generated requirement",
|
|
27
|
+
functionalRequirements: [
|
|
28
|
+
{
|
|
29
|
+
id: "FR-1",
|
|
30
|
+
description: "Implement API endpoint",
|
|
31
|
+
acceptanceCriteria: "Request returns expected payload",
|
|
32
|
+
priority: "must"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "FR-2",
|
|
36
|
+
description: "Handle invalid input",
|
|
37
|
+
acceptanceCriteria: "Invalid payload returns 400",
|
|
38
|
+
priority: "must"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
constraints: ["Use TypeScript"],
|
|
42
|
+
expectedDeliverables: ["source code", "tests"],
|
|
43
|
+
exampleIO: [
|
|
44
|
+
{
|
|
45
|
+
input: "POST /orders with valid payload",
|
|
46
|
+
expectedOutput: "201 Created with order id"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
evaluationGuidance: {
|
|
50
|
+
keyDifferentiators: ["robust validation"],
|
|
51
|
+
commonPitfalls: ["missing error handling"],
|
|
52
|
+
edgeCases: ["empty request body"]
|
|
53
|
+
},
|
|
54
|
+
selfReviewPassed: true
|
|
55
|
+
}),
|
|
56
|
+
usage: { promptTokens: 12, completionTokens: 22 },
|
|
57
|
+
latencyMs: 7
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
class StubFencedJsonProvider {
|
|
62
|
+
id = "stub-fenced";
|
|
63
|
+
name = "Stub Fenced";
|
|
64
|
+
callCount = 0;
|
|
65
|
+
async chat() {
|
|
66
|
+
this.callCount += 1;
|
|
67
|
+
if (this.callCount < 3) {
|
|
68
|
+
return {
|
|
69
|
+
content: this.callCount === 1 ? "Draft requirement text." : "Reviewed requirement text.",
|
|
70
|
+
usage: { promptTokens: 10, completionTokens: 20 },
|
|
71
|
+
latencyMs: 5
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
content: "```json\r\n{\"title\":\"Generated requirement\",\"description\":\"Detailed generated requirement\",\"functionalRequirements\":[{\"id\":\"FR-1\",\"description\":\"Implement API endpoint\",\"acceptanceCriteria\":\"Request returns expected payload\",\"priority\":\"must\"},{\"id\":\"FR-2\",\"description\":\"Handle invalid input\",\"acceptanceCriteria\":\"Invalid payload returns 400\",\"priority\":\"must\"}],\"constraints\":[\"Use TypeScript\"],\"expectedDeliverables\":[\"source code\",\"tests\"],\"selfReviewPassed\":true}\r\n```",
|
|
76
|
+
usage: { promptTokens: 12, completionTokens: 22 },
|
|
77
|
+
latencyMs: 7
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
describe("RequirementGenerator", () => {
|
|
82
|
+
it("returns deterministic seed metadata with fixed seed", async () => {
|
|
83
|
+
const provider = new StubProvider();
|
|
84
|
+
const generator = new RequirementGenerator();
|
|
85
|
+
const input = {
|
|
86
|
+
skills: ["api-design", "error-handling"],
|
|
87
|
+
complexity: "C2",
|
|
88
|
+
domain: "ecommerce",
|
|
89
|
+
scenario: "order-state",
|
|
90
|
+
techStack: ["typescript"],
|
|
91
|
+
seed: "fixed-seed"
|
|
92
|
+
};
|
|
93
|
+
const first = await generator.generate(input, { provider, model: "gpt-4o-mini" });
|
|
94
|
+
const second = await generator.generate(input, { provider, model: "gpt-4o-mini" });
|
|
95
|
+
expect(first.metadata.seedId).toBe(second.metadata.seedId);
|
|
96
|
+
expect(first.metadata.mutationLog).toEqual(second.metadata.mutationLog);
|
|
97
|
+
});
|
|
98
|
+
it("injects additional constraints", async () => {
|
|
99
|
+
const provider = new StubProvider();
|
|
100
|
+
const generator = new RequirementGenerator();
|
|
101
|
+
const result = await generator.generate({
|
|
102
|
+
skills: ["data-processing"],
|
|
103
|
+
complexity: "C1",
|
|
104
|
+
domain: "analytics",
|
|
105
|
+
scenario: "log-parser",
|
|
106
|
+
techStack: ["typescript"],
|
|
107
|
+
seed: "constraint-seed",
|
|
108
|
+
extraConstraints: ["must finish under 100 lines"]
|
|
109
|
+
}, { provider, model: "gpt-4o-mini" });
|
|
110
|
+
expect(result.constraints).toContain("must finish under 100 lines");
|
|
111
|
+
expect(result.metadata.mutationLog.some((entry) => entry.startsWith("extra-constraints:"))).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
it("runs a three-stage prompt pipeline", async () => {
|
|
114
|
+
const provider = new StubProvider();
|
|
115
|
+
const generator = new RequirementGenerator();
|
|
116
|
+
const result = await generator.generate({
|
|
117
|
+
skills: ["api-design", "error-handling"],
|
|
118
|
+
complexity: "C2",
|
|
119
|
+
domain: "ecommerce",
|
|
120
|
+
scenario: "order-state",
|
|
121
|
+
techStack: ["typescript"],
|
|
122
|
+
seed: "stage-seed"
|
|
123
|
+
}, { provider, model: "gpt-4o-mini" });
|
|
124
|
+
expect(provider.callCount).toBe(3);
|
|
125
|
+
expect(result.functionalRequirements.length).toBeGreaterThanOrEqual(2);
|
|
126
|
+
expect(result.title).toBe("Generated requirement");
|
|
127
|
+
expect(result.exampleIO?.[0]?.input).toContain("POST /orders");
|
|
128
|
+
});
|
|
129
|
+
it("supports C3/C4 generation with richer seeds", async () => {
|
|
130
|
+
const provider = new StubProvider();
|
|
131
|
+
const generator = new RequirementGenerator();
|
|
132
|
+
const c3 = await generator.generate({
|
|
133
|
+
skills: ["distributed-systems", "api-design"],
|
|
134
|
+
complexity: "C3",
|
|
135
|
+
domain: "platform",
|
|
136
|
+
scenario: "orchestration",
|
|
137
|
+
techStack: ["typescript"],
|
|
138
|
+
seed: "c3-seed"
|
|
139
|
+
}, { provider, model: "gpt-4o-mini" });
|
|
140
|
+
const c4 = await generator.generate({
|
|
141
|
+
skills: ["security", "governance"],
|
|
142
|
+
complexity: "C4",
|
|
143
|
+
domain: "banking",
|
|
144
|
+
scenario: "compliance",
|
|
145
|
+
techStack: ["typescript"],
|
|
146
|
+
seed: "c4-seed"
|
|
147
|
+
}, { provider, model: "gpt-4o-mini" });
|
|
148
|
+
expect(c3.metadata.complexity).toBe("C3");
|
|
149
|
+
expect(c4.metadata.complexity).toBe("C4");
|
|
150
|
+
expect(c3.metadata.seedId).toBeTruthy();
|
|
151
|
+
expect(c4.metadata.seedId).toBeTruthy();
|
|
152
|
+
});
|
|
153
|
+
it("parses fenced JSON payload with CRLF newlines", async () => {
|
|
154
|
+
const provider = new StubFencedJsonProvider();
|
|
155
|
+
const generator = new RequirementGenerator();
|
|
156
|
+
const result = await generator.generate({
|
|
157
|
+
skills: ["api-design", "error-handling"],
|
|
158
|
+
complexity: "C2",
|
|
159
|
+
domain: "ecommerce",
|
|
160
|
+
scenario: "order-state",
|
|
161
|
+
techStack: ["typescript"],
|
|
162
|
+
seed: "fenced-crlf-seed"
|
|
163
|
+
}, { provider, model: "gpt-4o-mini" });
|
|
164
|
+
expect(result.title).toBe("Generated requirement");
|
|
165
|
+
expect(result.functionalRequirements).toHaveLength(2);
|
|
166
|
+
});
|
|
167
|
+
it("samples domain taxonomy for generic pipeline input", async () => {
|
|
168
|
+
const provider = new StubProvider();
|
|
169
|
+
const generator = new RequirementGenerator();
|
|
170
|
+
const generated = await generator.generate({
|
|
171
|
+
skills: ["api-design", "error-handling"],
|
|
172
|
+
complexity: "C2",
|
|
173
|
+
domain: "generic",
|
|
174
|
+
scenario: "pipeline-eval",
|
|
175
|
+
techStack: ["typescript"],
|
|
176
|
+
seed: "taxonomy-seed"
|
|
177
|
+
}, { provider, model: "gpt-4o-mini" });
|
|
178
|
+
expect(generated.metadata.domain).not.toBe("generic");
|
|
179
|
+
expect(generated.metadata.scenario).not.toBe("pipeline-eval");
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
//# sourceMappingURL=requirement-generator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirement-generator.test.js","sourceRoot":"","sources":["../src/requirement-generator.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface SandboxOptions {
|
|
2
|
+
image?: string;
|
|
3
|
+
workdir?: string;
|
|
4
|
+
workspacePath?: string;
|
|
5
|
+
command?: string[];
|
|
6
|
+
timeoutMs?: number;
|
|
7
|
+
cpus?: number;
|
|
8
|
+
memoryMb?: number;
|
|
9
|
+
pidsLimit?: number;
|
|
10
|
+
network?: "none" | "bridge";
|
|
11
|
+
readOnly?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function buildDockerSandboxCommand(options?: SandboxOptions): string[];
|
|
14
|
+
export declare function runSandboxedCommand(options?: SandboxOptions): Promise<{
|
|
15
|
+
stdout: string;
|
|
16
|
+
stderr: string;
|
|
17
|
+
}>;
|
|
18
|
+
export interface SandboxedSubmissionInput {
|
|
19
|
+
code: string;
|
|
20
|
+
language: string;
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
image?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SandboxedSubmissionResult {
|
|
25
|
+
passed: boolean;
|
|
26
|
+
command: string[];
|
|
27
|
+
workspacePath: string;
|
|
28
|
+
stdout: string;
|
|
29
|
+
stderr: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function runSandboxedSubmission(input: SandboxedSubmissionInput): Promise<SandboxedSubmissionResult>;
|
|
32
|
+
//# sourceMappingURL=sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,cAAmB,GAAG,MAAM,EAAE,CAmChF;AAED,wBAAsB,mBAAmB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAOnH;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AA0CD,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAuChH"}
|