@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,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Adapters — Production Tests (sync/configuration surface)
|
|
3
|
+
*
|
|
4
|
+
* Tests: OpenAIAdapter, AnthropicAdapter, OllamaAdapter, LMStudioAdapter,
|
|
5
|
+
* GeminiAdapter — constructor defaults, isReady(), factory functions,
|
|
6
|
+
* and id/name fields. Network calls require real keys; we skip those
|
|
7
|
+
* and focus entirely on the synchronous, pure-logic surface.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, it, expect } from 'vitest';
|
|
11
|
+
import {
|
|
12
|
+
OpenAIAdapter,
|
|
13
|
+
AnthropicAdapter,
|
|
14
|
+
OllamaAdapter,
|
|
15
|
+
LMStudioAdapter,
|
|
16
|
+
GeminiAdapter,
|
|
17
|
+
useOpenAI,
|
|
18
|
+
useAnthropic,
|
|
19
|
+
useOllama,
|
|
20
|
+
useLMStudio,
|
|
21
|
+
} from '../adapters';
|
|
22
|
+
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// OpenAIAdapter
|
|
25
|
+
// =============================================================================
|
|
26
|
+
|
|
27
|
+
describe('OpenAIAdapter', () => {
|
|
28
|
+
it('has id="openai" and name="OpenAI"', () => {
|
|
29
|
+
const a = new OpenAIAdapter({ apiKey: 'sk-test' });
|
|
30
|
+
expect(a.id).toBe('openai');
|
|
31
|
+
expect(a.name).toBe('OpenAI');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('isReady() returns true when apiKey is present', () => {
|
|
35
|
+
expect(new OpenAIAdapter({ apiKey: 'sk-test' }).isReady()).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('isReady() returns false when apiKey is empty string', () => {
|
|
39
|
+
expect(new OpenAIAdapter({ apiKey: '' }).isReady()).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('accepts custom model override', () => {
|
|
43
|
+
// No direct getter — but constructor should not throw
|
|
44
|
+
expect(() => new OpenAIAdapter({ apiKey: 'x', model: 'gpt-4' })).not.toThrow();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('accepts custom baseUrl', () => {
|
|
48
|
+
expect(
|
|
49
|
+
() =>
|
|
50
|
+
new OpenAIAdapter({
|
|
51
|
+
apiKey: 'x',
|
|
52
|
+
baseUrl: 'https://my-proxy.com/v1',
|
|
53
|
+
})
|
|
54
|
+
).not.toThrow();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('accepts organization field', () => {
|
|
58
|
+
expect(
|
|
59
|
+
() =>
|
|
60
|
+
new OpenAIAdapter({
|
|
61
|
+
apiKey: 'x',
|
|
62
|
+
organization: 'org-123',
|
|
63
|
+
})
|
|
64
|
+
).not.toThrow();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// =============================================================================
|
|
69
|
+
// AnthropicAdapter
|
|
70
|
+
// =============================================================================
|
|
71
|
+
|
|
72
|
+
describe('AnthropicAdapter', () => {
|
|
73
|
+
it('has id="anthropic" and name="Anthropic Claude"', () => {
|
|
74
|
+
const a = new AnthropicAdapter({ apiKey: 'ant-test' });
|
|
75
|
+
expect(a.id).toBe('anthropic');
|
|
76
|
+
expect(a.name).toBe('Anthropic Claude');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('isReady() returns true when apiKey present', () => {
|
|
80
|
+
expect(new AnthropicAdapter({ apiKey: 'ant-test' }).isReady()).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('isReady() returns false when apiKey is empty', () => {
|
|
84
|
+
expect(new AnthropicAdapter({ apiKey: '' }).isReady()).toBe(false);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('accepts custom model', () => {
|
|
88
|
+
expect(
|
|
89
|
+
() =>
|
|
90
|
+
new AnthropicAdapter({
|
|
91
|
+
apiKey: 'x',
|
|
92
|
+
model: 'claude-3-opus',
|
|
93
|
+
})
|
|
94
|
+
).not.toThrow();
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// =============================================================================
|
|
99
|
+
// OllamaAdapter
|
|
100
|
+
// =============================================================================
|
|
101
|
+
|
|
102
|
+
describe('OllamaAdapter', () => {
|
|
103
|
+
it('has id="ollama" and name contains "Ollama"', () => {
|
|
104
|
+
const a = new OllamaAdapter();
|
|
105
|
+
expect(a.id).toBe('ollama');
|
|
106
|
+
expect(a.name).toContain('Ollama');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('constructs with no config (defaults)', () => {
|
|
110
|
+
expect(() => new OllamaAdapter()).not.toThrow();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('accepts custom baseUrl', () => {
|
|
114
|
+
expect(() => new OllamaAdapter({ baseUrl: 'http://192.168.1.1:11434' })).not.toThrow();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('accepts custom model', () => {
|
|
118
|
+
expect(() => new OllamaAdapter({ model: 'llama3:8b' })).not.toThrow();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('isReady() method exists and is callable', () => {
|
|
122
|
+
// isReady is async for Ollama — just verify it returns a Promise
|
|
123
|
+
const a = new OllamaAdapter({ baseUrl: 'http://localhost:11434' });
|
|
124
|
+
expect(typeof a.isReady).toBe('function');
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// =============================================================================
|
|
129
|
+
// LMStudioAdapter
|
|
130
|
+
// =============================================================================
|
|
131
|
+
|
|
132
|
+
describe('LMStudioAdapter', () => {
|
|
133
|
+
it('has id="lmstudio" and name contains "LM Studio"', () => {
|
|
134
|
+
const a = new LMStudioAdapter();
|
|
135
|
+
expect(a.id).toBe('lmstudio');
|
|
136
|
+
expect(a.name).toContain('LM Studio');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('isReady() always returns true', () => {
|
|
140
|
+
expect(new LMStudioAdapter().isReady()).toBe(true);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('constructs with no config', () => {
|
|
144
|
+
expect(() => new LMStudioAdapter()).not.toThrow();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('accepts custom baseUrl', () => {
|
|
148
|
+
expect(() => new LMStudioAdapter({ baseUrl: 'http://localhost:1234/v1' })).not.toThrow();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('accepts custom model', () => {
|
|
152
|
+
expect(() => new LMStudioAdapter({ model: 'mistral-7b' })).not.toThrow();
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// =============================================================================
|
|
157
|
+
// GeminiAdapter
|
|
158
|
+
// =============================================================================
|
|
159
|
+
|
|
160
|
+
describe('GeminiAdapter', () => {
|
|
161
|
+
it('has id="gemini" and name="Google Gemini"', () => {
|
|
162
|
+
const a = new GeminiAdapter({ apiKey: 'gem-test' });
|
|
163
|
+
expect(a.id).toBe('gemini');
|
|
164
|
+
expect(a.name).toBe('Google Gemini');
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('isReady() returns true when apiKey present', () => {
|
|
168
|
+
expect(new GeminiAdapter({ apiKey: 'gem-key' }).isReady()).toBe(true);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('isReady() returns false when apiKey missing', () => {
|
|
172
|
+
expect(new GeminiAdapter({ apiKey: '' }).isReady()).toBe(false);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('accepts custom model', () => {
|
|
176
|
+
expect(
|
|
177
|
+
() =>
|
|
178
|
+
new GeminiAdapter({
|
|
179
|
+
apiKey: 'x',
|
|
180
|
+
model: 'gemini-1.5-pro',
|
|
181
|
+
})
|
|
182
|
+
).not.toThrow();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('accepts custom embeddingModel', () => {
|
|
186
|
+
expect(
|
|
187
|
+
() =>
|
|
188
|
+
new GeminiAdapter({
|
|
189
|
+
apiKey: 'x',
|
|
190
|
+
embeddingModel: 'text-multilingual-embedding-002',
|
|
191
|
+
})
|
|
192
|
+
).not.toThrow();
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// =============================================================================
|
|
197
|
+
// Factory functions (useOpenAI, useAnthropic, useOllama, useLMStudio)
|
|
198
|
+
// =============================================================================
|
|
199
|
+
|
|
200
|
+
describe('Factory functions', () => {
|
|
201
|
+
it('useOpenAI returns an OpenAIAdapter instance', () => {
|
|
202
|
+
const a = useOpenAI({ apiKey: 'sk-test' });
|
|
203
|
+
expect(a).toBeInstanceOf(OpenAIAdapter);
|
|
204
|
+
expect(a.id).toBe('openai');
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('useAnthropic returns an AnthropicAdapter instance', () => {
|
|
208
|
+
const a = useAnthropic({ apiKey: 'ant-test' });
|
|
209
|
+
expect(a).toBeInstanceOf(AnthropicAdapter);
|
|
210
|
+
expect(a.id).toBe('anthropic');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('useOllama returns an OllamaAdapter instance', () => {
|
|
214
|
+
const a = useOllama();
|
|
215
|
+
expect(a).toBeInstanceOf(OllamaAdapter);
|
|
216
|
+
expect(a.id).toBe('ollama');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('useLMStudio returns an LMStudioAdapter instance', () => {
|
|
220
|
+
const a = useLMStudio();
|
|
221
|
+
expect(a).toBeInstanceOf(LMStudioAdapter);
|
|
222
|
+
expect(a.id).toBe('lmstudio');
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('useOpenAI passes config (isReady reflects key)', () => {
|
|
226
|
+
const a = useOpenAI({ apiKey: 'sk-abc123' });
|
|
227
|
+
expect(a.isReady()).toBe(true);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('useAnthropic isReady reflects provided key', () => {
|
|
231
|
+
const a = useAnthropic({ apiKey: 'ant-xyz' });
|
|
232
|
+
expect(a.isReady()).toBe(true);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// =============================================================================
|
|
237
|
+
// Adapter interface conformance
|
|
238
|
+
// =============================================================================
|
|
239
|
+
|
|
240
|
+
describe('Adapter interface conformance', () => {
|
|
241
|
+
const adapters = [
|
|
242
|
+
new OpenAIAdapter({ apiKey: 'sk-test' }),
|
|
243
|
+
new AnthropicAdapter({ apiKey: 'ant-test' }),
|
|
244
|
+
new OllamaAdapter(),
|
|
245
|
+
new LMStudioAdapter(),
|
|
246
|
+
new GeminiAdapter({ apiKey: 'gem-test' }),
|
|
247
|
+
];
|
|
248
|
+
|
|
249
|
+
for (const adapter of adapters) {
|
|
250
|
+
it(`${adapter.id} has required methods`, () => {
|
|
251
|
+
expect(typeof adapter.generateHoloScript).toBe('function');
|
|
252
|
+
expect(typeof adapter.explainHoloScript).toBe('function');
|
|
253
|
+
expect(typeof adapter.optimizeHoloScript).toBe('function');
|
|
254
|
+
expect(typeof adapter.fixHoloScript).toBe('function');
|
|
255
|
+
expect(typeof adapter.chat).toBe('function');
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it(`${adapter.id} has non-empty id and name`, () => {
|
|
259
|
+
expect(adapter.id.length).toBeGreaterThan(0);
|
|
260
|
+
expect(adapter.name.length).toBeGreaterThan(0);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
});
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
OpenAIAdapter,
|
|
4
|
+
AnthropicAdapter,
|
|
5
|
+
OllamaAdapter,
|
|
6
|
+
LMStudioAdapter,
|
|
7
|
+
GeminiAdapter,
|
|
8
|
+
XAIAdapter,
|
|
9
|
+
TogetherAdapter,
|
|
10
|
+
} from '../adapters';
|
|
11
|
+
|
|
12
|
+
// Mock fetch globally
|
|
13
|
+
const mockFetch = vi.fn();
|
|
14
|
+
vi.stubGlobal('fetch', mockFetch);
|
|
15
|
+
|
|
16
|
+
function mockOKResponse(body: any) {
|
|
17
|
+
return {
|
|
18
|
+
ok: true,
|
|
19
|
+
status: 200,
|
|
20
|
+
statusText: 'OK',
|
|
21
|
+
json: async () => body,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function mockErrorResponse(status: number, statusText: string = 'Error') {
|
|
26
|
+
return {
|
|
27
|
+
ok: false,
|
|
28
|
+
status,
|
|
29
|
+
statusText,
|
|
30
|
+
json: async () => ({}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe('AI Adapters', () => {
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
vi.clearAllMocks();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// ==============================
|
|
40
|
+
// OpenAI
|
|
41
|
+
// ==============================
|
|
42
|
+
describe('OpenAIAdapter', () => {
|
|
43
|
+
let adapter: OpenAIAdapter;
|
|
44
|
+
|
|
45
|
+
beforeEach(() => {
|
|
46
|
+
adapter = new OpenAIAdapter({ apiKey: 'test-key' });
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('has correct id and name', () => {
|
|
50
|
+
expect(adapter.id).toBe('openai');
|
|
51
|
+
expect(adapter.name).toBe('OpenAI');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('isReady returns true with api key', () => {
|
|
55
|
+
expect(adapter.isReady()).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('isReady returns false without api key', () => {
|
|
59
|
+
const empty = new OpenAIAdapter({ apiKey: '' });
|
|
60
|
+
expect(empty.isReady()).toBe(false);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('uses custom model', () => {
|
|
64
|
+
const custom = new OpenAIAdapter({ apiKey: 'key', model: 'gpt-4' });
|
|
65
|
+
expect(custom.isReady()).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('generateHoloScript calls fetch and extracts code', async () => {
|
|
69
|
+
mockFetch.mockResolvedValueOnce(
|
|
70
|
+
mockOKResponse({
|
|
71
|
+
choices: [{ message: { content: '```holoscript\ncomposition test {}\n```' } }],
|
|
72
|
+
})
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const result = await adapter.generateHoloScript('make a cube');
|
|
76
|
+
expect(result.holoScript).toBe('composition test {}');
|
|
77
|
+
expect(result.confidence).toBe(0.85);
|
|
78
|
+
expect(mockFetch).toHaveBeenCalledTimes(1);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('throws on 429 rate limit', async () => {
|
|
82
|
+
mockFetch.mockResolvedValueOnce(mockErrorResponse(429));
|
|
83
|
+
await expect(adapter.explainHoloScript('test')).rejects.toThrow('rate limited');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('throws on 401 auth error', async () => {
|
|
87
|
+
mockFetch.mockResolvedValueOnce(mockErrorResponse(401));
|
|
88
|
+
await expect(adapter.explainHoloScript('test')).rejects.toThrow('auth failed');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('getEmbeddings returns vectors', async () => {
|
|
92
|
+
mockFetch.mockResolvedValueOnce(
|
|
93
|
+
mockOKResponse({
|
|
94
|
+
data: [{ embedding: [0.1, 0.2, 0.3] }],
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
const result = await adapter.getEmbeddings('test text');
|
|
99
|
+
expect(result).toEqual([[0.1, 0.2, 0.3]]);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// ==============================
|
|
104
|
+
// Anthropic
|
|
105
|
+
// ==============================
|
|
106
|
+
describe('AnthropicAdapter', () => {
|
|
107
|
+
let adapter: AnthropicAdapter;
|
|
108
|
+
|
|
109
|
+
beforeEach(() => {
|
|
110
|
+
adapter = new AnthropicAdapter({ apiKey: 'test-key' });
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('has correct id and name', () => {
|
|
114
|
+
expect(adapter.id).toBe('anthropic');
|
|
115
|
+
expect(adapter.name).toBe('Anthropic Claude');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('isReady returns true with api key', () => {
|
|
119
|
+
expect(adapter.isReady()).toBe(true);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('generateHoloScript calls Anthropic API', async () => {
|
|
123
|
+
mockFetch.mockResolvedValueOnce(
|
|
124
|
+
mockOKResponse({
|
|
125
|
+
content: [{ text: '```holo\ncomposition room {}\n```' }],
|
|
126
|
+
})
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const result = await adapter.generateHoloScript('make a room');
|
|
130
|
+
expect(result.holoScript).toBe('composition room {}');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('getEmbeddings returns mock vectors', async () => {
|
|
134
|
+
const result = await adapter.getEmbeddings('test');
|
|
135
|
+
expect(result.length).toBe(1);
|
|
136
|
+
expect(result[0].length).toBe(1024);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// ==============================
|
|
141
|
+
// Ollama
|
|
142
|
+
// ==============================
|
|
143
|
+
describe('OllamaAdapter', () => {
|
|
144
|
+
let adapter: OllamaAdapter;
|
|
145
|
+
|
|
146
|
+
beforeEach(() => {
|
|
147
|
+
adapter = new OllamaAdapter();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('has correct id and name', () => {
|
|
151
|
+
expect(adapter.id).toBe('ollama');
|
|
152
|
+
expect(adapter.name).toBe('Ollama (Local)');
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('isReady checks API availability', async () => {
|
|
156
|
+
mockFetch.mockResolvedValueOnce({ ok: true });
|
|
157
|
+
const ready = await adapter.isReady();
|
|
158
|
+
expect(ready).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('isReady returns false on network error', async () => {
|
|
162
|
+
mockFetch.mockRejectedValueOnce(new Error('ECONNREFUSED'));
|
|
163
|
+
const ready = await adapter.isReady();
|
|
164
|
+
expect(ready).toBe(false);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('generateHoloScript calls local API', async () => {
|
|
168
|
+
mockFetch.mockResolvedValueOnce(
|
|
169
|
+
mockOKResponse({
|
|
170
|
+
response: 'composition cube { geometry: "cube" }',
|
|
171
|
+
})
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
const result = await adapter.generateHoloScript('a cube');
|
|
175
|
+
expect(result.holoScript).toBe('composition cube { geometry: "cube" }');
|
|
176
|
+
expect(result.confidence).toBe(0.75);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// ==============================
|
|
181
|
+
// LMStudio
|
|
182
|
+
// ==============================
|
|
183
|
+
describe('LMStudioAdapter', () => {
|
|
184
|
+
let adapter: LMStudioAdapter;
|
|
185
|
+
|
|
186
|
+
beforeEach(() => {
|
|
187
|
+
adapter = new LMStudioAdapter();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('has correct id and name', () => {
|
|
191
|
+
expect(adapter.id).toBe('lmstudio');
|
|
192
|
+
expect(adapter.name).toBe('LM Studio (Local)');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('isReady always returns true', () => {
|
|
196
|
+
expect(adapter.isReady()).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('delegates generateHoloScript to OpenAI adapter', async () => {
|
|
200
|
+
mockFetch.mockResolvedValueOnce(
|
|
201
|
+
mockOKResponse({
|
|
202
|
+
choices: [{ message: { content: 'test output' } }],
|
|
203
|
+
})
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const result = await adapter.generateHoloScript('test');
|
|
207
|
+
expect(result.holoScript).toBe('test output');
|
|
208
|
+
// Verify it used localhost:1234 (LM Studio default)
|
|
209
|
+
expect(mockFetch).toHaveBeenCalledWith(
|
|
210
|
+
expect.stringContaining('localhost:1234'),
|
|
211
|
+
expect.any(Object)
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// ==============================
|
|
217
|
+
// Gemini
|
|
218
|
+
// ==============================
|
|
219
|
+
describe('GeminiAdapter', () => {
|
|
220
|
+
let adapter: GeminiAdapter;
|
|
221
|
+
|
|
222
|
+
beforeEach(() => {
|
|
223
|
+
adapter = new GeminiAdapter({ apiKey: 'test-key' });
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('has correct id and name', () => {
|
|
227
|
+
expect(adapter.id).toBe('gemini');
|
|
228
|
+
expect(adapter.name).toBe('Google Gemini');
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('isReady returns true with api key', () => {
|
|
232
|
+
expect(adapter.isReady()).toBe(true);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('generateHoloScript calls Gemini API', async () => {
|
|
236
|
+
mockFetch.mockResolvedValueOnce(
|
|
237
|
+
mockOKResponse({
|
|
238
|
+
candidates: [{ content: { parts: [{ text: 'composition sphere {}' }] } }],
|
|
239
|
+
})
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
const result = await adapter.generateHoloScript('a sphere');
|
|
243
|
+
expect(result.holoScript).toBe('composition sphere {}');
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('getEmbeddings calls embedding API', async () => {
|
|
247
|
+
mockFetch.mockResolvedValueOnce(
|
|
248
|
+
mockOKResponse({
|
|
249
|
+
embedding: { values: [0.5, 0.6, 0.7] },
|
|
250
|
+
})
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
const result = await adapter.getEmbeddings('test');
|
|
254
|
+
expect(result).toEqual([[0.5, 0.6, 0.7]]);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// ==============================
|
|
259
|
+
// XAI (Grok)
|
|
260
|
+
// ==============================
|
|
261
|
+
describe('XAIAdapter', () => {
|
|
262
|
+
let adapter: XAIAdapter;
|
|
263
|
+
|
|
264
|
+
beforeEach(() => {
|
|
265
|
+
adapter = new XAIAdapter({ apiKey: 'test-key' });
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('has correct id and name', () => {
|
|
269
|
+
expect(adapter.id).toBe('xai');
|
|
270
|
+
expect(adapter.name).toBe('xAI Grok');
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('isReady returns true with api key', () => {
|
|
274
|
+
expect(adapter.isReady()).toBe(true);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('generateHoloScript calls xAI API', async () => {
|
|
278
|
+
mockFetch.mockResolvedValueOnce(
|
|
279
|
+
mockOKResponse({
|
|
280
|
+
choices: [{ message: { content: '```holo\nscene {}\n```' } }],
|
|
281
|
+
})
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
const result = await adapter.generateHoloScript('test');
|
|
285
|
+
expect(result.holoScript).toBe('scene {}');
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
// ==============================
|
|
290
|
+
// Together AI
|
|
291
|
+
// ==============================
|
|
292
|
+
describe('TogetherAdapter', () => {
|
|
293
|
+
let adapter: TogetherAdapter;
|
|
294
|
+
|
|
295
|
+
beforeEach(() => {
|
|
296
|
+
adapter = new TogetherAdapter({ apiKey: 'test-key' });
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('has correct id and name', () => {
|
|
300
|
+
expect(adapter.id).toBe('together');
|
|
301
|
+
expect(adapter.name).toBe('Together AI');
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('isReady returns true with api key', () => {
|
|
305
|
+
expect(adapter.isReady()).toBe(true);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('generateHoloScript calls Together API', async () => {
|
|
309
|
+
mockFetch.mockResolvedValueOnce(
|
|
310
|
+
mockOKResponse({
|
|
311
|
+
choices: [{ message: { content: 'output' } }],
|
|
312
|
+
})
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
const result = await adapter.generateHoloScript('test');
|
|
316
|
+
expect(result.holoScript).toBe('output');
|
|
317
|
+
expect(result.confidence).toBe(0.8);
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
});
|