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.
Files changed (91) hide show
  1. package/README.md +60 -10
  2. package/dist/chat/index.d.ts +3 -3
  3. package/dist/chat/index.d.ts.map +1 -1
  4. package/dist/chat/index.js +4 -4
  5. package/dist/chat/index.js.map +1 -1
  6. package/dist/chat/intent.d.ts +2 -2
  7. package/dist/chat/intent.d.ts.map +1 -1
  8. package/dist/chat/intent.js +7 -7
  9. package/dist/chat/intent.js.map +1 -1
  10. package/dist/cli.js +269 -23
  11. package/dist/cli.js.map +1 -1
  12. package/dist/config.d.ts +12 -0
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +9 -0
  15. package/dist/config.js.map +1 -1
  16. package/dist/core/gatekeeper.d.ts +3 -3
  17. package/dist/core/gatekeeper.d.ts.map +1 -1
  18. package/dist/core/gatekeeper.js +12 -12
  19. package/dist/core/gatekeeper.js.map +1 -1
  20. package/dist/core/reflection.d.ts +3 -3
  21. package/dist/core/reflection.d.ts.map +1 -1
  22. package/dist/core/reflection.js +10 -10
  23. package/dist/core/reflection.js.map +1 -1
  24. package/dist/core/roles.js +1 -1
  25. package/dist/core/roles.js.map +1 -1
  26. package/dist/core/runner.d.ts +3 -3
  27. package/dist/core/runner.d.ts.map +1 -1
  28. package/dist/core/runner.js +12 -14
  29. package/dist/core/runner.js.map +1 -1
  30. package/dist/events/daemon.js +3 -3
  31. package/dist/events/daemon.js.map +1 -1
  32. package/dist/index.d.ts +30 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +50 -5
  35. package/dist/index.js.map +1 -1
  36. package/dist/providers/anthropic.d.ts +8 -0
  37. package/dist/providers/anthropic.d.ts.map +1 -0
  38. package/dist/providers/anthropic.js +70 -0
  39. package/dist/providers/anthropic.js.map +1 -0
  40. package/dist/providers/factory.d.ts +3 -0
  41. package/dist/providers/factory.d.ts.map +1 -0
  42. package/dist/providers/factory.js +58 -0
  43. package/dist/providers/factory.js.map +1 -0
  44. package/dist/providers/index.d.ts +5 -0
  45. package/dist/providers/index.d.ts.map +1 -0
  46. package/dist/providers/index.js +4 -0
  47. package/dist/providers/index.js.map +1 -0
  48. package/dist/providers/openai.d.ts +16 -0
  49. package/dist/providers/openai.d.ts.map +1 -0
  50. package/dist/providers/openai.js +176 -0
  51. package/dist/providers/openai.js.map +1 -0
  52. package/dist/providers/types.d.ts +54 -0
  53. package/dist/providers/types.d.ts.map +1 -0
  54. package/dist/providers/types.js +4 -0
  55. package/dist/providers/types.js.map +1 -0
  56. package/dist/skills/index.d.ts.map +1 -1
  57. package/dist/skills/index.js +44 -0
  58. package/dist/skills/index.js.map +1 -1
  59. package/dist/tools/builtin/email.d.ts +5 -0
  60. package/dist/tools/builtin/email.d.ts.map +1 -0
  61. package/dist/tools/builtin/email.js +171 -0
  62. package/dist/tools/builtin/email.js.map +1 -0
  63. package/dist/tools/registry.d.ts +3 -12
  64. package/dist/tools/registry.d.ts.map +1 -1
  65. package/dist/tools/registry.js +3 -3
  66. package/dist/tools/registry.js.map +1 -1
  67. package/dist/training/curriculum.d.ts +4 -0
  68. package/dist/training/curriculum.d.ts.map +1 -0
  69. package/dist/training/curriculum.js +512 -0
  70. package/dist/training/curriculum.js.map +1 -0
  71. package/dist/training/evaluator.d.ts +21 -0
  72. package/dist/training/evaluator.d.ts.map +1 -0
  73. package/dist/training/evaluator.js +163 -0
  74. package/dist/training/evaluator.js.map +1 -0
  75. package/dist/training/exporter.d.ts +35 -0
  76. package/dist/training/exporter.d.ts.map +1 -0
  77. package/dist/training/exporter.js +377 -0
  78. package/dist/training/exporter.js.map +1 -0
  79. package/dist/training/index.d.ts +5 -0
  80. package/dist/training/index.d.ts.map +1 -0
  81. package/dist/training/index.js +5 -0
  82. package/dist/training/index.js.map +1 -0
  83. package/dist/training/sandbox-manager.d.ts +58 -0
  84. package/dist/training/sandbox-manager.d.ts.map +1 -0
  85. package/dist/training/sandbox-manager.js +416 -0
  86. package/dist/training/sandbox-manager.js.map +1 -0
  87. package/dist/training/types.d.ts +790 -0
  88. package/dist/training/types.d.ts.map +1 -0
  89. package/dist/training/types.js +154 -0
  90. package/dist/training/types.js.map +1 -0
  91. 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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"}