-
Notifications
You must be signed in to change notification settings - Fork 0
Sentinel LoRA training + RAG budget fix + fallback elimination #270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3b8ad61
868c73a
9887bcf
896b1f3
a092095
d6120be
06c686b
81ad574
bce6f16
2121127
e05e05d
8240605
5328e8f
ec0a33d
f600a43
2946f9c
db18c28
815b40c
adf74b7
5cac1cf
5402cc7
5494203
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -34,14 +34,11 @@ export interface AIGenerateParams extends CommandParams { | |||||||||||
| // Preview mode - returns request instead of calling LLM | ||||||||||||
| preview?: boolean; | ||||||||||||
|
|
||||||||||||
| // Model configuration | ||||||||||||
| model?: string; | ||||||||||||
| // Model configuration — required for RAG budget and inference routing | ||||||||||||
| model: string; | ||||||||||||
| provider: 'openai' | 'anthropic' | 'local' | 'candle' | 'groq' | 'deepseek'; | ||||||||||||
|
Comment on lines
+38
to
+39
|
||||||||||||
| model: string; | |
| provider: 'openai' | 'anthropic' | 'local' | 'candle' | 'groq' | 'deepseek'; | |
| // May be omitted by callers that rely on defaults inferred from context. | |
| model?: string; | |
| provider?: 'openai' | 'anthropic' | 'local' | 'candle' | 'groq' | 'deepseek'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| # Genome Academy Competition Command | ||
|
|
||
| Launches a multi-persona competition: 1 shared teacher sentinel generates a curriculum, N student sentinels compete on the same exam questions. Rankings computed from exam scores across all topics. | ||
|
|
||
| ## Table of Contents | ||
|
|
||
| - [Usage](#usage) | ||
| - [CLI Usage](#cli-usage) | ||
| - [Tool Usage](#tool-usage) | ||
| - [Parameters](#parameters) | ||
| - [Result](#result) | ||
| - [Examples](#examples) | ||
| - [Architecture](#architecture) | ||
| - [Testing](#testing) | ||
| - [Getting Help](#getting-help) | ||
| - [Access Level](#access-level) | ||
| - [Implementation Notes](#implementation-notes) | ||
|
|
||
| ## Usage | ||
|
|
||
| ### CLI Usage | ||
|
|
||
| ```bash | ||
| ./jtag genome/academy-competition --skill="typescript-generics" --competitors='[{"personaId":"<uuid1>","personaName":"Helper AI"},{"personaId":"<uuid2>","personaName":"Code Tutor"}]' | ||
| ``` | ||
|
|
||
| ### Tool Usage | ||
|
|
||
| ```typescript | ||
| import { GenomeAcademyCompetition } from '@commands/genome/academy-competition/shared/GenomeAcademyCompetitionTypes'; | ||
|
|
||
| const result = await GenomeAcademyCompetition.execute({ | ||
| skill: 'typescript-generics', | ||
| competitors: [ | ||
| { personaId: '<uuid1>', personaName: 'Helper AI' }, | ||
| { personaId: '<uuid2>', personaName: 'Code Tutor' }, | ||
| ], | ||
| baseModel: 'smollm2:135m', | ||
| passingScore: 70, | ||
| }); | ||
| ``` | ||
|
|
||
| ## Parameters | ||
|
|
||
| - **skill** (required): `string` - Skill to compete on (e.g., "typescript-generics") | ||
| - **competitors** (required): `CompetitorDef[]` - Array of competitors (minimum 2), each with `personaId` and `personaName` | ||
| - **baseModel** (optional): `string` - Base model for training (default: "smollm2:135m") | ||
| - **maxTopicAttempts** (optional): `number` - Maximum attempts per topic before failure (default: 3) | ||
| - **passingScore** (optional): `number` - Score required to pass exams, 0-100 (default: 70) | ||
| - **epochs** (optional): `number` - Training epochs per round (default: 3) | ||
| - **rank** (optional): `number` - LoRA rank (default: 32) | ||
| - **tournamentRounds** (optional): `number` - Number of tournament rounds (default: 1) | ||
| - **model** (optional): `string` - Teacher LLM model | ||
| - **provider** (optional): `string` - Teacher LLM provider | ||
|
|
||
| ## Result | ||
|
|
||
| Returns `GenomeAcademyCompetitionResult` with: | ||
|
|
||
| - **success**: `boolean` - Whether competition was created and sentinels spawned | ||
| - **competitionId**: `UUID` - The created competition entity ID | ||
| - **teacherHandle**: `string` - Sentinel handle for the shared teacher pipeline | ||
| - **competitorHandles**: `CompetitorHandle[]` - Per-competitor handles with `personaId`, `personaName`, `studentHandle`, `sessionId` | ||
| - **error**: `string` (optional) - Error message if failed | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Two-persona competition | ||
|
|
||
| ```bash | ||
| ./jtag genome/academy-competition \ | ||
| --skill="typescript-generics" \ | ||
| --competitors='[{"personaId":"00000000-0000-0000-0000-000000000002","personaName":"Helper AI"},{"personaId":"00000000-0000-0000-0000-000000000003","personaName":"Code Tutor"}]' | ||
| ``` | ||
|
|
||
| ### Track competition progress | ||
|
|
||
| ```bash | ||
| # Check teacher | ||
| ./jtag sentinel/status --handle="<teacherHandle>" | ||
|
|
||
| # Check each student | ||
| ./jtag sentinel/status --handle="<studentHandle1>" | ||
| ./jtag sentinel/status --handle="<studentHandle2>" | ||
|
|
||
| # View competition entity | ||
| ./jtag data/read --collection="competitions" --id="<competitionId>" | ||
| ``` | ||
|
|
||
| ## Architecture | ||
|
|
||
| Extends the Academy Dojo dual-sentinel pattern to N students: | ||
|
|
||
| ``` | ||
| 1 Teacher Sentinel (shared) | ||
| | | ||
| +---> Student Sentinel 1 (persona A) | ||
| +---> Student Sentinel 2 (persona B) | ||
| +---> Student Sentinel N (persona N) | ||
| ``` | ||
|
|
||
| All students receive the same curriculum and exam questions from the shared teacher. Each trains independently. Rankings are computed from exam scores. | ||
|
|
||
| See `docs/personas/ACADEMY-DOJO-ARCHITECTURE.md` for full design. | ||
|
|
||
| ## Testing | ||
|
|
||
| ```bash | ||
| # Unit tests | ||
| npx vitest run tests/unit/semantic-cognition.test.ts | ||
|
|
||
| # Integration tests (requires running server + Rust sentinel engine) | ||
| npm start | ||
| npx vitest run tests/integration/sentinel-lora-training.test.ts | ||
| ``` | ||
|
|
||
| ## Getting Help | ||
|
|
||
| ```bash | ||
| ./jtag help genome/academy-competition | ||
| ./jtag readme genome/academy-competition | ||
| ``` | ||
|
|
||
| ## Access Level | ||
|
|
||
| **ai-safe** - Safe for AI personas to call autonomously. | ||
|
|
||
| ## Implementation Notes | ||
|
|
||
| - **Shared Logic**: `shared/GenomeAcademyCompetitionTypes.ts` | ||
| - **Browser**: `browser/GenomeAcademyCompetitionBrowserCommand.ts` | ||
| - **Server**: `server/GenomeAcademyCompetitionServerCommand.ts` | ||
| - Entities: `CompetitionEntity` (collection: `competitions`) | ||
| - Per-competitor `AcademySessionEntity` for independent training tracking | ||
| - Events share competition ID as session scope for teacher broadcasts |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| /** | ||
| * Genome Academy Competition Command - Browser Implementation | ||
| * | ||
| * Delegates to server for competition orchestration. | ||
| */ | ||
|
|
||
| import { CommandBase, type ICommandDaemon } from '@daemons/command-daemon/shared/CommandBase'; | ||
| import type { JTAGContext } from '@system/core/types/JTAGTypes'; | ||
| import type { GenomeAcademyCompetitionParams, GenomeAcademyCompetitionResult } from '../shared/GenomeAcademyCompetitionTypes'; | ||
|
|
||
| export class GenomeAcademyCompetitionBrowserCommand extends CommandBase<GenomeAcademyCompetitionParams, GenomeAcademyCompetitionResult> { | ||
|
|
||
| constructor(context: JTAGContext, subpath: string, commander: ICommandDaemon) { | ||
| super('genome/academy-competition', context, subpath, commander); | ||
| } | ||
|
|
||
| async execute(params: GenomeAcademyCompetitionParams): Promise<GenomeAcademyCompetitionResult> { | ||
| console.log('🌐 BROWSER: Delegating Genome Academy Competition to server'); | ||
| return await this.remoteExecute(params); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| { | ||
| "name": "@jtag-commands/genome/academy-competition", | ||
| "version": "1.0.0", | ||
| "description": "Launch a multi-persona Academy competition — 1 teacher sentinel + N student sentinels competing on the same curriculum", | ||
| "main": "server/GenomeAcademyCompetitionServerCommand.ts", | ||
| "types": "shared/GenomeAcademyCompetitionTypes.ts", | ||
| "scripts": { | ||
| "test": "npm run test:unit && npm run test:integration", | ||
| "test:unit": "npx vitest run test/unit/*.test.ts", | ||
| "test:integration": "npx tsx test/integration/GenomeAcademyCompetitionIntegration.test.ts", | ||
| "lint": "npx eslint **/*.ts", | ||
| "typecheck": "npx tsc --noEmit" | ||
| }, | ||
| "peerDependencies": { | ||
| "@jtag/core": "*" | ||
| }, | ||
| "files": [ | ||
| "shared/**/*.ts", | ||
| "browser/**/*.ts", | ||
| "server/**/*.ts", | ||
| "test/**/*.ts", | ||
| "README.md" | ||
| ], | ||
| "keywords": [ | ||
| "jtag", | ||
| "command", | ||
| "genome/academy-competition" | ||
| ], | ||
| "license": "MIT", | ||
| "author": "", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "" | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deleting params.timeout after extraction could cause issues if the command legitimately expects a timeout parameter. Consider using a different naming convention (e.g., --cli-timeout) to avoid conflicts.