@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,1585 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @holoscript/core - Built-in AI Adapters
|
|
3
|
+
*
|
|
4
|
+
* Ready-to-use adapters for popular AI providers.
|
|
5
|
+
* Users just need to provide their API key.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
AIAdapter,
|
|
10
|
+
GenerateResult,
|
|
11
|
+
ExplainResult,
|
|
12
|
+
OptimizeResult,
|
|
13
|
+
FixResult,
|
|
14
|
+
GenerateOptions,
|
|
15
|
+
} from './AIAdapter';
|
|
16
|
+
/** Shape of API error responses from AI providers. */
|
|
17
|
+
interface APIErrorResponse {
|
|
18
|
+
error?: { message?: string };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type {
|
|
22
|
+
AIAdapter,
|
|
23
|
+
GenerateResult,
|
|
24
|
+
ExplainResult,
|
|
25
|
+
OptimizeResult,
|
|
26
|
+
FixResult,
|
|
27
|
+
GenerateOptions,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// System Prompt for HoloScript Generation
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
const HOLOSCRIPT_SYSTEM_PROMPT = `You are a HoloScript expert. HoloScript is a visual flow language for VR/AR world creation.
|
|
35
|
+
|
|
36
|
+
Generate valid HoloScript code following this syntax:
|
|
37
|
+
|
|
38
|
+
COMPOSITIONS:
|
|
39
|
+
composition "Scene Name" {
|
|
40
|
+
environment { skybox: "sky_day", ambient: 0.5 }
|
|
41
|
+
|
|
42
|
+
template "ObjectType" {
|
|
43
|
+
state { property: value }
|
|
44
|
+
action doSomething() { }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
spatial_group "GroupName" {
|
|
48
|
+
object "Object1" { position: [x, y, z] }
|
|
49
|
+
object "Object2" using "ObjectType" { position: [x, y, z] }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
logic {
|
|
53
|
+
on_event { action() }
|
|
54
|
+
every(1000) { periodic_action() }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
SHAPES: cube, sphere, cylinder, cone, plane, torus, capsule, pyramid, prism, hexagon, octahedron, icosahedron, ring, tube, spiral, stairs, arch, dome, wedge, ramp
|
|
59
|
+
|
|
60
|
+
TRAITS: @grabbable, @throwable, @hoverable, @interactive, @collidable, @animatable, @networked
|
|
61
|
+
|
|
62
|
+
RULES:
|
|
63
|
+
1. Use descriptive object names
|
|
64
|
+
2. Position objects logically in 3D space (y is up)
|
|
65
|
+
3. Include templates for reusable objects
|
|
66
|
+
4. Add logic for interactivity
|
|
67
|
+
5. Output ONLY valid HoloScript code, no explanations unless asked`;
|
|
68
|
+
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// OpenAI Adapter
|
|
71
|
+
// ============================================================================
|
|
72
|
+
|
|
73
|
+
export interface OpenAIAdapterConfig {
|
|
74
|
+
apiKey: string;
|
|
75
|
+
model?: string;
|
|
76
|
+
baseUrl?: string;
|
|
77
|
+
organization?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export class OpenAIAdapter implements AIAdapter {
|
|
81
|
+
readonly id = 'openai';
|
|
82
|
+
readonly name = 'OpenAI';
|
|
83
|
+
|
|
84
|
+
private config: OpenAIAdapterConfig;
|
|
85
|
+
private model: string;
|
|
86
|
+
|
|
87
|
+
constructor(config: OpenAIAdapterConfig) {
|
|
88
|
+
this.config = config;
|
|
89
|
+
this.model = config.model || 'gpt-4o-mini';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
isReady(): boolean {
|
|
93
|
+
return !!this.config.apiKey;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async generateHoloScript(prompt: string, options?: GenerateOptions): Promise<GenerateResult> {
|
|
97
|
+
const systemPrompt = this.buildSystemPrompt(options);
|
|
98
|
+
const response = await this.chat('Create a HoloScript scene: ' + prompt, undefined, [
|
|
99
|
+
{ role: 'assistant', content: systemPrompt },
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
holoScript: this.extractCode(response),
|
|
104
|
+
confidence: 0.85,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async explainHoloScript(holoScript: string): Promise<ExplainResult> {
|
|
109
|
+
const response = await this.callAPI([
|
|
110
|
+
{
|
|
111
|
+
role: 'system',
|
|
112
|
+
content: 'You are a HoloScript expert. Explain the following code clearly.',
|
|
113
|
+
},
|
|
114
|
+
{ role: 'user', content: 'Explain this HoloScript:\n\n' + holoScript },
|
|
115
|
+
]);
|
|
116
|
+
|
|
117
|
+
return { explanation: response };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async optimizeHoloScript(
|
|
121
|
+
holoScript: string,
|
|
122
|
+
target: 'mobile' | 'desktop' | 'vr' | 'ar'
|
|
123
|
+
): Promise<OptimizeResult> {
|
|
124
|
+
const response = await this.callAPI([
|
|
125
|
+
{
|
|
126
|
+
role: 'system',
|
|
127
|
+
content:
|
|
128
|
+
'You are a HoloScript optimizer. Optimize for ' +
|
|
129
|
+
target +
|
|
130
|
+
' platform. Return only the optimized code.',
|
|
131
|
+
},
|
|
132
|
+
{ role: 'user', content: holoScript },
|
|
133
|
+
]);
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
holoScript: this.extractCode(response),
|
|
137
|
+
improvements: ['Optimized for ' + target],
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async fixHoloScript(holoScript: string, errors: string[]): Promise<FixResult> {
|
|
142
|
+
const response = await this.callAPI([
|
|
143
|
+
{
|
|
144
|
+
role: 'system',
|
|
145
|
+
content: 'You are a HoloScript debugger. Fix the errors and return corrected code.',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
role: 'user',
|
|
149
|
+
content: 'Fix these errors:\n' + errors.join('\n') + '\n\nCode:\n' + holoScript,
|
|
150
|
+
},
|
|
151
|
+
]);
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
holoScript: this.extractCode(response),
|
|
155
|
+
fixes: errors.map((e) => ({ line: 0, issue: e, fix: 'auto-fixed' })),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async chat(
|
|
160
|
+
message: string,
|
|
161
|
+
holoScript?: string,
|
|
162
|
+
history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
163
|
+
): Promise<string> {
|
|
164
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
165
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
if (history) {
|
|
169
|
+
messages.push(...history);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (holoScript) {
|
|
173
|
+
messages.push({
|
|
174
|
+
role: 'user',
|
|
175
|
+
content: 'Context (current code):\n' + holoScript + '\n\nQuestion: ' + message,
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
messages.push({ role: 'user', content: message });
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return this.callAPI(messages, history);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private buildSystemPrompt(options?: GenerateOptions): string {
|
|
185
|
+
let prompt = HOLOSCRIPT_SYSTEM_PROMPT;
|
|
186
|
+
if (options?.style) prompt += '\nStyle: ' + options.style;
|
|
187
|
+
if (options?.complexity) prompt += '\nComplexity: ' + options.complexity;
|
|
188
|
+
if (options?.targetPlatform) prompt += '\nOptimize for: ' + options.targetPlatform;
|
|
189
|
+
return prompt;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private extractCode(response: string): string {
|
|
193
|
+
// Extract code from markdown code blocks
|
|
194
|
+
const match = response.match(/```(?:holoscript|holo)?\n([\s\S]*?)```/);
|
|
195
|
+
return match ? match[1].trim() : response.trim();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private async callAPI(
|
|
199
|
+
messages: Array<{ role: string; content: string }>,
|
|
200
|
+
_history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
201
|
+
): Promise<string> {
|
|
202
|
+
const baseUrl = this.config.baseUrl || 'https://api.openai.com/v1';
|
|
203
|
+
|
|
204
|
+
const headers: Record<string, string> = {
|
|
205
|
+
'Content-Type': 'application/json',
|
|
206
|
+
Authorization: 'Bearer ' + this.config.apiKey,
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
if (this.config.organization) {
|
|
210
|
+
headers['OpenAI-Organization'] = this.config.organization;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const response = await fetch(baseUrl + '/chat/completions', {
|
|
214
|
+
method: 'POST',
|
|
215
|
+
headers,
|
|
216
|
+
body: JSON.stringify({
|
|
217
|
+
model: this.model,
|
|
218
|
+
messages,
|
|
219
|
+
temperature: 0.7,
|
|
220
|
+
}),
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
if (response.status === 429) {
|
|
224
|
+
throw new Error('OpenAI rate limited (429) - please retry after backoff');
|
|
225
|
+
}
|
|
226
|
+
if (response.status === 401 || response.status === 403) {
|
|
227
|
+
throw new Error('OpenAI auth failed - check API key and permissions');
|
|
228
|
+
}
|
|
229
|
+
if (!response.ok) {
|
|
230
|
+
throw new Error('OpenAI API error: ' + response.statusText);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const data = await response.json();
|
|
234
|
+
return data.choices[0].message.content;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async getEmbeddings(text: string | string[]): Promise<number[][]> {
|
|
238
|
+
const baseUrl = this.config.baseUrl || 'https://api.openai.com/v1';
|
|
239
|
+
const inputs = Array.isArray(text) ? text : [text];
|
|
240
|
+
|
|
241
|
+
const response = await fetch(baseUrl + '/embeddings', {
|
|
242
|
+
method: 'POST',
|
|
243
|
+
headers: {
|
|
244
|
+
'Content-Type': 'application/json',
|
|
245
|
+
Authorization: 'Bearer ' + this.config.apiKey,
|
|
246
|
+
},
|
|
247
|
+
body: JSON.stringify({
|
|
248
|
+
model: 'text-embedding-3-small',
|
|
249
|
+
input: inputs,
|
|
250
|
+
}),
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
if (!response.ok) {
|
|
254
|
+
throw new Error('OpenAI Embeddings API error: ' + response.statusText);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const data = await response.json();
|
|
258
|
+
return data.data.map((item: { embedding: number[] }) => item.embedding);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// ============================================================================
|
|
263
|
+
// Anthropic (Claude) Adapter
|
|
264
|
+
// ============================================================================
|
|
265
|
+
|
|
266
|
+
export interface AnthropicAdapterConfig {
|
|
267
|
+
apiKey: string;
|
|
268
|
+
model?: string;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export class AnthropicAdapter implements AIAdapter {
|
|
272
|
+
readonly id = 'anthropic';
|
|
273
|
+
readonly name = 'Anthropic Claude';
|
|
274
|
+
|
|
275
|
+
private config: AnthropicAdapterConfig;
|
|
276
|
+
private model: string;
|
|
277
|
+
|
|
278
|
+
constructor(config: AnthropicAdapterConfig) {
|
|
279
|
+
this.config = config;
|
|
280
|
+
this.model = config.model || 'claude-3-5-sonnet-20241022';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
isReady(): boolean {
|
|
284
|
+
return !!this.config.apiKey;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async generateHoloScript(prompt: string, options?: GenerateOptions): Promise<GenerateResult> {
|
|
288
|
+
const messages: Array<{ role: 'user' | 'assistant'; content: string }> = [
|
|
289
|
+
{ role: 'user', content: 'Create a HoloScript scene: ' + prompt },
|
|
290
|
+
];
|
|
291
|
+
const response = await this.callAPI(messages, options);
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
holoScript: this.extractCode(response),
|
|
295
|
+
confidence: 0.85,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async explainHoloScript(holoScript: string): Promise<ExplainResult> {
|
|
300
|
+
const messages: Array<{ role: 'user' | 'assistant'; content: string }> = [
|
|
301
|
+
{ role: 'user', content: 'Explain this HoloScript code clearly:\n\n' + holoScript },
|
|
302
|
+
];
|
|
303
|
+
const response = await this.callAPI(messages);
|
|
304
|
+
return { explanation: response };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async optimizeHoloScript(
|
|
308
|
+
holoScript: string,
|
|
309
|
+
target: 'mobile' | 'desktop' | 'vr' | 'ar'
|
|
310
|
+
): Promise<OptimizeResult> {
|
|
311
|
+
const messages: Array<{ role: 'user' | 'assistant'; content: string }> = [
|
|
312
|
+
{
|
|
313
|
+
role: 'user',
|
|
314
|
+
content:
|
|
315
|
+
'Optimize this HoloScript for ' +
|
|
316
|
+
target +
|
|
317
|
+
'. Return only the optimized code:\n\n' +
|
|
318
|
+
holoScript,
|
|
319
|
+
},
|
|
320
|
+
];
|
|
321
|
+
const response = await this.callAPI(messages);
|
|
322
|
+
return {
|
|
323
|
+
holoScript: this.extractCode(response),
|
|
324
|
+
improvements: ['Optimized for ' + target],
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async fixHoloScript(holoScript: string, errors: string[]): Promise<FixResult> {
|
|
329
|
+
const messages: Array<{ role: 'user' | 'assistant'; content: string }> = [
|
|
330
|
+
{
|
|
331
|
+
role: 'user',
|
|
332
|
+
content:
|
|
333
|
+
'Fix these errors in the HoloScript:\nErrors: ' +
|
|
334
|
+
errors.join(', ') +
|
|
335
|
+
'\n\nCode:\n' +
|
|
336
|
+
holoScript,
|
|
337
|
+
},
|
|
338
|
+
];
|
|
339
|
+
const response = await this.callAPI(messages);
|
|
340
|
+
return {
|
|
341
|
+
holoScript: this.extractCode(response),
|
|
342
|
+
fixes: errors.map((e) => ({ line: 0, issue: e, fix: 'auto-fixed' })),
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async chat(
|
|
347
|
+
message: string,
|
|
348
|
+
holoScript?: string,
|
|
349
|
+
history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
350
|
+
): Promise<string> {
|
|
351
|
+
const messages: Array<{ role: 'user' | 'assistant'; content: string }> = history
|
|
352
|
+
? [...history]
|
|
353
|
+
: [];
|
|
354
|
+
|
|
355
|
+
if (holoScript) {
|
|
356
|
+
messages.push({
|
|
357
|
+
role: 'user',
|
|
358
|
+
content: 'Context:\n' + holoScript + '\n\nQuestion: ' + message,
|
|
359
|
+
});
|
|
360
|
+
} else {
|
|
361
|
+
messages.push({ role: 'user', content: message });
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return this.callAPI(messages);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
private extractCode(response: string): string {
|
|
368
|
+
const match = response.match(/```(?:holoscript|holo)?\n([\s\S]*?)```/);
|
|
369
|
+
return match ? match[1].trim() : response.trim();
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
private async callAPI(
|
|
373
|
+
messages: Array<{ role: 'user' | 'assistant'; content: string }>,
|
|
374
|
+
_options?: GenerateOptions
|
|
375
|
+
): Promise<string> {
|
|
376
|
+
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
|
377
|
+
method: 'POST',
|
|
378
|
+
headers: {
|
|
379
|
+
'Content-Type': 'application/json',
|
|
380
|
+
'x-api-key': this.config.apiKey,
|
|
381
|
+
'anthropic-version': '2023-06-01',
|
|
382
|
+
},
|
|
383
|
+
body: JSON.stringify({
|
|
384
|
+
model: this.model,
|
|
385
|
+
max_tokens: 4096,
|
|
386
|
+
system: HOLOSCRIPT_SYSTEM_PROMPT,
|
|
387
|
+
messages,
|
|
388
|
+
}),
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
if (response.status === 429) {
|
|
392
|
+
throw new Error('Anthropic rate limited (429) - please retry after backoff');
|
|
393
|
+
}
|
|
394
|
+
if (response.status === 401 || response.status === 403) {
|
|
395
|
+
throw new Error('Anthropic auth failed - check API key');
|
|
396
|
+
}
|
|
397
|
+
if (!response.ok) {
|
|
398
|
+
throw new Error('Anthropic API error: ' + response.statusText);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const data = await response.json();
|
|
402
|
+
return data.content[0].text;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
async getEmbeddings(text: string | string[]): Promise<number[][]> {
|
|
406
|
+
// Anthropic doesn't have native embeddings API yet, return mock for compatibility
|
|
407
|
+
const inputs = Array.isArray(text) ? text : [text];
|
|
408
|
+
return inputs.map((_) =>
|
|
409
|
+
Array(1024)
|
|
410
|
+
.fill(0.5)
|
|
411
|
+
.map(() => Math.random())
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// ============================================================================
|
|
417
|
+
// Ollama (Local) Adapter
|
|
418
|
+
// ============================================================================
|
|
419
|
+
|
|
420
|
+
export interface OllamaAdapterConfig {
|
|
421
|
+
baseUrl?: string;
|
|
422
|
+
model?: string;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export class OllamaAdapter implements AIAdapter {
|
|
426
|
+
readonly id = 'ollama';
|
|
427
|
+
readonly name = 'Ollama (Local)';
|
|
428
|
+
|
|
429
|
+
private baseUrl: string;
|
|
430
|
+
private model: string;
|
|
431
|
+
|
|
432
|
+
constructor(config: OllamaAdapterConfig = {}) {
|
|
433
|
+
this.baseUrl = config.baseUrl || 'http://localhost:11434';
|
|
434
|
+
this.model = config.model || 'brittney-qwen-v23:latest';
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async isReady(): Promise<boolean> {
|
|
438
|
+
try {
|
|
439
|
+
const response = await fetch(this.baseUrl + '/api/tags');
|
|
440
|
+
return response.ok;
|
|
441
|
+
} catch {
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
async generateHoloScript(prompt: string, _options?: GenerateOptions): Promise<GenerateResult> {
|
|
447
|
+
const response = await this.callAPI(
|
|
448
|
+
HOLOSCRIPT_SYSTEM_PROMPT,
|
|
449
|
+
'Create a HoloScript scene: ' + prompt
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
return {
|
|
453
|
+
holoScript: this.extractCode(response),
|
|
454
|
+
confidence: 0.75,
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
async explainHoloScript(holoScript: string): Promise<ExplainResult> {
|
|
459
|
+
const response = await this.callAPI(
|
|
460
|
+
'You are a HoloScript expert. Explain code clearly.',
|
|
461
|
+
'Explain this HoloScript:\n\n' + holoScript
|
|
462
|
+
);
|
|
463
|
+
return { explanation: response };
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
async optimizeHoloScript(
|
|
467
|
+
holoScript: string,
|
|
468
|
+
target: 'mobile' | 'desktop' | 'vr' | 'ar'
|
|
469
|
+
): Promise<OptimizeResult> {
|
|
470
|
+
const response = await this.callAPI(
|
|
471
|
+
'You are a HoloScript optimizer. Optimize for ' + target + '.',
|
|
472
|
+
holoScript
|
|
473
|
+
);
|
|
474
|
+
return {
|
|
475
|
+
holoScript: this.extractCode(response),
|
|
476
|
+
improvements: ['Optimized for ' + target],
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
async fixHoloScript(holoScript: string, errors: string[]): Promise<FixResult> {
|
|
481
|
+
const response = await this.callAPI(
|
|
482
|
+
'You are a HoloScript debugger. Fix errors and return corrected code.',
|
|
483
|
+
'Errors: ' + errors.join(', ') + '\n\nCode:\n' + holoScript
|
|
484
|
+
);
|
|
485
|
+
return {
|
|
486
|
+
holoScript: this.extractCode(response),
|
|
487
|
+
fixes: errors.map((e) => ({ line: 0, issue: e, fix: 'auto-fixed' })),
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
async chat(
|
|
492
|
+
message: string,
|
|
493
|
+
holoScript?: string,
|
|
494
|
+
history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
495
|
+
): Promise<string> {
|
|
496
|
+
// Ollama doesn't support multi-turn natively, but log history for context
|
|
497
|
+
if (history && history.length > 0) {
|
|
498
|
+
const contextMsg = history.map((h) => h.role + ': ' + h.content.slice(0, 100)).join('\n');
|
|
499
|
+
const fullMessage = holoScript
|
|
500
|
+
? 'History:\n' + contextMsg + '\n\nContext:\n' + holoScript + '\n\nQuestion: ' + message
|
|
501
|
+
: 'History:\n' + contextMsg + '\n\nQuestion: ' + message;
|
|
502
|
+
return this.callAPI(HOLOSCRIPT_SYSTEM_PROMPT, fullMessage);
|
|
503
|
+
}
|
|
504
|
+
const fullMessage = holoScript
|
|
505
|
+
? 'Context:\n' + holoScript + '\n\nQuestion: ' + message
|
|
506
|
+
: message;
|
|
507
|
+
return this.callAPI(HOLOSCRIPT_SYSTEM_PROMPT, fullMessage);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
private async callAPIWithErrorHandling(apiPath: string, body: RequestInit): Promise<Response> {
|
|
511
|
+
const response = await fetch(this.baseUrl + apiPath, body);
|
|
512
|
+
|
|
513
|
+
if (response.status === 429) {
|
|
514
|
+
throw new Error('Ollama rate limited (429) - model may be busy');
|
|
515
|
+
}
|
|
516
|
+
if (response.status === 503) {
|
|
517
|
+
throw new Error('Ollama service unavailable - ensure service is running');
|
|
518
|
+
}
|
|
519
|
+
if (!response.ok) {
|
|
520
|
+
throw new Error('Ollama API error: ' + response.statusText);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
return response;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
private extractCode(response: string): string {
|
|
527
|
+
const match = response.match(/```(?:holoscript|holo)?\n([\s\S]*?)```/);
|
|
528
|
+
return match ? match[1].trim() : response.trim();
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
private async callAPI(system: string, prompt: string): Promise<string> {
|
|
532
|
+
const response = await this.callAPIWithErrorHandling('/api/generate', {
|
|
533
|
+
method: 'POST',
|
|
534
|
+
headers: { 'Content-Type': 'application/json' },
|
|
535
|
+
body: JSON.stringify({
|
|
536
|
+
model: this.model,
|
|
537
|
+
system,
|
|
538
|
+
prompt,
|
|
539
|
+
stream: false,
|
|
540
|
+
}),
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
const data = await response.json();
|
|
544
|
+
return data.response;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
async getEmbeddings(text: string | string[]): Promise<number[][]> {
|
|
548
|
+
const inputs = Array.isArray(text) ? text : [text];
|
|
549
|
+
const results: number[][] = [];
|
|
550
|
+
|
|
551
|
+
for (const input of inputs) {
|
|
552
|
+
const response = await fetch(this.baseUrl + '/api/embeddings', {
|
|
553
|
+
method: 'POST',
|
|
554
|
+
headers: { 'Content-Type': 'application/json' },
|
|
555
|
+
body: JSON.stringify({
|
|
556
|
+
model: this.model,
|
|
557
|
+
prompt: input,
|
|
558
|
+
}),
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
if (!response.ok) {
|
|
562
|
+
throw new Error('Ollama Embeddings API error: ' + response.statusText);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
const data = await response.json();
|
|
566
|
+
results.push(data.embedding);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
return results;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// ============================================================================
|
|
574
|
+
// LM Studio Adapter (OpenAI-compatible local)
|
|
575
|
+
// ============================================================================
|
|
576
|
+
|
|
577
|
+
export interface LMStudioAdapterConfig {
|
|
578
|
+
baseUrl?: string;
|
|
579
|
+
model?: string;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* LM Studio adapter - uses OpenAI-compatible API running locally
|
|
584
|
+
*/
|
|
585
|
+
export class LMStudioAdapter implements AIAdapter {
|
|
586
|
+
readonly id = 'lmstudio';
|
|
587
|
+
readonly name = 'LM Studio (Local)';
|
|
588
|
+
|
|
589
|
+
private openaiAdapter: OpenAIAdapter;
|
|
590
|
+
|
|
591
|
+
constructor(config: LMStudioAdapterConfig = {}) {
|
|
592
|
+
this.openaiAdapter = new OpenAIAdapter({
|
|
593
|
+
apiKey: 'lm-studio', // LM Studio doesn't require an API key
|
|
594
|
+
baseUrl: config.baseUrl || 'http://localhost:1234/v1',
|
|
595
|
+
model: config.model || 'local-model',
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
isReady(): boolean {
|
|
600
|
+
return true; // Assume ready, will fail gracefully if not running
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
generateHoloScript(prompt: string, options?: GenerateOptions): Promise<GenerateResult> {
|
|
604
|
+
return this.openaiAdapter.generateHoloScript(prompt, options);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
explainHoloScript(holoScript: string): Promise<ExplainResult> {
|
|
608
|
+
return this.openaiAdapter.explainHoloScript(holoScript);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
optimizeHoloScript(
|
|
612
|
+
holoScript: string,
|
|
613
|
+
target: 'mobile' | 'desktop' | 'vr' | 'ar'
|
|
614
|
+
): Promise<OptimizeResult> {
|
|
615
|
+
return this.openaiAdapter.optimizeHoloScript(holoScript, target);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
fixHoloScript(holoScript: string, errors: string[]): Promise<FixResult> {
|
|
619
|
+
return this.openaiAdapter.fixHoloScript(holoScript, errors);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
chat(
|
|
623
|
+
message: string,
|
|
624
|
+
holoScript?: string,
|
|
625
|
+
history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
626
|
+
): Promise<string> {
|
|
627
|
+
return this.openaiAdapter.chat(message, holoScript, history);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// ============================================================================
|
|
632
|
+
// Factory Functions
|
|
633
|
+
// ============================================================================
|
|
634
|
+
|
|
635
|
+
import { registerAIAdapter } from './AIAdapter';
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* Create and register an OpenAI adapter
|
|
639
|
+
*/
|
|
640
|
+
export function useOpenAI(config: OpenAIAdapterConfig): OpenAIAdapter {
|
|
641
|
+
const adapter = new OpenAIAdapter(config);
|
|
642
|
+
registerAIAdapter(adapter, true);
|
|
643
|
+
return adapter;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Create and register an Anthropic adapter
|
|
648
|
+
*/
|
|
649
|
+
export function useAnthropic(config: AnthropicAdapterConfig): AnthropicAdapter {
|
|
650
|
+
const adapter = new AnthropicAdapter(config);
|
|
651
|
+
registerAIAdapter(adapter, true);
|
|
652
|
+
return adapter;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Create and register an Ollama adapter (local)
|
|
657
|
+
*/
|
|
658
|
+
export function useOllama(config: OllamaAdapterConfig = {}): OllamaAdapter {
|
|
659
|
+
const adapter = new OllamaAdapter(config);
|
|
660
|
+
registerAIAdapter(adapter, true);
|
|
661
|
+
return adapter;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Create and register an LM Studio adapter (local)
|
|
666
|
+
*/
|
|
667
|
+
export function useLMStudio(config: LMStudioAdapterConfig = {}): LMStudioAdapter {
|
|
668
|
+
const adapter = new LMStudioAdapter(config);
|
|
669
|
+
registerAIAdapter(adapter, true);
|
|
670
|
+
return adapter;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// ============================================================================
|
|
674
|
+
// Google Gemini Adapter
|
|
675
|
+
// ============================================================================
|
|
676
|
+
|
|
677
|
+
export interface GeminiAdapterConfig {
|
|
678
|
+
apiKey: string;
|
|
679
|
+
model?: string;
|
|
680
|
+
/** Embedding model (default: text-embedding-004) */
|
|
681
|
+
embeddingModel?: string;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
export class GeminiAdapter implements AIAdapter {
|
|
685
|
+
readonly id = 'gemini';
|
|
686
|
+
readonly name = 'Google Gemini';
|
|
687
|
+
|
|
688
|
+
private config: GeminiAdapterConfig;
|
|
689
|
+
private model: string;
|
|
690
|
+
private embeddingModel: string;
|
|
691
|
+
|
|
692
|
+
constructor(config: GeminiAdapterConfig) {
|
|
693
|
+
this.config = config;
|
|
694
|
+
this.model = config.model || 'gemini-2.0-flash';
|
|
695
|
+
this.embeddingModel = config.embeddingModel || 'text-embedding-004';
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
isReady(): boolean {
|
|
699
|
+
return !!this.config.apiKey;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
async generateHoloScript(prompt: string, options?: GenerateOptions): Promise<GenerateResult> {
|
|
703
|
+
const response = await this.callAPI('Create a HoloScript scene: ' + prompt, options);
|
|
704
|
+
|
|
705
|
+
return {
|
|
706
|
+
holoScript: this.extractCode(response),
|
|
707
|
+
confidence: 0.85,
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
async explainHoloScript(holoScript: string): Promise<ExplainResult> {
|
|
712
|
+
const response = await this.callAPI('Explain this HoloScript code clearly:\n\n' + holoScript);
|
|
713
|
+
return { explanation: response };
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
async optimizeHoloScript(
|
|
717
|
+
holoScript: string,
|
|
718
|
+
target: 'mobile' | 'desktop' | 'vr' | 'ar'
|
|
719
|
+
): Promise<OptimizeResult> {
|
|
720
|
+
const response = await this.callAPI(
|
|
721
|
+
'Optimize this HoloScript for ' +
|
|
722
|
+
target +
|
|
723
|
+
'. Return only the optimized code:\n\n' +
|
|
724
|
+
holoScript
|
|
725
|
+
);
|
|
726
|
+
return {
|
|
727
|
+
holoScript: this.extractCode(response),
|
|
728
|
+
improvements: ['Optimized for ' + target],
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
async fixHoloScript(holoScript: string, errors: string[]): Promise<FixResult> {
|
|
733
|
+
const response = await this.callAPI(
|
|
734
|
+
'Fix these errors in the HoloScript:\nErrors: ' +
|
|
735
|
+
errors.join(', ') +
|
|
736
|
+
'\n\nCode:\n' +
|
|
737
|
+
holoScript
|
|
738
|
+
);
|
|
739
|
+
return {
|
|
740
|
+
holoScript: this.extractCode(response),
|
|
741
|
+
fixes: errors.map((e) => ({ line: 0, issue: e, fix: 'auto-fixed' })),
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
async chat(
|
|
746
|
+
message: string,
|
|
747
|
+
holoScript?: string,
|
|
748
|
+
history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
749
|
+
): Promise<string> {
|
|
750
|
+
const fullMessage = holoScript
|
|
751
|
+
? 'Context:\n' + holoScript + '\n\nQuestion: ' + message
|
|
752
|
+
: message;
|
|
753
|
+
return this.callAPI(fullMessage, undefined, history);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
async getEmbeddings(text: string | string[]): Promise<number[][]> {
|
|
757
|
+
const inputs = Array.isArray(text) ? text : [text];
|
|
758
|
+
const results: number[][] = [];
|
|
759
|
+
|
|
760
|
+
for (const input of inputs) {
|
|
761
|
+
const response = await fetch(
|
|
762
|
+
`https://generativelanguage.googleapis.com/v1beta/models/${this.embeddingModel}:embedContent?key=${this.config.apiKey}`,
|
|
763
|
+
{
|
|
764
|
+
method: 'POST',
|
|
765
|
+
headers: { 'Content-Type': 'application/json' },
|
|
766
|
+
body: JSON.stringify({
|
|
767
|
+
model: `models/${this.embeddingModel}`,
|
|
768
|
+
content: { parts: [{ text: input }] },
|
|
769
|
+
}),
|
|
770
|
+
}
|
|
771
|
+
);
|
|
772
|
+
|
|
773
|
+
if (!response.ok) {
|
|
774
|
+
const errorData = await response.json().catch(() => ({}));
|
|
775
|
+
const errorMsg = (errorData as APIErrorResponse)?.error?.message || response.statusText;
|
|
776
|
+
throw new Error('Gemini Embeddings API error: ' + errorMsg);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
const data = await response.json();
|
|
780
|
+
results.push(data.embedding.values);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
return results;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
private extractCode(response: string): string {
|
|
787
|
+
const match = response.match(/```(?:holoscript|holo)?\n([\s\S]*?)```/);
|
|
788
|
+
return match ? match[1].trim() : response.trim();
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
private async callAPI(
|
|
792
|
+
message: string,
|
|
793
|
+
_options?: GenerateOptions,
|
|
794
|
+
history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
795
|
+
): Promise<string> {
|
|
796
|
+
// Build contents array with optional history
|
|
797
|
+
const contents: Array<{ role: string; parts: Array<{ text: string }> }> = [];
|
|
798
|
+
|
|
799
|
+
if (history && history.length > 0) {
|
|
800
|
+
for (const msg of history) {
|
|
801
|
+
contents.push({
|
|
802
|
+
role: msg.role === 'assistant' ? 'model' : 'user',
|
|
803
|
+
parts: [{ text: msg.content }],
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// Add system prompt + current message
|
|
809
|
+
contents.push({
|
|
810
|
+
role: 'user',
|
|
811
|
+
parts: [{ text: HOLOSCRIPT_SYSTEM_PROMPT }, { text: message }],
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
const response = await fetch(
|
|
815
|
+
`https://generativelanguage.googleapis.com/v1beta/models/${this.model}:generateContent?key=${this.config.apiKey}`,
|
|
816
|
+
{
|
|
817
|
+
method: 'POST',
|
|
818
|
+
headers: { 'Content-Type': 'application/json' },
|
|
819
|
+
body: JSON.stringify({
|
|
820
|
+
contents,
|
|
821
|
+
generationConfig: {
|
|
822
|
+
temperature: 0.7,
|
|
823
|
+
maxOutputTokens: 4096,
|
|
824
|
+
},
|
|
825
|
+
}),
|
|
826
|
+
}
|
|
827
|
+
);
|
|
828
|
+
|
|
829
|
+
if (!response.ok) {
|
|
830
|
+
const errorData = await response.json().catch(() => ({}));
|
|
831
|
+
const errorMsg = (errorData as APIErrorResponse)?.error?.message || response.statusText;
|
|
832
|
+
const status = response.status;
|
|
833
|
+
|
|
834
|
+
if (status === 429) {
|
|
835
|
+
throw new Error('Gemini API rate limited. Please retry after a short delay.');
|
|
836
|
+
}
|
|
837
|
+
if (status === 403) {
|
|
838
|
+
throw new Error('Gemini API key invalid or quota exceeded: ' + errorMsg);
|
|
839
|
+
}
|
|
840
|
+
throw new Error('Gemini API error (' + status + '): ' + errorMsg);
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
const data = await response.json();
|
|
844
|
+
|
|
845
|
+
if (!data.candidates || data.candidates.length === 0) {
|
|
846
|
+
const blockReason = data.promptFeedback?.blockReason;
|
|
847
|
+
if (blockReason) {
|
|
848
|
+
throw new Error('Gemini request blocked: ' + blockReason);
|
|
849
|
+
}
|
|
850
|
+
throw new Error('Gemini returned no candidates');
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
return data.candidates[0].content.parts[0].text;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
// ============================================================================
|
|
858
|
+
// XAI (Grok) Adapter
|
|
859
|
+
// ============================================================================
|
|
860
|
+
|
|
861
|
+
export interface XAIAdapterConfig {
|
|
862
|
+
apiKey: string;
|
|
863
|
+
model?: string;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
export class XAIAdapter implements AIAdapter {
|
|
867
|
+
readonly id = 'xai';
|
|
868
|
+
readonly name = 'xAI Grok';
|
|
869
|
+
|
|
870
|
+
private config: XAIAdapterConfig;
|
|
871
|
+
private model: string;
|
|
872
|
+
|
|
873
|
+
constructor(config: XAIAdapterConfig) {
|
|
874
|
+
this.config = config;
|
|
875
|
+
this.model = config.model || 'grok-3';
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
isReady(): boolean {
|
|
879
|
+
return !!this.config.apiKey;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
async generateHoloScript(prompt: string, _options?: GenerateOptions): Promise<GenerateResult> {
|
|
883
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
884
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
885
|
+
{ role: 'user', content: 'Create a HoloScript scene: ' + prompt },
|
|
886
|
+
];
|
|
887
|
+
const response = await this.callAPI(messages);
|
|
888
|
+
|
|
889
|
+
return {
|
|
890
|
+
holoScript: this.extractCode(response),
|
|
891
|
+
confidence: 0.85,
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
async explainHoloScript(holoScript: string): Promise<ExplainResult> {
|
|
896
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
897
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
898
|
+
{ role: 'user', content: 'Explain this HoloScript code clearly:\n\n' + holoScript },
|
|
899
|
+
];
|
|
900
|
+
const response = await this.callAPI(messages);
|
|
901
|
+
return { explanation: response };
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
async optimizeHoloScript(
|
|
905
|
+
holoScript: string,
|
|
906
|
+
target: 'mobile' | 'desktop' | 'vr' | 'ar'
|
|
907
|
+
): Promise<OptimizeResult> {
|
|
908
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
909
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
910
|
+
{
|
|
911
|
+
role: 'user',
|
|
912
|
+
content:
|
|
913
|
+
'Optimize this HoloScript for ' +
|
|
914
|
+
target +
|
|
915
|
+
'. Return only the optimized code:\n\n' +
|
|
916
|
+
holoScript,
|
|
917
|
+
},
|
|
918
|
+
];
|
|
919
|
+
const response = await this.callAPI(messages);
|
|
920
|
+
return {
|
|
921
|
+
holoScript: this.extractCode(response),
|
|
922
|
+
improvements: ['Optimized for ' + target],
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
async fixHoloScript(holoScript: string, errors: string[]): Promise<FixResult> {
|
|
927
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
928
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
929
|
+
{
|
|
930
|
+
role: 'user',
|
|
931
|
+
content:
|
|
932
|
+
'Fix these errors in the HoloScript:\nErrors: ' +
|
|
933
|
+
errors.join(', ') +
|
|
934
|
+
'\n\nCode:\n' +
|
|
935
|
+
holoScript,
|
|
936
|
+
},
|
|
937
|
+
];
|
|
938
|
+
const response = await this.callAPI(messages);
|
|
939
|
+
return {
|
|
940
|
+
holoScript: this.extractCode(response),
|
|
941
|
+
fixes: errors.map((e) => ({ line: 0, issue: e, fix: 'auto-fixed' })),
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
async chat(
|
|
946
|
+
message: string,
|
|
947
|
+
holoScript?: string,
|
|
948
|
+
history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
949
|
+
): Promise<string> {
|
|
950
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
951
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
952
|
+
];
|
|
953
|
+
|
|
954
|
+
if (history) {
|
|
955
|
+
messages.push(...history);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
if (holoScript) {
|
|
959
|
+
messages.push({
|
|
960
|
+
role: 'user',
|
|
961
|
+
content: 'Context:\n' + holoScript + '\n\nQuestion: ' + message,
|
|
962
|
+
});
|
|
963
|
+
} else {
|
|
964
|
+
messages.push({ role: 'user', content: message });
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
return this.callAPI(messages);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
private extractCode(response: string): string {
|
|
971
|
+
const match = response.match(/```(?:holoscript|holo)?\n([\s\S]*?)```/);
|
|
972
|
+
return match ? match[1].trim() : response.trim();
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
private async callAPI(messages: Array<{ role: string; content: string }>): Promise<string> {
|
|
976
|
+
const response = await fetch('https://api.x.ai/v1/chat/completions', {
|
|
977
|
+
method: 'POST',
|
|
978
|
+
headers: {
|
|
979
|
+
'Content-Type': 'application/json',
|
|
980
|
+
Authorization: 'Bearer ' + this.config.apiKey,
|
|
981
|
+
},
|
|
982
|
+
body: JSON.stringify({
|
|
983
|
+
model: this.model,
|
|
984
|
+
messages,
|
|
985
|
+
temperature: 0.7,
|
|
986
|
+
}),
|
|
987
|
+
});
|
|
988
|
+
|
|
989
|
+
if (response.status === 429) {
|
|
990
|
+
throw new Error('xAI rate limited (429) - please retry after backoff');
|
|
991
|
+
}
|
|
992
|
+
if (response.status === 401 || response.status === 403) {
|
|
993
|
+
throw new Error('xAI auth failed - check API key');
|
|
994
|
+
}
|
|
995
|
+
if (!response.ok) {
|
|
996
|
+
throw new Error('xAI API error: ' + response.statusText);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
const data = await response.json();
|
|
1000
|
+
return data.choices[0].message.content;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
// ============================================================================
|
|
1005
|
+
// Together AI Adapter
|
|
1006
|
+
// ============================================================================
|
|
1007
|
+
|
|
1008
|
+
export interface TogetherAdapterConfig {
|
|
1009
|
+
apiKey: string;
|
|
1010
|
+
model?: string;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
export class TogetherAdapter implements AIAdapter {
|
|
1014
|
+
readonly id = 'together';
|
|
1015
|
+
readonly name = 'Together AI';
|
|
1016
|
+
|
|
1017
|
+
private config: TogetherAdapterConfig;
|
|
1018
|
+
private model: string;
|
|
1019
|
+
|
|
1020
|
+
constructor(config: TogetherAdapterConfig) {
|
|
1021
|
+
this.config = config;
|
|
1022
|
+
this.model = config.model || 'meta-llama/Llama-3.3-70B-Instruct-Turbo';
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
async getEmbeddings(text: string | string[]): Promise<number[][]> {
|
|
1026
|
+
const inputs = Array.isArray(text) ? text : [text];
|
|
1027
|
+
const results: number[][] = [];
|
|
1028
|
+
|
|
1029
|
+
for (const input of inputs) {
|
|
1030
|
+
const response = await fetch('https://api.together.xyz/v1/embeddings', {
|
|
1031
|
+
method: 'POST',
|
|
1032
|
+
headers: {
|
|
1033
|
+
'Content-Type': 'application/json',
|
|
1034
|
+
Authorization: 'Bearer ' + this.config.apiKey,
|
|
1035
|
+
},
|
|
1036
|
+
body: JSON.stringify({
|
|
1037
|
+
model: 'togethercomputer/m2-bert-80M-32k-retrieval',
|
|
1038
|
+
input,
|
|
1039
|
+
}),
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
if (!response.ok) {
|
|
1043
|
+
throw new Error('Together Embeddings API error: ' + response.statusText);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
const data = await response.json();
|
|
1047
|
+
results.push(data.data[0].embedding);
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
return results;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
isReady(): boolean {
|
|
1054
|
+
return !!this.config.apiKey;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
async generateHoloScript(prompt: string, _options?: GenerateOptions): Promise<GenerateResult> {
|
|
1058
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1059
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1060
|
+
{ role: 'user', content: 'Create a HoloScript scene: ' + prompt },
|
|
1061
|
+
];
|
|
1062
|
+
const response = await this.callAPI(messages);
|
|
1063
|
+
|
|
1064
|
+
return {
|
|
1065
|
+
holoScript: this.extractCode(response),
|
|
1066
|
+
confidence: 0.8,
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
async explainHoloScript(holoScript: string): Promise<ExplainResult> {
|
|
1071
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1072
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1073
|
+
{ role: 'user', content: 'Explain this HoloScript code clearly:\n\n' + holoScript },
|
|
1074
|
+
];
|
|
1075
|
+
const response = await this.callAPI(messages);
|
|
1076
|
+
return { explanation: response };
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
async optimizeHoloScript(
|
|
1080
|
+
holoScript: string,
|
|
1081
|
+
target: 'mobile' | 'desktop' | 'vr' | 'ar'
|
|
1082
|
+
): Promise<OptimizeResult> {
|
|
1083
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1084
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1085
|
+
{
|
|
1086
|
+
role: 'user',
|
|
1087
|
+
content:
|
|
1088
|
+
'Optimize this HoloScript for ' +
|
|
1089
|
+
target +
|
|
1090
|
+
'. Return only the optimized code:\n\n' +
|
|
1091
|
+
holoScript,
|
|
1092
|
+
},
|
|
1093
|
+
];
|
|
1094
|
+
const response = await this.callAPI(messages);
|
|
1095
|
+
return {
|
|
1096
|
+
holoScript: this.extractCode(response),
|
|
1097
|
+
improvements: ['Optimized for ' + target],
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
async fixHoloScript(holoScript: string, errors: string[]): Promise<FixResult> {
|
|
1102
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1103
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1104
|
+
{
|
|
1105
|
+
role: 'user',
|
|
1106
|
+
content:
|
|
1107
|
+
'Fix these errors in the HoloScript:\nErrors: ' +
|
|
1108
|
+
errors.join(', ') +
|
|
1109
|
+
'\n\nCode:\n' +
|
|
1110
|
+
holoScript,
|
|
1111
|
+
},
|
|
1112
|
+
];
|
|
1113
|
+
const response = await this.callAPI(messages);
|
|
1114
|
+
return {
|
|
1115
|
+
holoScript: this.extractCode(response),
|
|
1116
|
+
fixes: errors.map((e) => ({ line: 0, issue: e, fix: 'auto-fixed' })),
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
async chat(
|
|
1121
|
+
message: string,
|
|
1122
|
+
holoScript?: string,
|
|
1123
|
+
history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
1124
|
+
): Promise<string> {
|
|
1125
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1126
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1127
|
+
];
|
|
1128
|
+
|
|
1129
|
+
if (history) {
|
|
1130
|
+
messages.push(...history);
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
if (holoScript) {
|
|
1134
|
+
messages.push({
|
|
1135
|
+
role: 'user',
|
|
1136
|
+
content: 'Context:\n' + holoScript + '\n\nQuestion: ' + message,
|
|
1137
|
+
});
|
|
1138
|
+
} else {
|
|
1139
|
+
messages.push({ role: 'user', content: message });
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
return this.callAPI(messages);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
private extractCode(response: string): string {
|
|
1146
|
+
const match = response.match(/```(?:holoscript|holo)?\n([\s\S]*?)```/);
|
|
1147
|
+
return match ? match[1].trim() : response.trim();
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
private async callAPI(messages: Array<{ role: string; content: string }>): Promise<string> {
|
|
1151
|
+
const response = await fetch('https://api.together.xyz/v1/chat/completions', {
|
|
1152
|
+
method: 'POST',
|
|
1153
|
+
headers: {
|
|
1154
|
+
'Content-Type': 'application/json',
|
|
1155
|
+
Authorization: 'Bearer ' + this.config.apiKey,
|
|
1156
|
+
},
|
|
1157
|
+
body: JSON.stringify({
|
|
1158
|
+
model: this.model,
|
|
1159
|
+
messages,
|
|
1160
|
+
temperature: 0.7,
|
|
1161
|
+
max_tokens: 4096,
|
|
1162
|
+
}),
|
|
1163
|
+
});
|
|
1164
|
+
|
|
1165
|
+
if (response.status === 429) {
|
|
1166
|
+
throw new Error('Together AI rate limited (429) - please retry');
|
|
1167
|
+
}
|
|
1168
|
+
if (response.status === 401 || response.status === 403) {
|
|
1169
|
+
throw new Error('Together AI auth failed - check API key');
|
|
1170
|
+
}
|
|
1171
|
+
if (!response.ok) {
|
|
1172
|
+
throw new Error('Together AI API error: ' + response.statusText);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
const data = await response.json();
|
|
1176
|
+
return data.choices[0].message.content;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
// ============================================================================
|
|
1181
|
+
// Fireworks AI Adapter
|
|
1182
|
+
// ============================================================================
|
|
1183
|
+
|
|
1184
|
+
export interface FireworksAdapterConfig {
|
|
1185
|
+
apiKey: string;
|
|
1186
|
+
model?: string;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
export class FireworksAdapter implements AIAdapter {
|
|
1190
|
+
readonly id = 'fireworks';
|
|
1191
|
+
readonly name = 'Fireworks AI';
|
|
1192
|
+
|
|
1193
|
+
private config: FireworksAdapterConfig;
|
|
1194
|
+
private model: string;
|
|
1195
|
+
|
|
1196
|
+
constructor(config: FireworksAdapterConfig) {
|
|
1197
|
+
this.config = config;
|
|
1198
|
+
this.model = config.model || 'accounts/fireworks/models/llama-v3p1-70b-instruct';
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
isReady(): boolean {
|
|
1202
|
+
return !!this.config.apiKey;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
async generateHoloScript(prompt: string, _options?: GenerateOptions): Promise<GenerateResult> {
|
|
1206
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1207
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1208
|
+
{ role: 'user', content: 'Create a HoloScript scene: ' + prompt },
|
|
1209
|
+
];
|
|
1210
|
+
const response = await this.callAPI(messages);
|
|
1211
|
+
|
|
1212
|
+
return {
|
|
1213
|
+
holoScript: this.extractCode(response),
|
|
1214
|
+
confidence: 0.8,
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
async explainHoloScript(holoScript: string): Promise<ExplainResult> {
|
|
1219
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1220
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1221
|
+
{ role: 'user', content: 'Explain this HoloScript code clearly:\n\n' + holoScript },
|
|
1222
|
+
];
|
|
1223
|
+
const response = await this.callAPI(messages);
|
|
1224
|
+
return { explanation: response };
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
async optimizeHoloScript(
|
|
1228
|
+
holoScript: string,
|
|
1229
|
+
target: 'mobile' | 'desktop' | 'vr' | 'ar'
|
|
1230
|
+
): Promise<OptimizeResult> {
|
|
1231
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1232
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1233
|
+
{
|
|
1234
|
+
role: 'user',
|
|
1235
|
+
content:
|
|
1236
|
+
'Optimize this HoloScript for ' +
|
|
1237
|
+
target +
|
|
1238
|
+
'. Return only the optimized code:\n\n' +
|
|
1239
|
+
holoScript,
|
|
1240
|
+
},
|
|
1241
|
+
];
|
|
1242
|
+
const response = await this.callAPI(messages);
|
|
1243
|
+
return {
|
|
1244
|
+
holoScript: this.extractCode(response),
|
|
1245
|
+
improvements: ['Optimized for ' + target],
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
async fixHoloScript(holoScript: string, errors: string[]): Promise<FixResult> {
|
|
1250
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1251
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1252
|
+
{
|
|
1253
|
+
role: 'user',
|
|
1254
|
+
content:
|
|
1255
|
+
'Fix these errors in the HoloScript:\nErrors: ' +
|
|
1256
|
+
errors.join(', ') +
|
|
1257
|
+
'\n\nCode:\n' +
|
|
1258
|
+
holoScript,
|
|
1259
|
+
},
|
|
1260
|
+
];
|
|
1261
|
+
const response = await this.callAPI(messages);
|
|
1262
|
+
return {
|
|
1263
|
+
holoScript: this.extractCode(response),
|
|
1264
|
+
fixes: errors.map((e) => ({ line: 0, issue: e, fix: 'auto-fixed' })),
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
async chat(
|
|
1269
|
+
message: string,
|
|
1270
|
+
holoScript?: string,
|
|
1271
|
+
history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
1272
|
+
): Promise<string> {
|
|
1273
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1274
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1275
|
+
];
|
|
1276
|
+
|
|
1277
|
+
if (history) {
|
|
1278
|
+
messages.push(...history);
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
if (holoScript) {
|
|
1282
|
+
messages.push({
|
|
1283
|
+
role: 'user',
|
|
1284
|
+
content: 'Context:\n' + holoScript + '\n\nQuestion: ' + message,
|
|
1285
|
+
});
|
|
1286
|
+
} else {
|
|
1287
|
+
messages.push({ role: 'user', content: message });
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
return this.callAPI(messages);
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
private extractCode(response: string): string {
|
|
1294
|
+
const match = response.match(/```(?:holoscript|holo)?\n([\s\S]*?)```/);
|
|
1295
|
+
return match ? match[1].trim() : response.trim();
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
private async callAPI(messages: Array<{ role: string; content: string }>): Promise<string> {
|
|
1299
|
+
const response = await fetch('https://api.fireworks.ai/inference/v1/chat/completions', {
|
|
1300
|
+
method: 'POST',
|
|
1301
|
+
headers: {
|
|
1302
|
+
'Content-Type': 'application/json',
|
|
1303
|
+
Authorization: 'Bearer ' + this.config.apiKey,
|
|
1304
|
+
},
|
|
1305
|
+
body: JSON.stringify({
|
|
1306
|
+
model: this.model,
|
|
1307
|
+
messages,
|
|
1308
|
+
temperature: 0.7,
|
|
1309
|
+
max_tokens: 4096,
|
|
1310
|
+
}),
|
|
1311
|
+
});
|
|
1312
|
+
|
|
1313
|
+
if (response.status === 429) {
|
|
1314
|
+
throw new Error('Fireworks AI rate limited (429) - please retry');
|
|
1315
|
+
}
|
|
1316
|
+
if (response.status === 401 || response.status === 403) {
|
|
1317
|
+
throw new Error('Fireworks AI auth failed - check API key');
|
|
1318
|
+
}
|
|
1319
|
+
if (!response.ok) {
|
|
1320
|
+
throw new Error('Fireworks AI API error: ' + response.statusText);
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
const data = await response.json();
|
|
1324
|
+
return data.choices[0].message.content;
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
async getEmbeddings(text: string | string[]): Promise<number[][]> {
|
|
1328
|
+
const inputs = Array.isArray(text) ? text : [text];
|
|
1329
|
+
const results: number[][] = [];
|
|
1330
|
+
|
|
1331
|
+
for (const input of inputs) {
|
|
1332
|
+
const response = await fetch('https://api.fireworks.ai/inference/v1/embeddings', {
|
|
1333
|
+
method: 'POST',
|
|
1334
|
+
headers: {
|
|
1335
|
+
'Content-Type': 'application/json',
|
|
1336
|
+
Authorization: 'Bearer ' + this.config.apiKey,
|
|
1337
|
+
},
|
|
1338
|
+
body: JSON.stringify({
|
|
1339
|
+
model: 'nomic-ai/nomic-embed-text-v1',
|
|
1340
|
+
input,
|
|
1341
|
+
}),
|
|
1342
|
+
});
|
|
1343
|
+
|
|
1344
|
+
if (!response.ok) {
|
|
1345
|
+
throw new Error('Fireworks Embeddings API error: ' + response.statusText);
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
const data = await response.json();
|
|
1349
|
+
results.push(data.data[0].embedding);
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
return results;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
// ============================================================================
|
|
1357
|
+
// NVIDIA NIM Adapter
|
|
1358
|
+
// ============================================================================
|
|
1359
|
+
|
|
1360
|
+
export interface NVIDIAAdapterConfig {
|
|
1361
|
+
apiKey: string;
|
|
1362
|
+
model?: string;
|
|
1363
|
+
baseUrl?: string;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
export class NVIDIAAdapter implements AIAdapter {
|
|
1367
|
+
readonly id = 'nvidia';
|
|
1368
|
+
readonly name = 'NVIDIA NIM';
|
|
1369
|
+
|
|
1370
|
+
private config: NVIDIAAdapterConfig;
|
|
1371
|
+
private model: string;
|
|
1372
|
+
private baseUrl: string;
|
|
1373
|
+
|
|
1374
|
+
constructor(config: NVIDIAAdapterConfig) {
|
|
1375
|
+
this.config = config;
|
|
1376
|
+
this.model = config.model || 'meta/llama-3.1-70b-instruct';
|
|
1377
|
+
this.baseUrl = config.baseUrl || 'https://integrate.api.nvidia.com/v1';
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
isReady(): boolean {
|
|
1381
|
+
return !!this.config.apiKey;
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
async generateHoloScript(prompt: string, _options?: GenerateOptions): Promise<GenerateResult> {
|
|
1385
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1386
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1387
|
+
{ role: 'user', content: 'Create a HoloScript scene: ' + prompt },
|
|
1388
|
+
];
|
|
1389
|
+
const response = await this.callAPI(messages);
|
|
1390
|
+
|
|
1391
|
+
return {
|
|
1392
|
+
holoScript: this.extractCode(response),
|
|
1393
|
+
confidence: 0.85,
|
|
1394
|
+
};
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
async explainHoloScript(holoScript: string): Promise<ExplainResult> {
|
|
1398
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1399
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1400
|
+
{ role: 'user', content: 'Explain this HoloScript code clearly:\n\n' + holoScript },
|
|
1401
|
+
];
|
|
1402
|
+
const response = await this.callAPI(messages);
|
|
1403
|
+
return { explanation: response };
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
async optimizeHoloScript(
|
|
1407
|
+
holoScript: string,
|
|
1408
|
+
target: 'mobile' | 'desktop' | 'vr' | 'ar'
|
|
1409
|
+
): Promise<OptimizeResult> {
|
|
1410
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1411
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1412
|
+
{
|
|
1413
|
+
role: 'user',
|
|
1414
|
+
content:
|
|
1415
|
+
'Optimize this HoloScript for ' +
|
|
1416
|
+
target +
|
|
1417
|
+
'. Return only the optimized code:\n\n' +
|
|
1418
|
+
holoScript,
|
|
1419
|
+
},
|
|
1420
|
+
];
|
|
1421
|
+
const response = await this.callAPI(messages);
|
|
1422
|
+
return {
|
|
1423
|
+
holoScript: this.extractCode(response),
|
|
1424
|
+
improvements: ['Optimized for ' + target],
|
|
1425
|
+
};
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
async fixHoloScript(holoScript: string, errors: string[]): Promise<FixResult> {
|
|
1429
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1430
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1431
|
+
{
|
|
1432
|
+
role: 'user',
|
|
1433
|
+
content:
|
|
1434
|
+
'Fix these errors in the HoloScript:\nErrors: ' +
|
|
1435
|
+
errors.join(', ') +
|
|
1436
|
+
'\n\nCode:\n' +
|
|
1437
|
+
holoScript,
|
|
1438
|
+
},
|
|
1439
|
+
];
|
|
1440
|
+
const response = await this.callAPI(messages);
|
|
1441
|
+
return {
|
|
1442
|
+
holoScript: this.extractCode(response),
|
|
1443
|
+
fixes: errors.map((e) => ({ line: 0, issue: e, fix: 'auto-fixed' })),
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
async chat(
|
|
1448
|
+
message: string,
|
|
1449
|
+
holoScript?: string,
|
|
1450
|
+
history?: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
1451
|
+
): Promise<string> {
|
|
1452
|
+
const messages: Array<{ role: string; content: string }> = [
|
|
1453
|
+
{ role: 'system', content: HOLOSCRIPT_SYSTEM_PROMPT },
|
|
1454
|
+
];
|
|
1455
|
+
|
|
1456
|
+
if (history) {
|
|
1457
|
+
messages.push(...history);
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
if (holoScript) {
|
|
1461
|
+
messages.push({
|
|
1462
|
+
role: 'user',
|
|
1463
|
+
content: 'Context:\n' + holoScript + '\n\nQuestion: ' + message,
|
|
1464
|
+
});
|
|
1465
|
+
} else {
|
|
1466
|
+
messages.push({ role: 'user', content: message });
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
return this.callAPI(messages);
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
private extractCode(response: string): string {
|
|
1473
|
+
const match = response.match(/```(?:holoscript|holo)?\n([\s\S]*?)```/);
|
|
1474
|
+
return match ? match[1].trim() : response.trim();
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
private async callAPI(messages: Array<{ role: string; content: string }>): Promise<string> {
|
|
1478
|
+
const response = await fetch(this.baseUrl + '/chat/completions', {
|
|
1479
|
+
method: 'POST',
|
|
1480
|
+
headers: {
|
|
1481
|
+
'Content-Type': 'application/json',
|
|
1482
|
+
Authorization: 'Bearer ' + this.config.apiKey,
|
|
1483
|
+
},
|
|
1484
|
+
body: JSON.stringify({
|
|
1485
|
+
model: this.model,
|
|
1486
|
+
messages,
|
|
1487
|
+
temperature: 0.7,
|
|
1488
|
+
max_tokens: 4096,
|
|
1489
|
+
}),
|
|
1490
|
+
});
|
|
1491
|
+
|
|
1492
|
+
if (response.status === 429) {
|
|
1493
|
+
throw new Error('NVIDIA NIM rate limited (429) - please retry');
|
|
1494
|
+
}
|
|
1495
|
+
if (response.status === 401 || response.status === 403) {
|
|
1496
|
+
throw new Error('NVIDIA NIM auth failed - check API key');
|
|
1497
|
+
}
|
|
1498
|
+
if (!response.ok) {
|
|
1499
|
+
throw new Error('NVIDIA NIM API error: ' + response.statusText);
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
const data = await response.json();
|
|
1503
|
+
return data.choices[0].message.content;
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
async getEmbeddings(text: string | string[]): Promise<number[][]> {
|
|
1507
|
+
const inputs = Array.isArray(text) ? text : [text];
|
|
1508
|
+
const results: number[][] = [];
|
|
1509
|
+
|
|
1510
|
+
for (const input of inputs) {
|
|
1511
|
+
const response = await fetch(this.baseUrl + '/embeddings', {
|
|
1512
|
+
method: 'POST',
|
|
1513
|
+
headers: {
|
|
1514
|
+
'Content-Type': 'application/json',
|
|
1515
|
+
Authorization: 'Bearer ' + this.config.apiKey,
|
|
1516
|
+
},
|
|
1517
|
+
body: JSON.stringify({
|
|
1518
|
+
model: 'nvidia/nvembed-v1',
|
|
1519
|
+
input,
|
|
1520
|
+
}),
|
|
1521
|
+
});
|
|
1522
|
+
|
|
1523
|
+
if (!response.ok) {
|
|
1524
|
+
throw new Error('NVIDIA Embeddings API error: ' + response.statusText);
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
const data = await response.json();
|
|
1528
|
+
results.push(data.data[0].embedding);
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
return results;
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
// ============================================================================
|
|
1536
|
+
// Additional Factory Functions
|
|
1537
|
+
// ============================================================================
|
|
1538
|
+
|
|
1539
|
+
/**
|
|
1540
|
+
* Create and register a Gemini adapter
|
|
1541
|
+
*/
|
|
1542
|
+
export function useGemini(config: GeminiAdapterConfig): GeminiAdapter {
|
|
1543
|
+
const adapter = new GeminiAdapter(config);
|
|
1544
|
+
registerAIAdapter(adapter, true);
|
|
1545
|
+
return adapter;
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
/**
|
|
1549
|
+
* Create and register an xAI (Grok) adapter
|
|
1550
|
+
*/
|
|
1551
|
+
export function useXAI(config: XAIAdapterConfig): XAIAdapter {
|
|
1552
|
+
const adapter = new XAIAdapter(config);
|
|
1553
|
+
registerAIAdapter(adapter, true);
|
|
1554
|
+
return adapter;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
/** Alias for useXAI */
|
|
1558
|
+
export const useGrok = useXAI;
|
|
1559
|
+
|
|
1560
|
+
/**
|
|
1561
|
+
* Create and register a Together AI adapter
|
|
1562
|
+
*/
|
|
1563
|
+
export function useTogether(config: TogetherAdapterConfig): TogetherAdapter {
|
|
1564
|
+
const adapter = new TogetherAdapter(config);
|
|
1565
|
+
registerAIAdapter(adapter, true);
|
|
1566
|
+
return adapter;
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
/**
|
|
1570
|
+
* Create and register a Fireworks AI adapter
|
|
1571
|
+
*/
|
|
1572
|
+
export function useFireworks(config: FireworksAdapterConfig): FireworksAdapter {
|
|
1573
|
+
const adapter = new FireworksAdapter(config);
|
|
1574
|
+
registerAIAdapter(adapter, true);
|
|
1575
|
+
return adapter;
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
/**
|
|
1579
|
+
* Create and register an NVIDIA NIM adapter
|
|
1580
|
+
*/
|
|
1581
|
+
export function useNVIDIA(config: NVIDIAAdapterConfig): NVIDIAAdapter {
|
|
1582
|
+
const adapter = new NVIDIAAdapter(config);
|
|
1583
|
+
registerAIAdapter(adapter, true);
|
|
1584
|
+
return adapter;
|
|
1585
|
+
}
|