beercan 0.6.12 → 0.6.14
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/README.md +60 -10
- package/dist/chat/index.d.ts +3 -3
- package/dist/chat/index.d.ts.map +1 -1
- package/dist/chat/index.js +4 -4
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/intent.d.ts +2 -2
- package/dist/chat/intent.d.ts.map +1 -1
- package/dist/chat/intent.js +7 -7
- package/dist/chat/intent.js.map +1 -1
- package/dist/cli.js +269 -23
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +9 -0
- package/dist/config.js.map +1 -1
- package/dist/core/gatekeeper.d.ts +3 -3
- package/dist/core/gatekeeper.d.ts.map +1 -1
- package/dist/core/gatekeeper.js +12 -12
- package/dist/core/gatekeeper.js.map +1 -1
- package/dist/core/reflection.d.ts +3 -3
- package/dist/core/reflection.d.ts.map +1 -1
- package/dist/core/reflection.js +10 -10
- package/dist/core/reflection.js.map +1 -1
- package/dist/core/roles.js +1 -1
- package/dist/core/roles.js.map +1 -1
- package/dist/core/runner.d.ts +3 -3
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +12 -14
- package/dist/core/runner.js.map +1 -1
- package/dist/events/daemon.js +3 -3
- package/dist/events/daemon.js.map +1 -1
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +50 -5
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.d.ts +8 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +70 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/factory.d.ts +3 -0
- package/dist/providers/factory.d.ts.map +1 -0
- package/dist/providers/factory.js +58 -0
- package/dist/providers/factory.js.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +4 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai.d.ts +16 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +176 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/types.d.ts +54 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +4 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +44 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/tools/builtin/email.d.ts +5 -0
- package/dist/tools/builtin/email.d.ts.map +1 -0
- package/dist/tools/builtin/email.js +171 -0
- package/dist/tools/builtin/email.js.map +1 -0
- package/dist/tools/registry.d.ts +3 -12
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +3 -3
- package/dist/tools/registry.js.map +1 -1
- package/dist/training/curriculum.d.ts +4 -0
- package/dist/training/curriculum.d.ts.map +1 -0
- package/dist/training/curriculum.js +512 -0
- package/dist/training/curriculum.js.map +1 -0
- package/dist/training/evaluator.d.ts +21 -0
- package/dist/training/evaluator.d.ts.map +1 -0
- package/dist/training/evaluator.js +163 -0
- package/dist/training/evaluator.js.map +1 -0
- package/dist/training/exporter.d.ts +35 -0
- package/dist/training/exporter.d.ts.map +1 -0
- package/dist/training/exporter.js +377 -0
- package/dist/training/exporter.js.map +1 -0
- package/dist/training/index.d.ts +5 -0
- package/dist/training/index.d.ts.map +1 -0
- package/dist/training/index.js +5 -0
- package/dist/training/index.js.map +1 -0
- package/dist/training/sandbox-manager.d.ts +58 -0
- package/dist/training/sandbox-manager.d.ts.map +1 -0
- package/dist/training/sandbox-manager.js +416 -0
- package/dist/training/sandbox-manager.js.map +1 -0
- package/dist/training/types.d.ts +790 -0
- package/dist/training/types.d.ts.map +1 -0
- package/dist/training/types.js +154 -0
- package/dist/training/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { BeerCanEngine } from "../index.js";
|
|
2
|
+
import type { BeerCanDB } from "../storage/database.js";
|
|
3
|
+
import type { Config } from "../config.js";
|
|
4
|
+
import type { Project } from "../schemas.js";
|
|
5
|
+
import { type TrainingProgress, type TrainingScenario, type ScenarioAttempt } from "./types.js";
|
|
6
|
+
export declare class TrainingSandboxManager {
|
|
7
|
+
private engine;
|
|
8
|
+
private db;
|
|
9
|
+
private config;
|
|
10
|
+
private logger;
|
|
11
|
+
private evaluator;
|
|
12
|
+
constructor(engine: BeerCanEngine, db: BeerCanDB, config: Config);
|
|
13
|
+
/**
|
|
14
|
+
* Lazily initialise the evaluator (requires async provider creation).
|
|
15
|
+
*/
|
|
16
|
+
private getEvaluator;
|
|
17
|
+
/**
|
|
18
|
+
* Create a new training project for an agent trainee.
|
|
19
|
+
*/
|
|
20
|
+
createTrainee(name: string, workDir?: string): Promise<Project>;
|
|
21
|
+
/**
|
|
22
|
+
* Read training progress from the project's context.
|
|
23
|
+
*/
|
|
24
|
+
getProgress(projectSlug: string): Promise<TrainingProgress>;
|
|
25
|
+
/**
|
|
26
|
+
* Persist updated progress to the project context.
|
|
27
|
+
*/
|
|
28
|
+
updateProgress(projectSlug: string, progress: TrainingProgress): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Pick the next scenario based on prerequisites and current level.
|
|
31
|
+
* Returns null if no scenarios are available (all done or prerequisites not met).
|
|
32
|
+
*/
|
|
33
|
+
getNextScenario(projectSlug: string): Promise<TrainingScenario | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Get a specific scenario by ID.
|
|
36
|
+
*/
|
|
37
|
+
getScenario(scenarioId: string): TrainingScenario | null;
|
|
38
|
+
/**
|
|
39
|
+
* Run a training scenario (or the next available one).
|
|
40
|
+
* Executes the bloop, evaluates the result, updates progress.
|
|
41
|
+
*/
|
|
42
|
+
runScenario(projectSlug: string, scenarioId?: string): Promise<ScenarioAttempt>;
|
|
43
|
+
/**
|
|
44
|
+
* Check if the trainee meets graduation criteria.
|
|
45
|
+
* Updates graduation status if criteria are met.
|
|
46
|
+
*/
|
|
47
|
+
checkGraduation(projectSlug: string): Promise<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Get a human-readable status summary for a training project.
|
|
50
|
+
*/
|
|
51
|
+
getStatus(projectSlug: string): Promise<{
|
|
52
|
+
progress: TrainingProgress;
|
|
53
|
+
nextScenario: TrainingScenario | null;
|
|
54
|
+
summary: string;
|
|
55
|
+
}>;
|
|
56
|
+
private recordAttempt;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=sandbox-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-manager.d.ts","sourceRoot":"","sources":["../../src/training/sandbox-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AASpB,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAkC;gBAEvC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM;IAOhE;;OAEG;YACW,YAAY;IAU1B;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA4CrE;;OAEG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAcjE;;OAEG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BpF;;;OAGG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAuE5E;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAMxD;;;OAGG;IACG,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC;IAkI3B;;;OAGG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkD5D;;OAEG;IACG,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAC5C,QAAQ,EAAE,gBAAgB,CAAC;QAC3B,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAC;QACtC,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;YA4CY,aAAa;CAqC5B"}
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
import { getLogger } from "../core/logger.js";
|
|
2
|
+
import { TrainingProgressSchema, } from "./types.js";
|
|
3
|
+
import { DEFAULT_CURRICULUM, GRADUATION_CRITERIA } from "./curriculum.js";
|
|
4
|
+
import { ScenarioEvaluator } from "./evaluator.js";
|
|
5
|
+
import { createLLMProvider } from "../providers/factory.js";
|
|
6
|
+
// ── Training Sandbox Manager ─────────────────────────────────
|
|
7
|
+
// Manages training projects, runs scenarios, tracks progress, and
|
|
8
|
+
// evaluates graduation criteria.
|
|
9
|
+
export class TrainingSandboxManager {
|
|
10
|
+
engine;
|
|
11
|
+
db;
|
|
12
|
+
config;
|
|
13
|
+
logger;
|
|
14
|
+
evaluator = null;
|
|
15
|
+
constructor(engine, db, config) {
|
|
16
|
+
this.engine = engine;
|
|
17
|
+
this.db = db;
|
|
18
|
+
this.config = config;
|
|
19
|
+
this.logger = getLogger();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Lazily initialise the evaluator (requires async provider creation).
|
|
23
|
+
*/
|
|
24
|
+
async getEvaluator() {
|
|
25
|
+
if (!this.evaluator) {
|
|
26
|
+
const provider = await createLLMProvider();
|
|
27
|
+
this.evaluator = new ScenarioEvaluator(provider);
|
|
28
|
+
}
|
|
29
|
+
return this.evaluator;
|
|
30
|
+
}
|
|
31
|
+
// ── Trainee Creation ────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Create a new training project for an agent trainee.
|
|
34
|
+
*/
|
|
35
|
+
async createTrainee(name, workDir) {
|
|
36
|
+
const slug = `training-${name.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
|
|
37
|
+
// Check for existing project
|
|
38
|
+
const existing = this.engine.getProject(slug);
|
|
39
|
+
if (existing) {
|
|
40
|
+
throw new Error(`Training project already exists: ${slug}`);
|
|
41
|
+
}
|
|
42
|
+
const now = new Date().toISOString();
|
|
43
|
+
const initialProgress = {
|
|
44
|
+
projectSlug: slug,
|
|
45
|
+
currentLevel: "novice",
|
|
46
|
+
passedScenarios: [],
|
|
47
|
+
failedScenarios: [],
|
|
48
|
+
scenarioAttempts: [],
|
|
49
|
+
createdTools: [],
|
|
50
|
+
createdSkills: [],
|
|
51
|
+
graduationStatus: "training",
|
|
52
|
+
startedAt: now,
|
|
53
|
+
totalTokensUsed: 0,
|
|
54
|
+
totalBloops: 0,
|
|
55
|
+
};
|
|
56
|
+
const project = this.engine.createProject({
|
|
57
|
+
name: `Training: ${name}`,
|
|
58
|
+
slug,
|
|
59
|
+
description: `Training sandbox for agent: ${name}`,
|
|
60
|
+
workDir,
|
|
61
|
+
system: false,
|
|
62
|
+
context: {
|
|
63
|
+
isTrainee: true,
|
|
64
|
+
reflectionEnabled: true,
|
|
65
|
+
allowCrossProjectAccess: false,
|
|
66
|
+
trainingProgress: initialProgress,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
this.logger.info("training", `Created trainee project: ${slug}`, { name });
|
|
70
|
+
return project;
|
|
71
|
+
}
|
|
72
|
+
// ── Progress Management ──────────────────────────────────
|
|
73
|
+
/**
|
|
74
|
+
* Read training progress from the project's context.
|
|
75
|
+
*/
|
|
76
|
+
async getProgress(projectSlug) {
|
|
77
|
+
const project = this.engine.getProject(projectSlug);
|
|
78
|
+
if (!project) {
|
|
79
|
+
throw new Error(`Project not found: ${projectSlug}`);
|
|
80
|
+
}
|
|
81
|
+
const rawProgress = project.context?.trainingProgress;
|
|
82
|
+
if (!rawProgress) {
|
|
83
|
+
throw new Error(`Project ${projectSlug} is not a training project`);
|
|
84
|
+
}
|
|
85
|
+
return TrainingProgressSchema.parse(rawProgress);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Persist updated progress to the project context.
|
|
89
|
+
*/
|
|
90
|
+
async updateProgress(projectSlug, progress) {
|
|
91
|
+
const project = this.engine.getProject(projectSlug);
|
|
92
|
+
if (!project) {
|
|
93
|
+
throw new Error(`Project not found: ${projectSlug}`);
|
|
94
|
+
}
|
|
95
|
+
const now = new Date().toISOString();
|
|
96
|
+
const updatedProject = {
|
|
97
|
+
...project,
|
|
98
|
+
context: {
|
|
99
|
+
...project.context,
|
|
100
|
+
trainingProgress: progress,
|
|
101
|
+
},
|
|
102
|
+
updatedAt: now,
|
|
103
|
+
};
|
|
104
|
+
this.db.updateProject(updatedProject);
|
|
105
|
+
this.logger.info("training", `Updated progress for ${projectSlug}`, {
|
|
106
|
+
currentLevel: progress.currentLevel,
|
|
107
|
+
passed: progress.passedScenarios.length,
|
|
108
|
+
graduationStatus: progress.graduationStatus,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// ── Scenario Selection ───────────────────────────────────
|
|
112
|
+
/**
|
|
113
|
+
* Pick the next scenario based on prerequisites and current level.
|
|
114
|
+
* Returns null if no scenarios are available (all done or prerequisites not met).
|
|
115
|
+
*/
|
|
116
|
+
async getNextScenario(projectSlug) {
|
|
117
|
+
const progress = await this.getProgress(projectSlug);
|
|
118
|
+
// Find all scenarios that:
|
|
119
|
+
// 1. Haven't been passed yet
|
|
120
|
+
// 2. Haven't exhausted max attempts
|
|
121
|
+
// 3. Have all prerequisites satisfied
|
|
122
|
+
// 4. Are at the current level or below (allow retrying earlier levels)
|
|
123
|
+
const LEVELS = ["novice", "apprentice", "journeyman", "expert"];
|
|
124
|
+
const currentLevelIdx = LEVELS.indexOf(progress.currentLevel);
|
|
125
|
+
for (const scenario of DEFAULT_CURRICULUM) {
|
|
126
|
+
const scenarioLevelIdx = LEVELS.indexOf(scenario.difficulty);
|
|
127
|
+
// Skip scenarios above current level
|
|
128
|
+
if (scenarioLevelIdx > currentLevelIdx)
|
|
129
|
+
continue;
|
|
130
|
+
// Skip already-passed scenarios
|
|
131
|
+
if (progress.passedScenarios.includes(scenario.id))
|
|
132
|
+
continue;
|
|
133
|
+
// Check max attempts
|
|
134
|
+
const failRecord = progress.failedScenarios.find((f) => f.id === scenario.id);
|
|
135
|
+
if (failRecord && failRecord.attempts >= scenario.maxAttempts)
|
|
136
|
+
continue;
|
|
137
|
+
// Check prerequisites
|
|
138
|
+
const prereqsMet = scenario.prerequisites.every((prereqId) => progress.passedScenarios.includes(prereqId));
|
|
139
|
+
if (!prereqsMet)
|
|
140
|
+
continue;
|
|
141
|
+
return scenario;
|
|
142
|
+
}
|
|
143
|
+
// Try advancing to next level only if current level meets minimum pass rate
|
|
144
|
+
const nextLevelIdx = currentLevelIdx + 1;
|
|
145
|
+
if (nextLevelIdx < LEVELS.length) {
|
|
146
|
+
const currentLevel = LEVELS[currentLevelIdx];
|
|
147
|
+
const currentLevelScenarios = DEFAULT_CURRICULUM.filter((s) => s.difficulty === currentLevel);
|
|
148
|
+
const passedInCurrentLevel = currentLevelScenarios.filter((s) => progress.passedScenarios.includes(s.id)).length;
|
|
149
|
+
const currentPassRate = currentLevelScenarios.length > 0
|
|
150
|
+
? passedInCurrentLevel / currentLevelScenarios.length
|
|
151
|
+
: 0;
|
|
152
|
+
const requiredRate = GRADUATION_CRITERIA.minPassRateByLevel[currentLevel] ?? 0;
|
|
153
|
+
// Only advance if current level meets its graduation pass rate
|
|
154
|
+
if (currentPassRate >= requiredRate) {
|
|
155
|
+
const nextLevel = LEVELS[nextLevelIdx];
|
|
156
|
+
const nextLevelScenarios = DEFAULT_CURRICULUM.filter((s) => s.difficulty === nextLevel);
|
|
157
|
+
for (const scenario of nextLevelScenarios) {
|
|
158
|
+
if (progress.passedScenarios.includes(scenario.id))
|
|
159
|
+
continue;
|
|
160
|
+
const failRecord = progress.failedScenarios.find((f) => f.id === scenario.id);
|
|
161
|
+
if (failRecord && failRecord.attempts >= scenario.maxAttempts)
|
|
162
|
+
continue;
|
|
163
|
+
const prereqsMet = scenario.prerequisites.every((prereqId) => progress.passedScenarios.includes(prereqId));
|
|
164
|
+
if (!prereqsMet)
|
|
165
|
+
continue;
|
|
166
|
+
// Advance level
|
|
167
|
+
progress.currentLevel = nextLevel;
|
|
168
|
+
await this.updateProgress(projectSlug, progress);
|
|
169
|
+
return scenario;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get a specific scenario by ID.
|
|
177
|
+
*/
|
|
178
|
+
getScenario(scenarioId) {
|
|
179
|
+
return DEFAULT_CURRICULUM.find((s) => s.id === scenarioId) ?? null;
|
|
180
|
+
}
|
|
181
|
+
// ── Scenario Execution ───────────────────────────────────
|
|
182
|
+
/**
|
|
183
|
+
* Run a training scenario (or the next available one).
|
|
184
|
+
* Executes the bloop, evaluates the result, updates progress.
|
|
185
|
+
*/
|
|
186
|
+
async runScenario(projectSlug, scenarioId) {
|
|
187
|
+
const progress = await this.getProgress(projectSlug);
|
|
188
|
+
// Resolve which scenario to run
|
|
189
|
+
let scenario = null;
|
|
190
|
+
if (scenarioId) {
|
|
191
|
+
scenario = this.getScenario(scenarioId);
|
|
192
|
+
if (!scenario) {
|
|
193
|
+
throw new Error(`Scenario not found: ${scenarioId}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
scenario = await this.getNextScenario(projectSlug);
|
|
198
|
+
if (!scenario) {
|
|
199
|
+
throw new Error("No scenarios available — all done or prerequisites not met");
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Check attempt count
|
|
203
|
+
const failRecord = progress.failedScenarios.find((f) => f.id === scenario.id);
|
|
204
|
+
const attemptNumber = (failRecord?.attempts ?? 0) + 1;
|
|
205
|
+
if (failRecord && failRecord.attempts >= scenario.maxAttempts) {
|
|
206
|
+
throw new Error(`Scenario ${scenario.id} has reached max attempts (${scenario.maxAttempts})`);
|
|
207
|
+
}
|
|
208
|
+
// Build training context for the bloop
|
|
209
|
+
const extraContext = [
|
|
210
|
+
`--- Training Scenario ---`,
|
|
211
|
+
`Name: ${scenario.name}`,
|
|
212
|
+
`Difficulty: ${scenario.difficulty}`,
|
|
213
|
+
`Category: ${scenario.category}`,
|
|
214
|
+
`This tests: ${scenario.teaches.join(", ")}`,
|
|
215
|
+
`Attempt: ${attemptNumber} of ${scenario.maxAttempts}`,
|
|
216
|
+
scenario.requiredTools.length > 0
|
|
217
|
+
? `Expected tools: ${scenario.requiredTools.join(", ")}`
|
|
218
|
+
: "",
|
|
219
|
+
``,
|
|
220
|
+
`Demonstrate your capability clearly and completely.`,
|
|
221
|
+
`Show your work — use the relevant tools and explain what you are doing.`,
|
|
222
|
+
].filter(Boolean).join("\n");
|
|
223
|
+
this.logger.info("training", `Running scenario: ${scenario.id}`, {
|
|
224
|
+
projectSlug,
|
|
225
|
+
scenarioId: scenario.id,
|
|
226
|
+
attempt: attemptNumber,
|
|
227
|
+
});
|
|
228
|
+
const startTime = Date.now();
|
|
229
|
+
let bloopId = "";
|
|
230
|
+
let bloopResult = "";
|
|
231
|
+
let toolCalls = [];
|
|
232
|
+
let tokensUsed = 0;
|
|
233
|
+
let bloopStatus = "error";
|
|
234
|
+
try {
|
|
235
|
+
const bloop = await this.engine.runBloop({
|
|
236
|
+
projectSlug,
|
|
237
|
+
goal: scenario.goal,
|
|
238
|
+
team: "auto",
|
|
239
|
+
extraContext,
|
|
240
|
+
});
|
|
241
|
+
bloopId = bloop.id;
|
|
242
|
+
tokensUsed = bloop.tokensUsed;
|
|
243
|
+
toolCalls = bloop.toolCalls;
|
|
244
|
+
if (bloop.result) {
|
|
245
|
+
bloopResult = typeof bloop.result === "string"
|
|
246
|
+
? bloop.result
|
|
247
|
+
: JSON.stringify(bloop.result);
|
|
248
|
+
}
|
|
249
|
+
if (bloop.status === "failed") {
|
|
250
|
+
bloopStatus = "error";
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
// Evaluate the result
|
|
254
|
+
const evaluator = await this.getEvaluator();
|
|
255
|
+
const evaluation = await evaluator.evaluate(scenario, bloopResult, toolCalls);
|
|
256
|
+
bloopStatus = evaluation.passed ? "pass" : "fail";
|
|
257
|
+
const attempt = {
|
|
258
|
+
scenarioId: scenario.id,
|
|
259
|
+
bloopId,
|
|
260
|
+
status: bloopStatus,
|
|
261
|
+
score: evaluation.score,
|
|
262
|
+
feedback: evaluation.feedback,
|
|
263
|
+
tokensUsed,
|
|
264
|
+
durationMs: Date.now() - startTime,
|
|
265
|
+
attemptNumber,
|
|
266
|
+
timestamp: new Date().toISOString(),
|
|
267
|
+
};
|
|
268
|
+
// Update progress with this attempt result
|
|
269
|
+
await this.recordAttempt(projectSlug, scenario, attempt, progress);
|
|
270
|
+
this.logger.info("training", `Scenario ${scenario.id}: ${bloopStatus}`, {
|
|
271
|
+
score: evaluation.score,
|
|
272
|
+
feedback: evaluation.feedback.slice(0, 100),
|
|
273
|
+
});
|
|
274
|
+
return attempt;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
this.logger.error("training", `Scenario ${scenario.id} execution failed`, {
|
|
279
|
+
error: err.message,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
// Build a failure/error attempt
|
|
283
|
+
const attempt = {
|
|
284
|
+
scenarioId: scenario.id,
|
|
285
|
+
bloopId: bloopId || "unknown",
|
|
286
|
+
status: bloopStatus,
|
|
287
|
+
score: 0,
|
|
288
|
+
feedback: bloopStatus === "error"
|
|
289
|
+
? "Bloop failed to complete."
|
|
290
|
+
: "Scenario did not meet passing criteria.",
|
|
291
|
+
tokensUsed,
|
|
292
|
+
durationMs: Date.now() - startTime,
|
|
293
|
+
attemptNumber,
|
|
294
|
+
timestamp: new Date().toISOString(),
|
|
295
|
+
};
|
|
296
|
+
await this.recordAttempt(projectSlug, scenario, attempt, progress);
|
|
297
|
+
return attempt;
|
|
298
|
+
}
|
|
299
|
+
// ── Graduation ───────────────────────────────────────────
|
|
300
|
+
/**
|
|
301
|
+
* Check if the trainee meets graduation criteria.
|
|
302
|
+
* Updates graduation status if criteria are met.
|
|
303
|
+
*/
|
|
304
|
+
async checkGraduation(projectSlug) {
|
|
305
|
+
const progress = await this.getProgress(projectSlug);
|
|
306
|
+
if (progress.graduationStatus === "graduated")
|
|
307
|
+
return true;
|
|
308
|
+
const LEVELS = ["novice", "apprentice", "journeyman", "expert"];
|
|
309
|
+
const criteria = GRADUATION_CRITERIA;
|
|
310
|
+
// Check required scenarios
|
|
311
|
+
for (const reqId of criteria.requiredScenarioIds) {
|
|
312
|
+
if (!progress.passedScenarios.includes(reqId)) {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// Check pass rate per level
|
|
317
|
+
for (const level of LEVELS) {
|
|
318
|
+
const minRate = criteria.minPassRateByLevel[level] ?? 0;
|
|
319
|
+
if (minRate === 0)
|
|
320
|
+
continue;
|
|
321
|
+
const levelScenarios = DEFAULT_CURRICULUM.filter((s) => s.difficulty === level);
|
|
322
|
+
if (levelScenarios.length === 0)
|
|
323
|
+
continue;
|
|
324
|
+
const passedInLevel = levelScenarios.filter((s) => progress.passedScenarios.includes(s.id)).length;
|
|
325
|
+
const passRate = passedInLevel / levelScenarios.length;
|
|
326
|
+
if (passRate < minRate)
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
// Check tools and skills
|
|
330
|
+
if (progress.createdTools.length < criteria.minToolsCreated)
|
|
331
|
+
return false;
|
|
332
|
+
if (progress.createdSkills.length < criteria.minSkillsCreated)
|
|
333
|
+
return false;
|
|
334
|
+
// Graduate!
|
|
335
|
+
progress.graduationStatus = "graduated";
|
|
336
|
+
progress.graduatedAt = new Date().toISOString();
|
|
337
|
+
await this.updateProgress(projectSlug, progress);
|
|
338
|
+
this.logger.info("training", `Agent graduated: ${projectSlug}`, {
|
|
339
|
+
passedScenarios: progress.passedScenarios.length,
|
|
340
|
+
totalTokens: progress.totalTokensUsed,
|
|
341
|
+
});
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
// ── Status ───────────────────────────────────────────────
|
|
345
|
+
/**
|
|
346
|
+
* Get a human-readable status summary for a training project.
|
|
347
|
+
*/
|
|
348
|
+
async getStatus(projectSlug) {
|
|
349
|
+
const progress = await this.getProgress(projectSlug);
|
|
350
|
+
const nextScenario = await this.getNextScenario(projectSlug);
|
|
351
|
+
const LEVELS = ["novice", "apprentice", "journeyman", "expert"];
|
|
352
|
+
const lines = [
|
|
353
|
+
`Training Status: ${projectSlug}`,
|
|
354
|
+
`Graduation: ${progress.graduationStatus}`,
|
|
355
|
+
`Current Level: ${progress.currentLevel}`,
|
|
356
|
+
``,
|
|
357
|
+
`Progress by Level:`,
|
|
358
|
+
];
|
|
359
|
+
for (const level of LEVELS) {
|
|
360
|
+
const levelScenarios = DEFAULT_CURRICULUM.filter((s) => s.difficulty === level);
|
|
361
|
+
const passed = levelScenarios.filter((s) => progress.passedScenarios.includes(s.id));
|
|
362
|
+
const minRate = GRADUATION_CRITERIA.minPassRateByLevel[level] ?? 0;
|
|
363
|
+
const required = Math.ceil(levelScenarios.length * minRate);
|
|
364
|
+
lines.push(` ${level}: ${passed.length}/${levelScenarios.length} passed (need ${required})`);
|
|
365
|
+
}
|
|
366
|
+
lines.push(``, `Total Bloops: ${progress.totalBloops}`);
|
|
367
|
+
lines.push(`Total Tokens: ${progress.totalTokensUsed.toLocaleString()}`);
|
|
368
|
+
if (nextScenario) {
|
|
369
|
+
lines.push(``, `Next Scenario: ${nextScenario.name} (${nextScenario.difficulty})`);
|
|
370
|
+
lines.push(` Category: ${nextScenario.category}`);
|
|
371
|
+
lines.push(` Tests: ${nextScenario.teaches.slice(0, 3).join(", ")}`);
|
|
372
|
+
}
|
|
373
|
+
else if (progress.graduationStatus === "training") {
|
|
374
|
+
lines.push(``, `No more scenarios available — check prerequisites or max attempts.`);
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
lines.push(``, `Graduation complete!`);
|
|
378
|
+
}
|
|
379
|
+
return {
|
|
380
|
+
progress,
|
|
381
|
+
nextScenario,
|
|
382
|
+
summary: lines.join("\n"),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
// ── Internal ─────────────────────────────────────────────
|
|
386
|
+
async recordAttempt(projectSlug, scenario, attempt, progress) {
|
|
387
|
+
// Add attempt to history
|
|
388
|
+
progress.scenarioAttempts.push(attempt);
|
|
389
|
+
progress.totalBloops += 1;
|
|
390
|
+
progress.totalTokensUsed += attempt.tokensUsed;
|
|
391
|
+
if (attempt.status === "pass") {
|
|
392
|
+
// Add to passed list (avoid duplicates)
|
|
393
|
+
if (!progress.passedScenarios.includes(scenario.id)) {
|
|
394
|
+
progress.passedScenarios.push(scenario.id);
|
|
395
|
+
}
|
|
396
|
+
// Remove from failed list if present
|
|
397
|
+
progress.failedScenarios = progress.failedScenarios.filter((f) => f.id !== scenario.id);
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
// Increment failed attempt counter
|
|
401
|
+
const failRecord = progress.failedScenarios.find((f) => f.id === scenario.id);
|
|
402
|
+
if (failRecord) {
|
|
403
|
+
failRecord.attempts += 1;
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
progress.failedScenarios.push({ id: scenario.id, attempts: 1 });
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
await this.updateProgress(projectSlug, progress);
|
|
410
|
+
// Check graduation after each successful attempt
|
|
411
|
+
if (attempt.status === "pass") {
|
|
412
|
+
await this.checkGraduation(projectSlug);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
//# sourceMappingURL=sandbox-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-manager.js","sourceRoot":"","sources":["../../src/training/sandbox-manager.ts"],"names":[],"mappings":"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"}
|