@holoscript/framework 6.0.3 → 6.0.4
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/CHANGELOG.md +1 -2
- package/ROADMAP.md +68 -66
- package/dist/{InvisibleWallet-BB6tFvRA.d.cts → InvisibleWallet-EFiuaLn3.d.cts} +1 -1
- package/dist/{OrchestratorAgent-BvWgf9uw.d.cts → OrchestratorAgent-CrLDGNL6.d.cts} +1 -1
- package/dist/agents/index.cjs +11 -10
- package/dist/agents/index.d.cts +4 -16
- package/dist/ai/index.cjs +2 -2
- package/dist/behavior.cjs +10 -0
- package/dist/economy/index.cjs +4 -4
- package/dist/economy/index.d.cts +2 -2
- package/dist/index.cjs +33 -11
- package/dist/index.d.cts +3 -3
- package/dist/swarm/index.cjs +3 -0
- package/package.json +14 -9
- package/src/__tests__/bounty-marketplace.test.ts +53 -21
- package/src/__tests__/delegation.test.ts +1 -4
- package/src/__tests__/done-log-audit.test.ts +38 -46
- package/src/__tests__/framework.test.ts +172 -53
- package/src/__tests__/goal-synthesizer.test.ts +9 -6
- package/src/__tests__/presence.test.ts +1 -1
- package/src/__tests__/protocol-agent.test.ts +12 -11
- package/src/__tests__/revenue-splitter.test.ts +22 -15
- package/src/__tests__/scenario-driven-todo.test.ts +55 -35
- package/src/__tests__/self-improve.test.ts +28 -9
- package/src/__tests__/service-lifecycle.test.ts +9 -3
- package/src/__tests__/skill-router.test.ts +3 -3
- package/src/agents/CulturalMemory.ts +6 -6
- package/src/agents/DelegationTraceHooks.ts +560 -0
- package/src/agents/FederatedRegistryAdapter.ts +1 -1
- package/src/agents/NormEngine.ts +3 -8
- package/src/agents/OrchestratorAgent.ts +1 -1
- package/src/agents/TaskDelegationService.ts +5 -9
- package/src/agents/__tests__/AgentWalletRegistry.test.ts +5 -4
- package/src/agents/__tests__/CrossRealityHandoff.test.ts +9 -3
- package/src/agents/__tests__/DelegationTraceHooks.test.ts +390 -0
- package/src/agents/__tests__/TaskDelegationService.test.ts +4 -2
- package/src/agents/spatial-comms/Layer1RealTime.ts +36 -19
- package/src/agents/spatial-comms/Layer2A2A.ts +1 -3
- package/src/agents/spatial-comms/Layer3MCP.ts +13 -4
- package/src/agents/spatial-comms/ProtocolTypes.ts +5 -2
- package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +2 -2
- package/src/ai/HoloScriptGenerator.ts +2 -2
- package/src/ai/__tests__/PerceptionSystem.prod.test.ts +1 -1
- package/src/ai/__tests__/PerceptionSystem.test.ts +14 -14
- package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +1 -1
- package/src/ai/index.ts +5 -1
- package/src/board/audit.ts +17 -6
- package/src/board/board-ops.ts +45 -15
- package/src/board/board-types.ts +94 -20
- package/src/delegation.ts +5 -3
- package/src/distributed-claimer.ts +13 -2
- package/src/economy/BountyManager.ts +40 -18
- package/src/economy/KnowledgeMarketplace.ts +27 -8
- package/src/economy/PaymentWebhookService.ts +0 -1
- package/src/economy/RevenueSplitter.ts +2 -4
- package/src/economy/UnifiedBudgetOptimizer.ts +8 -9
- package/src/economy/_core-stubs.ts +1 -1
- package/src/economy/x402-facilitator.ts +17 -8
- package/src/index.ts +16 -12
- package/src/knowledge/__tests__/knowledge-consolidator.test.ts +138 -89
- package/src/knowledge/__tests__/knowledge-store-vector.test.ts +59 -16
- package/src/knowledge/brain.ts +7 -7
- package/src/knowledge/consolidation.ts +16 -16
- package/src/knowledge/knowledge-consolidator.ts +60 -30
- package/src/knowledge/knowledge-store.ts +83 -45
- package/src/learning/ProceduralCompiler.ts +6 -1
- package/src/learning/learning/MemoryConsolidator.ts +102 -0
- package/src/learning/learning/MemoryScorer.ts +69 -0
- package/src/learning/learning/ProceduralCompiler.ts +45 -0
- package/src/learning/learning/SemanticClusterer.ts +66 -0
- package/src/llm/llm-adapter.ts +24 -10
- package/src/mesh/index.ts +37 -17
- package/src/protocol/goal-synthesizer.ts +24 -34
- package/src/protocol/implementations.ts +91 -22
- package/src/protocol/micro-phase-decomposer.ts +25 -17
- package/src/protocol/micro-step-decomposer.test.ts +104 -39
- package/src/protocol-agent.test.ts +17 -7
- package/src/protocol-agent.ts +45 -42
- package/src/self-improve/absorb-scanner.ts +9 -6
- package/src/self-improve/evolution-engine.ts +36 -18
- package/src/self-improve/framework-absorber.ts +21 -16
- package/src/self-improve/index.ts +2 -10
- package/src/self-improve/prompt-optimizer.ts +31 -19
- package/src/self-improve/test-generator.ts +16 -12
- package/src/skill-router.ts +7 -6
- package/src/swarm/messaging/GossipProtocol.ts +1 -1
- package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +31 -9
- package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +21 -7
- package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +24 -8
- package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +6 -2
- package/src/team.ts +277 -122
- package/src/training/scripts/generate-spatial-dataset.ts +1 -1
- package/src/training/training/LRScheduler.ts +377 -0
- package/src/training/training/QualityScoringPipeline.ts +139 -0
- package/src/training/training/SoftDedup.ts +461 -0
- package/src/training/training/SparsityMonitor.ts +685 -0
- package/src/training/training/SparsityMonitorTypes.ts +209 -0
- package/src/training/training/SpatialTrainingDataGenerator.ts +1526 -0
- package/src/training/training/SpatialTrainingDataTypes.ts +216 -0
- package/src/training/training/TrainingPipelineConfig.ts +215 -0
- package/src/training/training/__tests__/CorpusValidation.test.ts +87 -0
- package/src/training/training/__tests__/LRScheduler.test.ts +592 -0
- package/src/training/training/__tests__/SoftDedup.test.ts +415 -0
- package/src/training/training/__tests__/SparsityMonitor.test.ts +1623 -0
- package/src/training/training/__tests__/SpatialCorpusValidation.test.ts +72 -0
- package/src/training/training/__tests__/SpatialTrainingDataGenerator.test.ts +1244 -0
- package/src/training/training/__tests__/TrainingMonkeyIntegration.test.ts +897 -0
- package/src/training/training/__tests__/TrainingPipelineConfig.test.ts +202 -0
- package/src/training/training/__tests__/schema.test.ts +72 -0
- package/src/training/training/__tests__/training-constants.test.ts +106 -0
- package/src/training/training/__tests__/trait-mappings.test.ts +81 -0
- package/src/training/training/constants.ts +94 -0
- package/src/training/training/index.ts +17 -0
- package/src/training/training/schema.ts +147 -0
- package/src/training/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
- package/src/training/training/scripts/generate-spatial-dataset.ts +521 -0
- package/src/training/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
- package/src/training/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
- package/src/training/training/trainingmonkey/index.ts +26 -0
- package/src/training/training/trait-mappings.ts +157 -0
- package/src/types.ts +2 -7
- package/ALL-test-results.json +0 -1
- package/LICENSE +0 -21
- package/dist/AgentManifest-CB4xM-Ma.d.ts +0 -704
- package/dist/BehaviorTree-BrBFECv5.d.ts +0 -103
- package/dist/InvisibleWallet-rtRrBOA8.d.ts +0 -1732
- package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +0 -798
- package/dist/agents/index.d.ts +0 -1788
- package/dist/agents/index.js +0 -4695
- package/dist/ai/index.d.ts +0 -1753
- package/dist/ai/index.js +0 -5244
- package/dist/behavior.d.ts +0 -130
- package/dist/behavior.js +0 -407
- package/dist/economy/index.d.ts +0 -747
- package/dist/economy/index.js +0 -3617
- package/dist/implementations-D9T3un9D.d.ts +0 -236
- package/dist/index.d.ts +0 -1729
- package/dist/index.js +0 -24277
- package/dist/learning/index.d.ts +0 -104
- package/dist/learning/index.js +0 -189
- package/dist/negotiation/index.d.ts +0 -610
- package/dist/negotiation/index.js +0 -931
- package/dist/skills/index.d.ts +0 -289
- package/dist/skills/index.js +0 -1079
- package/dist/swarm/index.d.ts +0 -2433
- package/dist/swarm/index.js +0 -5221
- package/dist/training/index.d.ts +0 -1734
- package/dist/training/index.js +0 -2687
- package/extract-failures.js +0 -10
- package/src/training/training/data/novel-use-cases.jsonl +0 -153
- package/src/training/training/data/spatial-reasoning-10k.jsonl +0 -9354
- package/src/types/core-stubs.d.ts +0 -113
- package/test-output.txt +0 -0
- package/test-result.json +0 -1
- package/tsc-errors.txt +0 -4
- package/tsc_output.txt +0 -0
- package/typescript-errors-2.txt +0 -0
- package/typescript-errors.txt +0 -22
- package/vitest-log-utf8.txt +0 -268
- package/vitest-log.txt +0 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_TRAINING_PIPELINE_CONFIG,
|
|
4
|
+
buildTrainingPipelineConfig,
|
|
5
|
+
computeTotalSteps,
|
|
6
|
+
} from '../TrainingPipelineConfig';
|
|
7
|
+
import type { TrainingPipelineConfig } from '../TrainingPipelineConfig';
|
|
8
|
+
import { DEFAULT_SOFTDEDUP_CONFIG } from '../SoftDedup';
|
|
9
|
+
import { DEFAULT_LR_SCHEDULER_CONFIG } from '../LRScheduler';
|
|
10
|
+
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// TESTS
|
|
13
|
+
// =============================================================================
|
|
14
|
+
|
|
15
|
+
describe('TrainingPipelineConfig', () => {
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// DEFAULT CONFIG
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
describe('DEFAULT_TRAINING_PIPELINE_CONFIG', () => {
|
|
21
|
+
it('has correct hyperparameters per W.006', () => {
|
|
22
|
+
const { hyperparameters } = DEFAULT_TRAINING_PIPELINE_CONFIG;
|
|
23
|
+
|
|
24
|
+
expect(hyperparameters.learningRate).toBe(2e-4); // NOT 2e-5
|
|
25
|
+
expect(hyperparameters.epochs).toBe(2); // NOT 3
|
|
26
|
+
expect(hyperparameters.optimizer).toBe('paged_adamw_8bit'); // NOT adamw_torch
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('has correct batch settings per W.007', () => {
|
|
30
|
+
const { hyperparameters } = DEFAULT_TRAINING_PIPELINE_CONFIG;
|
|
31
|
+
|
|
32
|
+
expect(hyperparameters.microBatchSize).toBe(8);
|
|
33
|
+
expect(hyperparameters.gradientAccumulationSteps).toBe(4);
|
|
34
|
+
// Effective batch = 8 * 4 = 32 (in range 32-512)
|
|
35
|
+
const effectiveBatch =
|
|
36
|
+
hyperparameters.microBatchSize * hyperparameters.gradientAccumulationSteps;
|
|
37
|
+
expect(effectiveBatch).toBeGreaterThanOrEqual(32);
|
|
38
|
+
expect(effectiveBatch).toBeLessThanOrEqual(512);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('includes SoftDedup defaults (W.008)', () => {
|
|
42
|
+
expect(DEFAULT_TRAINING_PIPELINE_CONFIG.softDedup).toEqual(DEFAULT_SOFTDEDUP_CONFIG);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('includes LR schedule defaults (W.009)', () => {
|
|
46
|
+
expect(DEFAULT_TRAINING_PIPELINE_CONFIG.lrSchedule).toEqual(DEFAULT_LR_SCHEDULER_CONFIG);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('enables all pipeline stages by default', () => {
|
|
50
|
+
const { pipeline } = DEFAULT_TRAINING_PIPELINE_CONFIG;
|
|
51
|
+
|
|
52
|
+
expect(pipeline.enableQualityFilter).toBe(true);
|
|
53
|
+
expect(pipeline.enableSoftDedup).toBe(true);
|
|
54
|
+
expect(pipeline.enableLRSchedule).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// BUILD CONFIG
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
describe('buildTrainingPipelineConfig', () => {
|
|
63
|
+
it('returns defaults with no overrides', () => {
|
|
64
|
+
const config = buildTrainingPipelineConfig();
|
|
65
|
+
expect(config.hyperparameters.learningRate).toBe(
|
|
66
|
+
DEFAULT_TRAINING_PIPELINE_CONFIG.hyperparameters.learningRate
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('allows overriding hyperparameters', () => {
|
|
71
|
+
const config = buildTrainingPipelineConfig({
|
|
72
|
+
hyperparameters: { learningRate: 1e-4, epochs: 3 },
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
expect(config.hyperparameters.learningRate).toBe(1e-4);
|
|
76
|
+
expect(config.hyperparameters.epochs).toBe(3);
|
|
77
|
+
expect(config.hyperparameters.optimizer).toBe('paged_adamw_8bit'); // preserved
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('allows overriding softDedup settings', () => {
|
|
81
|
+
const config = buildTrainingPipelineConfig({
|
|
82
|
+
softDedup: { temperature: 0.5, wordLevel: true },
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(config.softDedup.temperature).toBe(0.5);
|
|
86
|
+
expect(config.softDedup.wordLevel).toBe(true);
|
|
87
|
+
expect(config.softDedup.minWeight).toBe(DEFAULT_SOFTDEDUP_CONFIG.minWeight); // preserved
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('allows overriding lrSchedule settings', () => {
|
|
91
|
+
const config = buildTrainingPipelineConfig({
|
|
92
|
+
lrSchedule: { totalSteps: 5000, warmupRatio: 0.05 },
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
expect(config.lrSchedule.totalSteps).toBe(5000);
|
|
96
|
+
expect(config.lrSchedule.warmupRatio).toBe(0.05);
|
|
97
|
+
expect(config.lrSchedule.baseLR).toBe(DEFAULT_LR_SCHEDULER_CONFIG.baseLR); // preserved
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('allows disabling pipeline stages', () => {
|
|
101
|
+
const config = buildTrainingPipelineConfig({
|
|
102
|
+
pipeline: {
|
|
103
|
+
enableQualityFilter: false,
|
|
104
|
+
enableSoftDedup: false,
|
|
105
|
+
enableLRSchedule: false,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
expect(config.pipeline.enableQualityFilter).toBe(false);
|
|
110
|
+
expect(config.pipeline.enableSoftDedup).toBe(false);
|
|
111
|
+
expect(config.pipeline.enableLRSchedule).toBe(false);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('does not mutate the default config', () => {
|
|
115
|
+
const originalLR = DEFAULT_TRAINING_PIPELINE_CONFIG.hyperparameters.learningRate;
|
|
116
|
+
buildTrainingPipelineConfig({
|
|
117
|
+
hyperparameters: { learningRate: 999 },
|
|
118
|
+
});
|
|
119
|
+
expect(DEFAULT_TRAINING_PIPELINE_CONFIG.hyperparameters.learningRate).toBe(originalLR);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// COMPUTE TOTAL STEPS
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
|
|
127
|
+
describe('computeTotalSteps', () => {
|
|
128
|
+
it('computes correct steps for standard config', () => {
|
|
129
|
+
const config = buildTrainingPipelineConfig();
|
|
130
|
+
// Dataset: 920K, microBatch: 8, gradAccum: 4, epochs: 2
|
|
131
|
+
// effectiveBatch = 32
|
|
132
|
+
// stepsPerEpoch = ceil(920000 / 32) = 28750
|
|
133
|
+
// totalSteps = 28750 * 2 = 57500
|
|
134
|
+
const steps = computeTotalSteps(920000, config);
|
|
135
|
+
expect(steps).toBe(57500);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('handles small datasets', () => {
|
|
139
|
+
const config = buildTrainingPipelineConfig({
|
|
140
|
+
hyperparameters: {
|
|
141
|
+
microBatchSize: 4,
|
|
142
|
+
gradientAccumulationSteps: 2,
|
|
143
|
+
epochs: 1,
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
// effectiveBatch = 8
|
|
147
|
+
// stepsPerEpoch = ceil(10 / 8) = 2
|
|
148
|
+
// totalSteps = 2 * 1 = 2
|
|
149
|
+
const steps = computeTotalSteps(10, config);
|
|
150
|
+
expect(steps).toBe(2);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('handles dataset size of 1', () => {
|
|
154
|
+
const config = buildTrainingPipelineConfig({
|
|
155
|
+
hyperparameters: {
|
|
156
|
+
microBatchSize: 8,
|
|
157
|
+
gradientAccumulationSteps: 4,
|
|
158
|
+
epochs: 2,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
// effectiveBatch = 32
|
|
162
|
+
// stepsPerEpoch = ceil(1 / 32) = 1
|
|
163
|
+
// totalSteps = 1 * 2 = 2
|
|
164
|
+
const steps = computeTotalSteps(1, config);
|
|
165
|
+
expect(steps).toBe(2);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('handles dataset size of 0', () => {
|
|
169
|
+
const config = buildTrainingPipelineConfig();
|
|
170
|
+
const steps = computeTotalSteps(0, config);
|
|
171
|
+
expect(steps).toBe(0);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('rounds up partial batches', () => {
|
|
175
|
+
const config = buildTrainingPipelineConfig({
|
|
176
|
+
hyperparameters: {
|
|
177
|
+
microBatchSize: 10,
|
|
178
|
+
gradientAccumulationSteps: 1,
|
|
179
|
+
epochs: 1,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
// effectiveBatch = 10
|
|
183
|
+
// stepsPerEpoch = ceil(15 / 10) = 2
|
|
184
|
+
const steps = computeTotalSteps(15, config);
|
|
185
|
+
expect(steps).toBe(2);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('scales linearly with epochs', () => {
|
|
189
|
+
const config1 = buildTrainingPipelineConfig({
|
|
190
|
+
hyperparameters: { epochs: 1 },
|
|
191
|
+
});
|
|
192
|
+
const config2 = buildTrainingPipelineConfig({
|
|
193
|
+
hyperparameters: { epochs: 2 },
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const steps1 = computeTotalSteps(1000, config1);
|
|
197
|
+
const steps2 = computeTotalSteps(1000, config2);
|
|
198
|
+
|
|
199
|
+
expect(steps2).toBe(steps1 * 2);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Training Schema Tests
|
|
3
|
+
*
|
|
4
|
+
* Gap 1: Validates training example schema and validation functions.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
import { validateTrainingExample } from '../schema';
|
|
9
|
+
import type { TrainingExample } from '../schema';
|
|
10
|
+
|
|
11
|
+
describe('validateTrainingExample', () => {
|
|
12
|
+
const validExample: TrainingExample = {
|
|
13
|
+
instruction: 'Create a grabbable cube',
|
|
14
|
+
input: '',
|
|
15
|
+
output: 'object "Cube" @grabbable { position: [0,1,0] }',
|
|
16
|
+
metadata: {
|
|
17
|
+
category: 'vr-interaction',
|
|
18
|
+
difficulty: 'beginner',
|
|
19
|
+
traits: ['grabbable'],
|
|
20
|
+
keywords: ['vr', 'interaction'],
|
|
21
|
+
version: '6.0.0',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
it('validates a correct training example', () => {
|
|
26
|
+
const result = validateTrainingExample(validExample);
|
|
27
|
+
expect(result.valid).toBe(true);
|
|
28
|
+
expect(result.errors).toHaveLength(0);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('rejects null input', () => {
|
|
32
|
+
const result = validateTrainingExample(null);
|
|
33
|
+
expect(result.valid).toBe(false);
|
|
34
|
+
expect(result.errors[0].field).toBe('root');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('rejects missing instruction', () => {
|
|
38
|
+
const result = validateTrainingExample({
|
|
39
|
+
...validExample,
|
|
40
|
+
instruction: '',
|
|
41
|
+
});
|
|
42
|
+
expect(result.valid).toBe(false);
|
|
43
|
+
expect(result.errors.some((e) => e.field === 'instruction')).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('rejects missing output', () => {
|
|
47
|
+
const result = validateTrainingExample({
|
|
48
|
+
...validExample,
|
|
49
|
+
output: '',
|
|
50
|
+
});
|
|
51
|
+
expect(result.valid).toBe(false);
|
|
52
|
+
expect(result.errors.some((e) => e.field === 'output')).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('rejects missing metadata', () => {
|
|
56
|
+
const { metadata, ...noMeta } = validExample;
|
|
57
|
+
const result = validateTrainingExample(noMeta);
|
|
58
|
+
expect(result.valid).toBe(false);
|
|
59
|
+
expect(result.errors.some((e) => e.field === 'metadata')).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('warns about missing traits array', () => {
|
|
63
|
+
const result = validateTrainingExample({
|
|
64
|
+
...validExample,
|
|
65
|
+
metadata: {
|
|
66
|
+
...validExample.metadata,
|
|
67
|
+
traits: 'not-an-array' as any,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
expect(result.warnings.length).toBeGreaterThan(0);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Training Constants Tests
|
|
3
|
+
*
|
|
4
|
+
* Gap 1: Verifies canonical constants, type narrowing, and exhaustiveness.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
import {
|
|
9
|
+
TRAINING_CATEGORIES,
|
|
10
|
+
DIFFICULTY_LEVELS,
|
|
11
|
+
QUALITY_THRESHOLDS,
|
|
12
|
+
DEFAULT_GENERATOR_THRESHOLDS,
|
|
13
|
+
RULEFORGE_DOMAINS,
|
|
14
|
+
getQualityTier,
|
|
15
|
+
isValidCategory,
|
|
16
|
+
isValidDifficulty,
|
|
17
|
+
} from '../constants';
|
|
18
|
+
|
|
19
|
+
describe('Training Constants', () => {
|
|
20
|
+
it('has 9 training categories', () => {
|
|
21
|
+
expect(TRAINING_CATEGORIES).toHaveLength(9);
|
|
22
|
+
expect(TRAINING_CATEGORIES).toContain('vr-interaction');
|
|
23
|
+
expect(TRAINING_CATEGORIES).toContain('ai-agents');
|
|
24
|
+
expect(TRAINING_CATEGORIES).toContain('physics');
|
|
25
|
+
expect(TRAINING_CATEGORIES).toContain('game-mechanics');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('has 4 difficulty levels', () => {
|
|
29
|
+
expect(DIFFICULTY_LEVELS).toHaveLength(4);
|
|
30
|
+
expect(DIFFICULTY_LEVELS).toContain('beginner');
|
|
31
|
+
expect(DIFFICULTY_LEVELS).toContain('intermediate');
|
|
32
|
+
expect(DIFFICULTY_LEVELS).toContain('advanced');
|
|
33
|
+
expect(DIFFICULTY_LEVELS).toContain('production');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('has quality thresholds with correct ranges', () => {
|
|
37
|
+
expect(QUALITY_THRESHOLDS.Excellent.min).toBe(90);
|
|
38
|
+
expect(QUALITY_THRESHOLDS.Excellent.max).toBe(100);
|
|
39
|
+
expect(QUALITY_THRESHOLDS.VeryGood.min).toBe(80);
|
|
40
|
+
expect(QUALITY_THRESHOLDS.VeryGood.max).toBe(89);
|
|
41
|
+
expect(QUALITY_THRESHOLDS.Acceptable.min).toBe(70);
|
|
42
|
+
expect(QUALITY_THRESHOLDS.Acceptable.max).toBe(79);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('has default generator thresholds', () => {
|
|
46
|
+
expect(DEFAULT_GENERATOR_THRESHOLDS.min_compression_ratio).toBe(5);
|
|
47
|
+
expect(DEFAULT_GENERATOR_THRESHOLDS.max_duplication_rate).toBe(0.05);
|
|
48
|
+
expect(DEFAULT_GENERATOR_THRESHOLDS.min_quality_score).toBe(0.7);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('has 8 ruleforge domains', () => {
|
|
52
|
+
expect(RULEFORGE_DOMAINS).toHaveLength(8);
|
|
53
|
+
expect(RULEFORGE_DOMAINS).toContain('ai_agents');
|
|
54
|
+
expect(RULEFORGE_DOMAINS).toContain('physics');
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('getQualityTier', () => {
|
|
59
|
+
it('returns Excellent for scores >= 90', () => {
|
|
60
|
+
expect(getQualityTier(95)).toBe('Excellent');
|
|
61
|
+
expect(getQualityTier(90)).toBe('Excellent');
|
|
62
|
+
expect(getQualityTier(100)).toBe('Excellent');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('returns VeryGood for scores 80-89', () => {
|
|
66
|
+
expect(getQualityTier(85)).toBe('VeryGood');
|
|
67
|
+
expect(getQualityTier(80)).toBe('VeryGood');
|
|
68
|
+
expect(getQualityTier(89)).toBe('VeryGood');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('returns Acceptable for scores 70-79', () => {
|
|
72
|
+
expect(getQualityTier(75)).toBe('Acceptable');
|
|
73
|
+
expect(getQualityTier(70)).toBe('Acceptable');
|
|
74
|
+
expect(getQualityTier(79)).toBe('Acceptable');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('returns BelowAcceptable for scores < 70', () => {
|
|
78
|
+
expect(getQualityTier(69)).toBe('BelowAcceptable');
|
|
79
|
+
expect(getQualityTier(0)).toBe('BelowAcceptable');
|
|
80
|
+
expect(getQualityTier(50)).toBe('BelowAcceptable');
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('isValidCategory', () => {
|
|
85
|
+
it('validates known categories', () => {
|
|
86
|
+
expect(isValidCategory('physics')).toBe(true);
|
|
87
|
+
expect(isValidCategory('ai-agents')).toBe(true);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('rejects unknown categories', () => {
|
|
91
|
+
expect(isValidCategory('unknown')).toBe(false);
|
|
92
|
+
expect(isValidCategory('')).toBe(false);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('isValidDifficulty', () => {
|
|
97
|
+
it('validates known difficulties', () => {
|
|
98
|
+
expect(isValidDifficulty('beginner')).toBe(true);
|
|
99
|
+
expect(isValidDifficulty('production')).toBe(true);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('rejects unknown difficulties', () => {
|
|
103
|
+
expect(isValidDifficulty('expert')).toBe(false);
|
|
104
|
+
expect(isValidDifficulty('')).toBe(false);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trait Mappings Tests
|
|
3
|
+
*
|
|
4
|
+
* Gap 1 + 2: Validates TM-to-HS trait mapping and validation functions.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
import {
|
|
9
|
+
TM_REGISTERED_TRAITS,
|
|
10
|
+
validateTraitName,
|
|
11
|
+
generateValidationReport,
|
|
12
|
+
} from '../trait-mappings';
|
|
13
|
+
|
|
14
|
+
describe('TM_REGISTERED_TRAITS', () => {
|
|
15
|
+
it('has 48 registered traits', () => {
|
|
16
|
+
expect(TM_REGISTERED_TRAITS).toHaveLength(48);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('includes core VR traits', () => {
|
|
20
|
+
expect(TM_REGISTERED_TRAITS).toContain('grabbable');
|
|
21
|
+
expect(TM_REGISTERED_TRAITS).toContain('throwable');
|
|
22
|
+
expect(TM_REGISTERED_TRAITS).toContain('physics');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('includes AI traits', () => {
|
|
26
|
+
expect(TM_REGISTERED_TRAITS).toContain('llm_agent');
|
|
27
|
+
expect(TM_REGISTERED_TRAITS).toContain('behavior_tree');
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('validateTraitName', () => {
|
|
32
|
+
const validTraits = new Set(['grabbable', 'throwable', 'physics', 'networked']);
|
|
33
|
+
|
|
34
|
+
it('matches exact trait names', () => {
|
|
35
|
+
expect(validateTraitName('grabbable', validTraits)).toBe('grabbable');
|
|
36
|
+
expect(validateTraitName('physics', validTraits)).toBe('physics');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('strips @ prefix and normalizes', () => {
|
|
40
|
+
expect(validateTraitName('@grabbable', validTraits)).toBe('grabbable');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('returns null for unknown traits', () => {
|
|
44
|
+
expect(validateTraitName('unknown_trait', validTraits)).toBeNull();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('works with readonly arrays', () => {
|
|
48
|
+
const arr = ['grabbable', 'physics'] as const;
|
|
49
|
+
expect(validateTraitName('grabbable', arr)).toBe('grabbable');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('generateValidationReport', () => {
|
|
54
|
+
const hsTraits = new Set(['grabbable', 'throwable', 'physics', 'networked', 'glowing']);
|
|
55
|
+
const deprecatedTraits = new Set(['collision', 'talkable']);
|
|
56
|
+
|
|
57
|
+
it('correctly classifies matched traits', () => {
|
|
58
|
+
const report = generateValidationReport(['grabbable', 'physics'], hsTraits);
|
|
59
|
+
expect(report.matched).toBe(2);
|
|
60
|
+
expect(report.unmatched).toBe(0);
|
|
61
|
+
expect(report.total).toBe(2);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('correctly identifies unmatched traits', () => {
|
|
65
|
+
const report = generateValidationReport(['grabbable', 'unknown_trait'], hsTraits);
|
|
66
|
+
expect(report.matched).toBe(1);
|
|
67
|
+
expect(report.unmatched).toBe(1);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('correctly identifies deprecated traits', () => {
|
|
71
|
+
const report = generateValidationReport(['collision', 'grabbable'], hsTraits, deprecatedTraits);
|
|
72
|
+
expect(report.deprecated).toBe(1);
|
|
73
|
+
expect(report.matched).toBe(1);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('generates full report for TM traits', () => {
|
|
77
|
+
const report = generateValidationReport(TM_REGISTERED_TRAITS as unknown as string[], hsTraits);
|
|
78
|
+
expect(report.total).toBe(48);
|
|
79
|
+
expect(report.matched + report.unmatched + report.deprecated).toBe(48);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Training Constants
|
|
3
|
+
*
|
|
4
|
+
* Canonical constants shared between @holoscript/core and TrainingMonkey.
|
|
5
|
+
* This module has ZERO imports from other workspace packages (G.GAP.01 prevention).
|
|
6
|
+
*
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 9 training categories covering all HoloScript domains
|
|
12
|
+
*/
|
|
13
|
+
export const TRAINING_CATEGORIES = [
|
|
14
|
+
'vr-interaction',
|
|
15
|
+
'multiplayer',
|
|
16
|
+
'physics',
|
|
17
|
+
'ui-spatial',
|
|
18
|
+
'ai-agents',
|
|
19
|
+
'procedural',
|
|
20
|
+
'audio-spatial',
|
|
21
|
+
'visual-effects',
|
|
22
|
+
'game-mechanics',
|
|
23
|
+
] as const;
|
|
24
|
+
|
|
25
|
+
export type TrainingCategory = (typeof TRAINING_CATEGORIES)[number];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 4 difficulty levels for training data
|
|
29
|
+
*/
|
|
30
|
+
export const DIFFICULTY_LEVELS = ['beginner', 'intermediate', 'advanced', 'production'] as const;
|
|
31
|
+
|
|
32
|
+
export type DifficultyLevel = (typeof DIFFICULTY_LEVELS)[number];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Quality score thresholds for training data evaluation
|
|
36
|
+
*/
|
|
37
|
+
export const QUALITY_THRESHOLDS = {
|
|
38
|
+
Excellent: { min: 90, max: 100 },
|
|
39
|
+
VeryGood: { min: 80, max: 89 },
|
|
40
|
+
Acceptable: { min: 70, max: 79 },
|
|
41
|
+
} as const;
|
|
42
|
+
|
|
43
|
+
export type QualityTier = keyof typeof QUALITY_THRESHOLDS;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Default quality constraints for training data generators
|
|
47
|
+
*/
|
|
48
|
+
export const DEFAULT_GENERATOR_THRESHOLDS = {
|
|
49
|
+
min_compression_ratio: 5,
|
|
50
|
+
max_compression_ratio: 15,
|
|
51
|
+
max_duplication_rate: 0.05,
|
|
52
|
+
min_templates_per_difficulty: 10,
|
|
53
|
+
min_quality_score: 0.7,
|
|
54
|
+
} as const;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* RuleForge domain categories used by the rule generator
|
|
58
|
+
*/
|
|
59
|
+
export const RULEFORGE_DOMAINS = [
|
|
60
|
+
'ai_agents',
|
|
61
|
+
'physics',
|
|
62
|
+
'robotics',
|
|
63
|
+
'audio',
|
|
64
|
+
'rendering',
|
|
65
|
+
'interaction',
|
|
66
|
+
'multiplayer',
|
|
67
|
+
'vr_ar',
|
|
68
|
+
] as const;
|
|
69
|
+
|
|
70
|
+
export type RuleForgeDomain = (typeof RULEFORGE_DOMAINS)[number];
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get quality tier for a given score
|
|
74
|
+
*/
|
|
75
|
+
export function getQualityTier(score: number): QualityTier | 'BelowAcceptable' {
|
|
76
|
+
if (score >= QUALITY_THRESHOLDS.Excellent.min) return 'Excellent';
|
|
77
|
+
if (score >= QUALITY_THRESHOLDS.VeryGood.min) return 'VeryGood';
|
|
78
|
+
if (score >= QUALITY_THRESHOLDS.Acceptable.min) return 'Acceptable';
|
|
79
|
+
return 'BelowAcceptable';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Validate that a category string is a valid TrainingCategory
|
|
84
|
+
*/
|
|
85
|
+
export function isValidCategory(category: string): category is TrainingCategory {
|
|
86
|
+
return (TRAINING_CATEGORIES as readonly string[]).includes(category);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Validate that a difficulty string is a valid DifficultyLevel
|
|
91
|
+
*/
|
|
92
|
+
export function isValidDifficulty(difficulty: string): difficulty is DifficultyLevel {
|
|
93
|
+
return (DIFFICULTY_LEVELS as readonly string[]).includes(difficulty);
|
|
94
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @holoscript/core - Training Module
|
|
3
|
+
*
|
|
4
|
+
* Spatial training data generation, sparsity monitoring, quality scoring,
|
|
5
|
+
* and training pipeline configuration.
|
|
6
|
+
*/
|
|
7
|
+
export * from './SparsityMonitor';
|
|
8
|
+
export * from './SparsityMonitorTypes';
|
|
9
|
+
export * from './SpatialTrainingDataGenerator';
|
|
10
|
+
export * from './SpatialTrainingDataTypes';
|
|
11
|
+
export * from './TrainingPipelineConfig';
|
|
12
|
+
export * from './QualityScoringPipeline';
|
|
13
|
+
export * from './SoftDedup';
|
|
14
|
+
export * from './LRScheduler';
|
|
15
|
+
export * from './constants';
|
|
16
|
+
export * from './trait-mappings';
|
|
17
|
+
export * from './schema';
|