@holoscript/framework 6.0.3
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/ALL-test-results.json +1 -0
- package/CHANGELOG.md +8 -0
- package/LICENSE +21 -0
- package/ROADMAP.md +175 -0
- package/dist/AgentManifest-CB4xM-Ma.d.cts +704 -0
- package/dist/AgentManifest-CB4xM-Ma.d.ts +704 -0
- package/dist/BehaviorTree-BrBFECv5.d.cts +103 -0
- package/dist/BehaviorTree-BrBFECv5.d.ts +103 -0
- package/dist/InvisibleWallet-BB6tFvRA.d.cts +1732 -0
- package/dist/InvisibleWallet-rtRrBOA8.d.ts +1732 -0
- package/dist/OrchestratorAgent-BvWgf9uw.d.cts +798 -0
- package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +798 -0
- package/dist/agents/index.cjs +4790 -0
- package/dist/agents/index.d.cts +1788 -0
- package/dist/agents/index.d.ts +1788 -0
- package/dist/agents/index.js +4695 -0
- package/dist/ai/index.cjs +5347 -0
- package/dist/ai/index.d.cts +1753 -0
- package/dist/ai/index.d.ts +1753 -0
- package/dist/ai/index.js +5244 -0
- package/dist/behavior.cjs +449 -0
- package/dist/behavior.d.cts +130 -0
- package/dist/behavior.d.ts +130 -0
- package/dist/behavior.js +407 -0
- package/dist/economy/index.cjs +3659 -0
- package/dist/economy/index.d.cts +747 -0
- package/dist/economy/index.d.ts +747 -0
- package/dist/economy/index.js +3617 -0
- package/dist/implementations-D9T3un9D.d.cts +236 -0
- package/dist/implementations-D9T3un9D.d.ts +236 -0
- package/dist/index.cjs +24550 -0
- package/dist/index.d.cts +1729 -0
- package/dist/index.d.ts +1729 -0
- package/dist/index.js +24277 -0
- package/dist/learning/index.cjs +219 -0
- package/dist/learning/index.d.cts +104 -0
- package/dist/learning/index.d.ts +104 -0
- package/dist/learning/index.js +189 -0
- package/dist/negotiation/index.cjs +970 -0
- package/dist/negotiation/index.d.cts +610 -0
- package/dist/negotiation/index.d.ts +610 -0
- package/dist/negotiation/index.js +931 -0
- package/dist/skills/index.cjs +1118 -0
- package/dist/skills/index.d.cts +289 -0
- package/dist/skills/index.d.ts +289 -0
- package/dist/skills/index.js +1079 -0
- package/dist/swarm/index.cjs +5268 -0
- package/dist/swarm/index.d.cts +2433 -0
- package/dist/swarm/index.d.ts +2433 -0
- package/dist/swarm/index.js +5221 -0
- package/dist/training/index.cjs +2745 -0
- package/dist/training/index.d.cts +1734 -0
- package/dist/training/index.d.ts +1734 -0
- package/dist/training/index.js +2687 -0
- package/extract-failures.js +10 -0
- package/package.json +82 -0
- package/src/__tests__/bounty-marketplace.test.ts +374 -0
- package/src/__tests__/delegation.test.ts +144 -0
- package/src/__tests__/distributed-claimer.test.ts +147 -0
- package/src/__tests__/done-log-audit.test.ts +342 -0
- package/src/__tests__/framework.test.ts +865 -0
- package/src/__tests__/goal-synthesizer.test.ts +236 -0
- package/src/__tests__/presence.test.ts +223 -0
- package/src/__tests__/protocol-agent.test.ts +254 -0
- package/src/__tests__/revenue-splitter.test.ts +114 -0
- package/src/__tests__/scenario-driven-todo.test.ts +197 -0
- package/src/__tests__/self-improve.test.ts +349 -0
- package/src/__tests__/service-lifecycle.test.ts +237 -0
- package/src/__tests__/skill-router.test.ts +121 -0
- package/src/agents/AgentManifest.ts +493 -0
- package/src/agents/AgentRegistry.ts +475 -0
- package/src/agents/AgentTypes.ts +585 -0
- package/src/agents/AgentWalletRegistry.ts +83 -0
- package/src/agents/AuthenticatedCRDT.ts +388 -0
- package/src/agents/CapabilityMatcher.ts +453 -0
- package/src/agents/CrossRealityHandoff.ts +305 -0
- package/src/agents/CulturalMemory.ts +454 -0
- package/src/agents/FederatedRegistryAdapter.ts +429 -0
- package/src/agents/NormEngine.ts +450 -0
- package/src/agents/OrchestratorAgent.ts +414 -0
- package/src/agents/SkillWorkflowEngine.ts +472 -0
- package/src/agents/TaskDelegationService.ts +551 -0
- package/src/agents/__tests__/AgentManifest.prod.test.ts +134 -0
- package/src/agents/__tests__/AgentManifest.test.ts +182 -0
- package/src/agents/__tests__/AgentModule.test.ts +864 -0
- package/src/agents/__tests__/AgentRegistry.prod.test.ts +125 -0
- package/src/agents/__tests__/AgentRegistry.test.ts +148 -0
- package/src/agents/__tests__/AgentTypes.test.ts +534 -0
- package/src/agents/__tests__/AgentWalletRegistry.test.ts +152 -0
- package/src/agents/__tests__/AuthenticatedCRDT.test.ts +558 -0
- package/src/agents/__tests__/CapabilityMatcher.prod.test.ts +117 -0
- package/src/agents/__tests__/CapabilityMatcher.test.ts +178 -0
- package/src/agents/__tests__/CrossRealityHandoff.test.ts +402 -0
- package/src/agents/__tests__/CulturalMemory.test.ts +200 -0
- package/src/agents/__tests__/FederatedRegistryAdapter.test.ts +409 -0
- package/src/agents/__tests__/NormEngine.test.ts +276 -0
- package/src/agents/__tests__/OrchestratorAgent.test.ts +182 -0
- package/src/agents/__tests__/SkillWorkflowEngine.test.ts +357 -0
- package/src/agents/__tests__/TaskDelegationService.test.ts +446 -0
- package/src/agents/index.ts +107 -0
- package/src/agents/spatial-comms/Layer1RealTime.ts +621 -0
- package/src/agents/spatial-comms/Layer2A2A.ts +661 -0
- package/src/agents/spatial-comms/Layer3MCP.ts +651 -0
- package/src/agents/spatial-comms/ProtocolTypes.ts +543 -0
- package/src/agents/spatial-comms/SpatialCommClient.ts +483 -0
- package/src/agents/spatial-comms/__tests__/performance-benchmark.test.ts +465 -0
- package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +409 -0
- package/src/agents/spatial-comms/index.ts +66 -0
- package/src/ai/AIAdapter.ts +313 -0
- package/src/ai/AICopilot.ts +331 -0
- package/src/ai/AIOutputValidator.ts +203 -0
- package/src/ai/BTNodes.ts +239 -0
- package/src/ai/BehaviorSelector.ts +135 -0
- package/src/ai/BehaviorTree.ts +153 -0
- package/src/ai/Blackboard.ts +165 -0
- package/src/ai/GenerationAnalytics.ts +461 -0
- package/src/ai/GenerationCache.ts +265 -0
- package/src/ai/GoalPlanner.ts +165 -0
- package/src/ai/HoloScriptGenerator.ts +580 -0
- package/src/ai/InfluenceMap.ts +180 -0
- package/src/ai/NavMesh.ts +168 -0
- package/src/ai/PerceptionSystem.ts +178 -0
- package/src/ai/PromptTemplates.ts +453 -0
- package/src/ai/SemanticSearchService.ts +80 -0
- package/src/ai/StateMachine.ts +196 -0
- package/src/ai/SteeringBehavior.ts +150 -0
- package/src/ai/SteeringBehaviors.ts +244 -0
- package/src/ai/TrainingDataGenerator.ts +1082 -0
- package/src/ai/UtilityAI.ts +145 -0
- package/src/ai/__tests__/AIAdapter.prod.test.ts +259 -0
- package/src/ai/__tests__/AIAdapter.test.ts +109 -0
- package/src/ai/__tests__/AICopilot.prod.test.ts +341 -0
- package/src/ai/__tests__/AICopilot.test.ts +178 -0
- package/src/ai/__tests__/AIOutputValidator.prod.test.ts +226 -0
- package/src/ai/__tests__/AIOutputValidator.test.ts +138 -0
- package/src/ai/__tests__/BTNodes.prod.test.ts +391 -0
- package/src/ai/__tests__/BTNodes.test.ts +263 -0
- package/src/ai/__tests__/BehaviorSelector.prod.test.ts +129 -0
- package/src/ai/__tests__/BehaviorSelector.test.ts +132 -0
- package/src/ai/__tests__/BehaviorTree.prod.test.ts +266 -0
- package/src/ai/__tests__/BehaviorTree.test.ts +216 -0
- package/src/ai/__tests__/Blackboard.prod.test.ts +339 -0
- package/src/ai/__tests__/Blackboard.test.ts +183 -0
- package/src/ai/__tests__/GenerationAnalytics.prod.test.ts +141 -0
- package/src/ai/__tests__/GenerationAnalytics.test.ts +165 -0
- package/src/ai/__tests__/GenerationCache.prod.test.ts +144 -0
- package/src/ai/__tests__/GenerationCache.test.ts +171 -0
- package/src/ai/__tests__/GoalPlanner.prod.test.ts +189 -0
- package/src/ai/__tests__/GoalPlanner.test.ts +137 -0
- package/src/ai/__tests__/GoalPlannerDepth.prod.test.ts +217 -0
- package/src/ai/__tests__/HoloScriptGenerator.test.ts +125 -0
- package/src/ai/__tests__/InfluenceMap.prod.test.ts +146 -0
- package/src/ai/__tests__/InfluenceMap.test.ts +149 -0
- package/src/ai/__tests__/NavMesh.prod.test.ts +141 -0
- package/src/ai/__tests__/NavMesh.test.ts +159 -0
- package/src/ai/__tests__/PerceptionSystem.prod.test.ts +135 -0
- package/src/ai/__tests__/PerceptionSystem.test.ts +250 -0
- package/src/ai/__tests__/PromptTemplates.prod.test.ts +313 -0
- package/src/ai/__tests__/PromptTemplates.test.ts +146 -0
- package/src/ai/__tests__/SemanticSearch.test.ts +37 -0
- package/src/ai/__tests__/StateMachine.prod.test.ts +162 -0
- package/src/ai/__tests__/StateMachine.test.ts +163 -0
- package/src/ai/__tests__/SteeringBehavior.prod.test.ts +251 -0
- package/src/ai/__tests__/SteeringBehavior.test.ts +135 -0
- package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +133 -0
- package/src/ai/__tests__/SteeringBehaviors.test.ts +151 -0
- package/src/ai/__tests__/TrainingDataGenerator.prod.test.ts +286 -0
- package/src/ai/__tests__/TrainingDataGenerator.test.ts +286 -0
- package/src/ai/__tests__/UtilityAI.prod.test.ts +207 -0
- package/src/ai/__tests__/UtilityAI.test.ts +155 -0
- package/src/ai/__tests__/adapters.prod.test.ts +263 -0
- package/src/ai/__tests__/adapters.test.ts +320 -0
- package/src/ai/adapters.ts +1585 -0
- package/src/ai/index.ts +130 -0
- package/src/behavior/BehaviorPresets.ts +140 -0
- package/src/behavior/BehaviorTree.ts +236 -0
- package/src/behavior/StateMachine.ts +176 -0
- package/src/behavior/StateTrait.ts +67 -0
- package/src/behavior/index.ts +8 -0
- package/src/behavior.ts +8 -0
- package/src/board/audit.ts +284 -0
- package/src/board/board-ops.ts +336 -0
- package/src/board/board-types.ts +302 -0
- package/src/board/index.ts +69 -0
- package/src/define-agent.ts +46 -0
- package/src/define-team.ts +33 -0
- package/src/delegation.ts +265 -0
- package/src/distributed-claimer.ts +228 -0
- package/src/economy/AgentBudgetEnforcer.ts +464 -0
- package/src/economy/BountyManager.ts +185 -0
- package/src/economy/CreatorRevenueAggregator.ts +460 -0
- package/src/economy/InvisibleWallet.ts +82 -0
- package/src/economy/KnowledgeMarketplace.ts +193 -0
- package/src/economy/PaymentWebhookService.ts +512 -0
- package/src/economy/RevenueSplitter.ts +156 -0
- package/src/economy/SubscriptionManager.ts +546 -0
- package/src/economy/UnifiedBudgetOptimizer.ts +635 -0
- package/src/economy/UsageMeter.ts +440 -0
- package/src/economy/_core-stubs.ts +219 -0
- package/src/economy/index.ts +100 -0
- package/src/economy/x402-facilitator.ts +1978 -0
- package/src/index.ts +348 -0
- package/src/knowledge/__tests__/knowledge-consolidator.test.ts +444 -0
- package/src/knowledge/__tests__/knowledge-store-vector.test.ts +291 -0
- package/src/knowledge/brain.ts +167 -0
- package/src/knowledge/consolidation.ts +581 -0
- package/src/knowledge/knowledge-consolidator.ts +510 -0
- package/src/knowledge/knowledge-store.ts +616 -0
- package/src/learning/MemoryConsolidator.ts +102 -0
- package/src/learning/MemoryScorer.ts +69 -0
- package/src/learning/ProceduralCompiler.ts +45 -0
- package/src/learning/SemanticClusterer.ts +66 -0
- package/src/learning/index.ts +8 -0
- package/src/llm/llm-adapter.ts +159 -0
- package/src/mesh/index.ts +309 -0
- package/src/negotiation/NegotiationProtocol.ts +694 -0
- package/src/negotiation/NegotiationTypes.ts +473 -0
- package/src/negotiation/VotingMechanisms.ts +691 -0
- package/src/negotiation/index.ts +49 -0
- package/src/protocol/goal-synthesizer.ts +317 -0
- package/src/protocol/implementations.ts +474 -0
- package/src/protocol/micro-phase-decomposer.ts +299 -0
- package/src/protocol/micro-step-decomposer.test.ts +306 -0
- package/src/protocol-agent.test.ts +353 -0
- package/src/protocol-agent.ts +670 -0
- package/src/self-improve/absorb-scanner.ts +252 -0
- package/src/self-improve/evolution-engine.ts +149 -0
- package/src/self-improve/framework-absorber.ts +214 -0
- package/src/self-improve/index.ts +50 -0
- package/src/self-improve/prompt-optimizer.ts +212 -0
- package/src/self-improve/test-generator.ts +175 -0
- package/src/skill-router.ts +186 -0
- package/src/skills/index.ts +5 -0
- package/src/skills/skill-md-bridge.ts +1699 -0
- package/src/swarm/ACOEngine.ts +261 -0
- package/src/swarm/CollectiveIntelligence.ts +383 -0
- package/src/swarm/ContributionSynthesizer.ts +481 -0
- package/src/swarm/LeaderElection.ts +393 -0
- package/src/swarm/PSOEngine.ts +206 -0
- package/src/swarm/QuorumPolicy.ts +173 -0
- package/src/swarm/SwarmCoordinator.ts +335 -0
- package/src/swarm/SwarmManager.ts +442 -0
- package/src/swarm/SwarmMembership.ts +456 -0
- package/src/swarm/VotingRound.ts +255 -0
- package/src/swarm/__tests__/ACOEngine.prod.test.ts +164 -0
- package/src/swarm/__tests__/ACOEngine.test.ts +117 -0
- package/src/swarm/__tests__/CollectiveIntelligence.prod.test.ts +296 -0
- package/src/swarm/__tests__/CollectiveIntelligence.test.ts +457 -0
- package/src/swarm/__tests__/ContributionSynthesizer.prod.test.ts +269 -0
- package/src/swarm/__tests__/ContributionSynthesizer.test.ts +254 -0
- package/src/swarm/__tests__/LeaderElection.prod.test.ts +196 -0
- package/src/swarm/__tests__/LeaderElection.test.ts +151 -0
- package/src/swarm/__tests__/PSOEngine.prod.test.ts +162 -0
- package/src/swarm/__tests__/PSOEngine.test.ts +106 -0
- package/src/swarm/__tests__/QuorumPolicy.prod.test.ts +216 -0
- package/src/swarm/__tests__/QuorumPolicy.test.ts +177 -0
- package/src/swarm/__tests__/SwarmCoordinator.prod.test.ts +186 -0
- package/src/swarm/__tests__/SwarmCoordinator.test.ts +167 -0
- package/src/swarm/__tests__/SwarmManager.prod.test.ts +308 -0
- package/src/swarm/__tests__/SwarmManager.test.ts +373 -0
- package/src/swarm/__tests__/SwarmMembership.prod.test.ts +273 -0
- package/src/swarm/__tests__/SwarmMembership.test.ts +264 -0
- package/src/swarm/__tests__/VotingRound.prod.test.ts +233 -0
- package/src/swarm/__tests__/VotingRound.test.ts +174 -0
- package/src/swarm/analytics/SwarmInspector.ts +476 -0
- package/src/swarm/analytics/SwarmMetrics.ts +449 -0
- package/src/swarm/analytics/__tests__/SwarmInspector.prod.test.ts +366 -0
- package/src/swarm/analytics/__tests__/SwarmInspector.test.ts +454 -0
- package/src/swarm/analytics/__tests__/SwarmMetrics.prod.test.ts +254 -0
- package/src/swarm/analytics/__tests__/SwarmMetrics.test.ts +370 -0
- package/src/swarm/analytics/index.ts +7 -0
- package/src/swarm/index.ts +69 -0
- package/src/swarm/messaging/BroadcastChannel.ts +509 -0
- package/src/swarm/messaging/GossipProtocol.ts +565 -0
- package/src/swarm/messaging/SwarmEventBus.ts +443 -0
- package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +331 -0
- package/src/swarm/messaging/__tests__/BroadcastChannel.test.ts +333 -0
- package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +356 -0
- package/src/swarm/messaging/__tests__/GossipProtocol.test.ts +437 -0
- package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +191 -0
- package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +247 -0
- package/src/swarm/messaging/index.ts +8 -0
- package/src/swarm/spatial/FlockingBehavior.ts +462 -0
- package/src/swarm/spatial/FormationController.ts +500 -0
- package/src/swarm/spatial/Vector3.ts +170 -0
- package/src/swarm/spatial/ZoneClaiming.ts +509 -0
- package/src/swarm/spatial/__tests__/FlockingBehavior.prod.test.ts +239 -0
- package/src/swarm/spatial/__tests__/FlockingBehavior.test.ts +298 -0
- package/src/swarm/spatial/__tests__/FormationController.prod.test.ts +240 -0
- package/src/swarm/spatial/__tests__/FormationController.test.ts +297 -0
- package/src/swarm/spatial/__tests__/Vector3.prod.test.ts +283 -0
- package/src/swarm/spatial/__tests__/Vector3.test.ts +224 -0
- package/src/swarm/spatial/__tests__/ZoneClaiming.prod.test.ts +246 -0
- package/src/swarm/spatial/__tests__/ZoneClaiming.test.ts +374 -0
- package/src/swarm/spatial/index.ts +28 -0
- package/src/team.ts +1245 -0
- package/src/training/LRScheduler.ts +377 -0
- package/src/training/QualityScoringPipeline.ts +139 -0
- package/src/training/SoftDedup.ts +461 -0
- package/src/training/SparsityMonitor.ts +685 -0
- package/src/training/SparsityMonitorTypes.ts +209 -0
- package/src/training/SpatialTrainingDataGenerator.ts +1526 -0
- package/src/training/SpatialTrainingDataTypes.ts +216 -0
- package/src/training/TrainingPipelineConfig.ts +215 -0
- package/src/training/constants.ts +94 -0
- package/src/training/index.ts +138 -0
- package/src/training/schema.ts +147 -0
- package/src/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
- package/src/training/scripts/generate-spatial-dataset.ts +521 -0
- package/src/training/training/data/novel-use-cases.jsonl +153 -0
- package/src/training/training/data/spatial-reasoning-10k.jsonl +9354 -0
- package/src/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
- package/src/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
- package/src/training/trainingmonkey/index.ts +26 -0
- package/src/training/trait-mappings.ts +157 -0
- package/src/types/core-stubs.d.ts +113 -0
- package/src/types.ts +304 -0
- package/test-output.txt +0 -0
- package/test-result.json +1 -0
- package/tsc-errors.txt +4 -0
- package/tsc_output.txt +0 -0
- package/tsconfig.json +14 -0
- package/tsup-learning-esm.config.ts +12 -0
- package/tsup.config.ts +21 -0
- package/typescript-errors-2.txt +0 -0
- package/typescript-errors.txt +22 -0
- package/vitest-log-utf8.txt +268 -0
- package/vitest-log.txt +0 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UtilityAI.ts
|
|
3
|
+
*
|
|
4
|
+
* Utility-based AI: action scoring with consideration curves,
|
|
5
|
+
* weighted selection, cooldowns, and action history.
|
|
6
|
+
*
|
|
7
|
+
* @module ai
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// TYPES
|
|
12
|
+
// =============================================================================
|
|
13
|
+
|
|
14
|
+
export type CurveType = 'linear' | 'quadratic' | 'logistic' | 'step';
|
|
15
|
+
|
|
16
|
+
export interface Consideration {
|
|
17
|
+
name: string;
|
|
18
|
+
input: () => number; // 0-1 normalized input
|
|
19
|
+
curve: CurveType;
|
|
20
|
+
weight: number;
|
|
21
|
+
invert: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface UtilityAction {
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
considerations: Consideration[];
|
|
28
|
+
cooldown: number; // Seconds
|
|
29
|
+
lastExecuted: number;
|
|
30
|
+
bonus: number; // Flat score bonus
|
|
31
|
+
execute: () => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// =============================================================================
|
|
35
|
+
// UTILITY AI
|
|
36
|
+
// =============================================================================
|
|
37
|
+
|
|
38
|
+
export class UtilityAI {
|
|
39
|
+
private actions: Map<string, UtilityAction> = new Map();
|
|
40
|
+
private history: Array<{ actionId: string; score: number; timestamp: number }> = [];
|
|
41
|
+
private maxHistory = 50;
|
|
42
|
+
private currentTime = 0;
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Action Management
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
addAction(action: UtilityAction): void {
|
|
49
|
+
this.actions.set(action.id, action);
|
|
50
|
+
}
|
|
51
|
+
removeAction(id: string): void {
|
|
52
|
+
this.actions.delete(id);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Scoring
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
scoreAction(action: UtilityAction): number {
|
|
60
|
+
if (this.currentTime - action.lastExecuted < action.cooldown) return 0;
|
|
61
|
+
|
|
62
|
+
let score = 1;
|
|
63
|
+
for (const c of action.considerations) {
|
|
64
|
+
let input = Math.max(0, Math.min(1, c.input()));
|
|
65
|
+
if (c.invert) input = 1 - input;
|
|
66
|
+
|
|
67
|
+
let value: number;
|
|
68
|
+
switch (c.curve) {
|
|
69
|
+
case 'linear':
|
|
70
|
+
value = input;
|
|
71
|
+
break;
|
|
72
|
+
case 'quadratic':
|
|
73
|
+
value = input * input;
|
|
74
|
+
break;
|
|
75
|
+
case 'logistic':
|
|
76
|
+
value = 1 / (1 + Math.exp(-10 * (input - 0.5)));
|
|
77
|
+
break;
|
|
78
|
+
case 'step':
|
|
79
|
+
value = input >= 0.5 ? 1 : 0;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
score *= value * c.weight;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return score + action.bonus;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
scoreAll(): Array<{ actionId: string; score: number }> {
|
|
90
|
+
const scores: Array<{ actionId: string; score: number }> = [];
|
|
91
|
+
for (const action of this.actions.values()) {
|
|
92
|
+
scores.push({ actionId: action.id, score: this.scoreAction(action) });
|
|
93
|
+
}
|
|
94
|
+
return scores.sort((a, b) => b.score - a.score);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Selection & Execution
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
selectBest(): UtilityAction | null {
|
|
102
|
+
let bestAction: UtilityAction | null = null;
|
|
103
|
+
let bestScore = -Infinity;
|
|
104
|
+
|
|
105
|
+
for (const action of this.actions.values()) {
|
|
106
|
+
const score = this.scoreAction(action);
|
|
107
|
+
if (score > bestScore) {
|
|
108
|
+
bestScore = score;
|
|
109
|
+
bestAction = action;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return bestAction;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
executeBest(): string | null {
|
|
117
|
+
const action = this.selectBest();
|
|
118
|
+
if (!action || this.scoreAction(action) <= 0) return null;
|
|
119
|
+
|
|
120
|
+
action.execute();
|
|
121
|
+
action.lastExecuted = this.currentTime;
|
|
122
|
+
this.history.push({
|
|
123
|
+
actionId: action.id,
|
|
124
|
+
score: this.scoreAction(action),
|
|
125
|
+
timestamp: this.currentTime,
|
|
126
|
+
});
|
|
127
|
+
if (this.history.length > this.maxHistory) this.history.shift();
|
|
128
|
+
|
|
129
|
+
return action.id;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Time
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
setTime(time: number): void {
|
|
137
|
+
this.currentTime = time;
|
|
138
|
+
}
|
|
139
|
+
getHistory() {
|
|
140
|
+
return [...this.history];
|
|
141
|
+
}
|
|
142
|
+
getActionCount(): number {
|
|
143
|
+
return this.actions.size;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIAdapter Registry — Production Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests: registerAIAdapter, getAIAdapter, getDefaultAIAdapter,
|
|
5
|
+
* setDefaultAIAdapter, unregisterAIAdapter, listAIAdapters,
|
|
6
|
+
* and the convenience wrappers (generateHoloScript, explainHoloScript,
|
|
7
|
+
* optimizeHoloScript, fixHoloScript).
|
|
8
|
+
*
|
|
9
|
+
* Each test isolates registry state by registering unique IDs.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
13
|
+
import {
|
|
14
|
+
registerAIAdapter,
|
|
15
|
+
getAIAdapter,
|
|
16
|
+
getDefaultAIAdapter,
|
|
17
|
+
setDefaultAIAdapter,
|
|
18
|
+
unregisterAIAdapter,
|
|
19
|
+
listAIAdapters,
|
|
20
|
+
generateHoloScript,
|
|
21
|
+
explainHoloScript,
|
|
22
|
+
optimizeHoloScript,
|
|
23
|
+
fixHoloScript,
|
|
24
|
+
type AIAdapter,
|
|
25
|
+
type GenerateResult,
|
|
26
|
+
type ExplainResult,
|
|
27
|
+
type OptimizeResult,
|
|
28
|
+
type FixResult,
|
|
29
|
+
} from '../AIAdapter';
|
|
30
|
+
|
|
31
|
+
let _counter = 0;
|
|
32
|
+
function uniqueId(): string {
|
|
33
|
+
return `test-adapter-${_counter++}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function makeAdapter(overrides: Partial<AIAdapter> = {}): AIAdapter {
|
|
37
|
+
const id = uniqueId();
|
|
38
|
+
return {
|
|
39
|
+
id,
|
|
40
|
+
name: `Test Adapter ${id}`,
|
|
41
|
+
isReady: () => true,
|
|
42
|
+
generateHoloScript: async (prompt: string) =>
|
|
43
|
+
({
|
|
44
|
+
holoScript: `object "Test" { // ${prompt} }`,
|
|
45
|
+
confidence: 0.9,
|
|
46
|
+
}) as GenerateResult,
|
|
47
|
+
explainHoloScript: async () => ({ explanation: 'This creates a cube.' }) as ExplainResult,
|
|
48
|
+
optimizeHoloScript: async (code: string) =>
|
|
49
|
+
({
|
|
50
|
+
holoScript: code + ' // optimized',
|
|
51
|
+
improvements: ['removed redundant calls'],
|
|
52
|
+
}) as OptimizeResult,
|
|
53
|
+
fixHoloScript: async (code: string, errors: string[]) =>
|
|
54
|
+
({
|
|
55
|
+
holoScript: code,
|
|
56
|
+
fixes: errors.map((e) => ({ line: 0, issue: e, fix: 'auto-fixed' })),
|
|
57
|
+
}) as FixResult,
|
|
58
|
+
...overrides,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// --- registerAIAdapter / getAIAdapter ---
|
|
63
|
+
describe('registerAIAdapter and getAIAdapter', () => {
|
|
64
|
+
it('retrieves a registered adapter by id', () => {
|
|
65
|
+
const a = makeAdapter();
|
|
66
|
+
registerAIAdapter(a, false);
|
|
67
|
+
expect(getAIAdapter(a.id)).toBe(a);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('returns undefined for unregistered id', () => {
|
|
71
|
+
expect(getAIAdapter('totally-unknown-99999')).toBeUndefined();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('overwriting with same id replaces the adapter', () => {
|
|
75
|
+
const id = uniqueId();
|
|
76
|
+
const a1 = makeAdapter({ id, name: 'First' });
|
|
77
|
+
const a2 = makeAdapter({ id, name: 'Second' });
|
|
78
|
+
registerAIAdapter(a1, false);
|
|
79
|
+
registerAIAdapter(a2, false);
|
|
80
|
+
expect(getAIAdapter(id)!.name).toBe('Second');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('multiple adapters can coexist', () => {
|
|
84
|
+
const a = makeAdapter();
|
|
85
|
+
const b = makeAdapter();
|
|
86
|
+
registerAIAdapter(a, false);
|
|
87
|
+
registerAIAdapter(b, false);
|
|
88
|
+
expect(getAIAdapter(a.id)).toBe(a);
|
|
89
|
+
expect(getAIAdapter(b.id)).toBe(b);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// --- default adapter ---
|
|
94
|
+
describe('getDefaultAIAdapter / setDefaultAIAdapter', () => {
|
|
95
|
+
it('first registered adapter becomes default when setAsDefault=true', () => {
|
|
96
|
+
const a = makeAdapter();
|
|
97
|
+
registerAIAdapter(a, true);
|
|
98
|
+
expect(getDefaultAIAdapter()).toBe(a);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('setDefaultAIAdapter changes the default', () => {
|
|
102
|
+
const a = makeAdapter();
|
|
103
|
+
const b = makeAdapter();
|
|
104
|
+
registerAIAdapter(a, true);
|
|
105
|
+
registerAIAdapter(b, false);
|
|
106
|
+
const result = setDefaultAIAdapter(b.id);
|
|
107
|
+
expect(result).toBe(true);
|
|
108
|
+
expect(getDefaultAIAdapter()).toBe(b);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('setDefaultAIAdapter returns false for unknown id', () => {
|
|
112
|
+
expect(setDefaultAIAdapter('nonexistent-id')).toBe(false);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('setDefaultAIAdapter does not change default when id not found', () => {
|
|
116
|
+
const a = makeAdapter();
|
|
117
|
+
registerAIAdapter(a, true);
|
|
118
|
+
setDefaultAIAdapter('nope');
|
|
119
|
+
expect(getDefaultAIAdapter()).toBe(a);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// --- unregisterAIAdapter ---
|
|
124
|
+
describe('unregisterAIAdapter', () => {
|
|
125
|
+
it('removes adapter from registry', () => {
|
|
126
|
+
const a = makeAdapter();
|
|
127
|
+
registerAIAdapter(a, false);
|
|
128
|
+
expect(unregisterAIAdapter(a.id)).toBe(true);
|
|
129
|
+
expect(getAIAdapter(a.id)).toBeUndefined();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('returns false for unknown id', () => {
|
|
133
|
+
expect(unregisterAIAdapter('definitely-not-registered')).toBe(false);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('removes adapter from listAIAdapters', () => {
|
|
137
|
+
const a = makeAdapter();
|
|
138
|
+
registerAIAdapter(a, false);
|
|
139
|
+
unregisterAIAdapter(a.id);
|
|
140
|
+
const ids = listAIAdapters().map((x) => x.id);
|
|
141
|
+
expect(ids).not.toContain(a.id);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('default falls back to another adapter when current default is removed', () => {
|
|
145
|
+
const a = makeAdapter();
|
|
146
|
+
const b = makeAdapter();
|
|
147
|
+
registerAIAdapter(a, true);
|
|
148
|
+
registerAIAdapter(b, false);
|
|
149
|
+
unregisterAIAdapter(a.id);
|
|
150
|
+
// Should fall back to some remaining adapter (not null if b is still registered)
|
|
151
|
+
const def = getDefaultAIAdapter();
|
|
152
|
+
expect(def === null || def!.id !== a.id).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// --- listAIAdapters ---
|
|
157
|
+
describe('listAIAdapters', () => {
|
|
158
|
+
it('returns array with id and name for each adapter', () => {
|
|
159
|
+
const a = makeAdapter();
|
|
160
|
+
registerAIAdapter(a, false);
|
|
161
|
+
const list = listAIAdapters();
|
|
162
|
+
const entry = list.find((x) => x.id === a.id);
|
|
163
|
+
expect(entry).toBeDefined();
|
|
164
|
+
expect(entry!.name).toBe(a.name);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('each entry only has id and name (no extra methods)', () => {
|
|
168
|
+
const a = makeAdapter();
|
|
169
|
+
registerAIAdapter(a, false);
|
|
170
|
+
const list = listAIAdapters();
|
|
171
|
+
const entry = list.find((x) => x.id === a.id)!;
|
|
172
|
+
expect(Object.keys(entry)).toEqual(['id', 'name']);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// --- generateHoloScript convenience wrapper ---
|
|
177
|
+
describe('generateHoloScript (convenience)', () => {
|
|
178
|
+
it('delegates to default adapter', async () => {
|
|
179
|
+
const a = makeAdapter();
|
|
180
|
+
registerAIAdapter(a, true);
|
|
181
|
+
const result = await generateHoloScript('a spinning cube');
|
|
182
|
+
expect(result.holoScript).toContain('Test');
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('throws when no adapter is registered', async () => {
|
|
186
|
+
// We cannot guarantee no adapter is registered in a shared module,
|
|
187
|
+
// so we test by expecting the resolved value to be defined only if adapter is set.
|
|
188
|
+
// Instead test the "no generate support" path:
|
|
189
|
+
const noGenAdapter = makeAdapter({ generateHoloScript: undefined });
|
|
190
|
+
registerAIAdapter(noGenAdapter, true);
|
|
191
|
+
await expect(generateHoloScript('test')).rejects.toThrow(/does not support generateHoloScript/);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// --- explainHoloScript convenience wrapper ---
|
|
196
|
+
describe('explainHoloScript (convenience)', () => {
|
|
197
|
+
it('delegates to default adapter', async () => {
|
|
198
|
+
const a = makeAdapter();
|
|
199
|
+
registerAIAdapter(a, true);
|
|
200
|
+
const result = await explainHoloScript('object "Cube" {}');
|
|
201
|
+
expect(result.explanation).toContain('cube');
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('throws when adapter does not support explain', async () => {
|
|
205
|
+
const noExplain = makeAdapter({ explainHoloScript: undefined });
|
|
206
|
+
registerAIAdapter(noExplain, true);
|
|
207
|
+
await expect(explainHoloScript('object "X" {}')).rejects.toThrow(
|
|
208
|
+
/does not support explainHoloScript/
|
|
209
|
+
);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// --- optimizeHoloScript convenience wrapper ---
|
|
214
|
+
describe('optimizeHoloScript (convenience)', () => {
|
|
215
|
+
it('delegates to default adapter', async () => {
|
|
216
|
+
const a = makeAdapter();
|
|
217
|
+
registerAIAdapter(a, true);
|
|
218
|
+
const result = await optimizeHoloScript('object "X" {}', 'mobile');
|
|
219
|
+
expect(result.improvements.length).toBeGreaterThan(0);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('throws when adapter does not support optimize', async () => {
|
|
223
|
+
const noOpt = makeAdapter({ optimizeHoloScript: undefined });
|
|
224
|
+
registerAIAdapter(noOpt, true);
|
|
225
|
+
await expect(optimizeHoloScript('code', 'vr')).rejects.toThrow(
|
|
226
|
+
/does not support optimizeHoloScript/
|
|
227
|
+
);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// --- fixHoloScript convenience wrapper ---
|
|
232
|
+
describe('fixHoloScript (convenience)', () => {
|
|
233
|
+
it('delegates to default adapter', async () => {
|
|
234
|
+
const a = makeAdapter();
|
|
235
|
+
registerAIAdapter(a, true);
|
|
236
|
+
const result = await fixHoloScript('object "X" {}', ['missing brace', 'unknown property']);
|
|
237
|
+
expect(result.fixes).toHaveLength(2);
|
|
238
|
+
expect(result.fixes[0].fix).toBe('auto-fixed');
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('throws when adapter does not support fix', async () => {
|
|
242
|
+
const noFix = makeAdapter({ fixHoloScript: undefined });
|
|
243
|
+
registerAIAdapter(noFix, true);
|
|
244
|
+
await expect(fixHoloScript('code', ['err'])).rejects.toThrow(/does not support fixHoloScript/);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('fix result has correct structure', async () => {
|
|
248
|
+
const a = makeAdapter();
|
|
249
|
+
registerAIAdapter(a, true);
|
|
250
|
+
const result = await fixHoloScript('code', ['err1', 'err2', 'err3']);
|
|
251
|
+
expect(result.holoScript).toBeTruthy();
|
|
252
|
+
expect(Array.isArray(result.fixes)).toBe(true);
|
|
253
|
+
for (const fix of result.fixes) {
|
|
254
|
+
expect(typeof fix.line).toBe('number');
|
|
255
|
+
expect(typeof fix.issue).toBe('string');
|
|
256
|
+
expect(typeof fix.fix).toBe('string');
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
});
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
registerAIAdapter,
|
|
4
|
+
getAIAdapter,
|
|
5
|
+
getDefaultAIAdapter,
|
|
6
|
+
setDefaultAIAdapter,
|
|
7
|
+
listAIAdapters,
|
|
8
|
+
unregisterAIAdapter,
|
|
9
|
+
generateHoloScript,
|
|
10
|
+
explainHoloScript,
|
|
11
|
+
type AIAdapter,
|
|
12
|
+
} from '../AIAdapter';
|
|
13
|
+
|
|
14
|
+
function mockAdapter(id: string, name = id): AIAdapter {
|
|
15
|
+
return {
|
|
16
|
+
id,
|
|
17
|
+
name,
|
|
18
|
+
isReady: () => true,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// The registry uses module-level state, so we need to clean up
|
|
23
|
+
function clearRegistry() {
|
|
24
|
+
for (const a of listAIAdapters()) {
|
|
25
|
+
unregisterAIAdapter(a.id);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('AIAdapter Registry', () => {
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
clearRegistry();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('registerAIAdapter stores adapter', () => {
|
|
35
|
+
registerAIAdapter(mockAdapter('test'));
|
|
36
|
+
expect(getAIAdapter('test')).toBeDefined();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('first registered becomes default', () => {
|
|
40
|
+
registerAIAdapter(mockAdapter('a'));
|
|
41
|
+
expect(getDefaultAIAdapter()?.id).toBe('a');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('setAsDefault overrides default', () => {
|
|
45
|
+
registerAIAdapter(mockAdapter('a'));
|
|
46
|
+
registerAIAdapter(mockAdapter('b'), true);
|
|
47
|
+
expect(getDefaultAIAdapter()?.id).toBe('b');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('getAIAdapter returns undefined for missing', () => {
|
|
51
|
+
expect(getAIAdapter('nope')).toBeUndefined();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('setDefaultAIAdapter by id', () => {
|
|
55
|
+
registerAIAdapter(mockAdapter('a'));
|
|
56
|
+
registerAIAdapter(mockAdapter('b'));
|
|
57
|
+
expect(setDefaultAIAdapter('a')).toBe(true);
|
|
58
|
+
expect(getDefaultAIAdapter()?.id).toBe('a');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('setDefaultAIAdapter returns false for missing', () => {
|
|
62
|
+
expect(setDefaultAIAdapter('nope')).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('listAIAdapters returns all', () => {
|
|
66
|
+
registerAIAdapter(mockAdapter('a', 'Alpha'));
|
|
67
|
+
registerAIAdapter(mockAdapter('b', 'Beta'));
|
|
68
|
+
const list = listAIAdapters();
|
|
69
|
+
expect(list).toHaveLength(2);
|
|
70
|
+
expect(list.map((l) => l.id)).toContain('a');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('unregisterAIAdapter removes adapter', () => {
|
|
74
|
+
registerAIAdapter(mockAdapter('a'));
|
|
75
|
+
expect(unregisterAIAdapter('a')).toBe(true);
|
|
76
|
+
expect(getAIAdapter('a')).toBeUndefined();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('unregisterAIAdapter returns false for missing', () => {
|
|
80
|
+
expect(unregisterAIAdapter('nope')).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('unregister default promotes next', () => {
|
|
84
|
+
registerAIAdapter(mockAdapter('a'));
|
|
85
|
+
registerAIAdapter(mockAdapter('b'));
|
|
86
|
+
unregisterAIAdapter('a');
|
|
87
|
+
expect(getDefaultAIAdapter()?.id).toBe('b');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('unregister all sets default to null', () => {
|
|
91
|
+
registerAIAdapter(mockAdapter('a'));
|
|
92
|
+
unregisterAIAdapter('a');
|
|
93
|
+
expect(getDefaultAIAdapter()).toBeNull();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// --- Convenience functions ---
|
|
97
|
+
it('generateHoloScript throws without adapter', async () => {
|
|
98
|
+
await expect(generateHoloScript('test')).rejects.toThrow('No AI adapter registered');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('generateHoloScript throws if adapter lacks method', async () => {
|
|
102
|
+
registerAIAdapter(mockAdapter('a'));
|
|
103
|
+
await expect(generateHoloScript('test')).rejects.toThrow('does not support');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('explainHoloScript throws without adapter', async () => {
|
|
107
|
+
await expect(explainHoloScript('code')).rejects.toThrow('No AI adapter registered');
|
|
108
|
+
});
|
|
109
|
+
});
|