@framers/agentos 0.1.119 → 0.1.121
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/README.md +21 -0
- package/dist/api/agency.d.ts.map +1 -1
- package/dist/api/agency.js +227 -84
- package/dist/api/agency.js.map +1 -1
- package/dist/api/analyzeVideo.d.ts +127 -0
- package/dist/api/analyzeVideo.d.ts.map +1 -0
- package/dist/api/analyzeVideo.js +136 -0
- package/dist/api/analyzeVideo.js.map +1 -0
- package/dist/api/detectScenes.d.ts +82 -0
- package/dist/api/detectScenes.d.ts.map +1 -0
- package/dist/api/detectScenes.js +67 -0
- package/dist/api/detectScenes.js.map +1 -0
- package/dist/api/generateImage.d.ts +7 -0
- package/dist/api/generateImage.d.ts.map +1 -1
- package/dist/api/generateImage.js +133 -9
- package/dist/api/generateImage.js.map +1 -1
- package/dist/api/generateMusic.d.ts +98 -0
- package/dist/api/generateMusic.d.ts.map +1 -0
- package/dist/api/generateMusic.js +319 -0
- package/dist/api/generateMusic.js.map +1 -0
- package/dist/api/generateSFX.d.ts +96 -0
- package/dist/api/generateSFX.d.ts.map +1 -0
- package/dist/api/generateSFX.js +317 -0
- package/dist/api/generateSFX.js.map +1 -0
- package/dist/api/generateVideo.d.ts +113 -0
- package/dist/api/generateVideo.d.ts.map +1 -0
- package/dist/api/generateVideo.js +342 -0
- package/dist/api/generateVideo.js.map +1 -0
- package/dist/api/model.d.ts.map +1 -1
- package/dist/api/model.js +8 -4
- package/dist/api/model.js.map +1 -1
- package/dist/api/performOCR.d.ts +169 -0
- package/dist/api/performOCR.d.ts.map +1 -0
- package/dist/api/performOCR.js +198 -0
- package/dist/api/performOCR.js.map +1 -0
- package/dist/api/provider-defaults.d.ts +7 -5
- package/dist/api/provider-defaults.d.ts.map +1 -1
- package/dist/api/provider-defaults.js +32 -10
- package/dist/api/provider-defaults.js.map +1 -1
- package/dist/api/strategies/debate.d.ts.map +1 -1
- package/dist/api/strategies/debate.js +1 -0
- package/dist/api/strategies/debate.js.map +1 -1
- package/dist/api/strategies/graph.d.ts.map +1 -1
- package/dist/api/strategies/graph.js +69 -13
- package/dist/api/strategies/graph.js.map +1 -1
- package/dist/api/strategies/hierarchical.d.ts.map +1 -1
- package/dist/api/strategies/hierarchical.js +1 -0
- package/dist/api/strategies/hierarchical.js.map +1 -1
- package/dist/api/strategies/parallel.d.ts.map +1 -1
- package/dist/api/strategies/parallel.js +1 -0
- package/dist/api/strategies/parallel.js.map +1 -1
- package/dist/api/strategies/review-loop.d.ts.map +1 -1
- package/dist/api/strategies/review-loop.js +1 -0
- package/dist/api/strategies/review-loop.js.map +1 -1
- package/dist/api/strategies/sequential.d.ts.map +1 -1
- package/dist/api/strategies/sequential.js +54 -48
- package/dist/api/strategies/sequential.js.map +1 -1
- package/dist/api/streamBuffer.d.ts +20 -0
- package/dist/api/streamBuffer.d.ts.map +1 -0
- package/dist/api/streamBuffer.js +81 -0
- package/dist/api/streamBuffer.js.map +1 -0
- package/dist/api/types.d.ts +145 -5
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/types.js.map +1 -1
- package/dist/channels/adapters/RedditChannelAdapter.js.map +1 -1
- package/dist/core/audio/AudioProcessor.d.ts.map +1 -1
- package/dist/core/audio/AudioProcessor.js +1 -0
- package/dist/core/audio/AudioProcessor.js.map +1 -1
- package/dist/core/audio/EnvironmentalCalibrator.d.ts.map +1 -1
- package/dist/core/audio/EnvironmentalCalibrator.js +1 -0
- package/dist/core/audio/EnvironmentalCalibrator.js.map +1 -1
- package/dist/core/audio/FallbackAudioProxy.d.ts +169 -0
- package/dist/core/audio/FallbackAudioProxy.d.ts.map +1 -0
- package/dist/core/audio/FallbackAudioProxy.js +236 -0
- package/dist/core/audio/FallbackAudioProxy.js.map +1 -0
- package/dist/core/audio/IAudioGenerator.d.ts +103 -0
- package/dist/core/audio/IAudioGenerator.d.ts.map +1 -0
- package/dist/core/audio/IAudioGenerator.js +24 -0
- package/dist/core/audio/IAudioGenerator.js.map +1 -0
- package/dist/core/audio/index.d.ts +54 -0
- package/dist/core/audio/index.d.ts.map +1 -1
- package/dist/core/audio/index.js +93 -0
- package/dist/core/audio/index.js.map +1 -1
- package/dist/core/audio/providers/AudioGenLocalProvider.d.ts +136 -0
- package/dist/core/audio/providers/AudioGenLocalProvider.d.ts.map +1 -0
- package/dist/core/audio/providers/AudioGenLocalProvider.js +235 -0
- package/dist/core/audio/providers/AudioGenLocalProvider.js.map +1 -0
- package/dist/core/audio/providers/ElevenLabsSFXProvider.d.ts +107 -0
- package/dist/core/audio/providers/ElevenLabsSFXProvider.d.ts.map +1 -0
- package/dist/core/audio/providers/ElevenLabsSFXProvider.js +154 -0
- package/dist/core/audio/providers/ElevenLabsSFXProvider.js.map +1 -0
- package/dist/core/audio/providers/FalAudioProvider.d.ts +207 -0
- package/dist/core/audio/providers/FalAudioProvider.d.ts.map +1 -0
- package/dist/core/audio/providers/FalAudioProvider.js +315 -0
- package/dist/core/audio/providers/FalAudioProvider.js.map +1 -0
- package/dist/core/audio/providers/MusicGenLocalProvider.d.ts +136 -0
- package/dist/core/audio/providers/MusicGenLocalProvider.d.ts.map +1 -0
- package/dist/core/audio/providers/MusicGenLocalProvider.js +235 -0
- package/dist/core/audio/providers/MusicGenLocalProvider.js.map +1 -0
- package/dist/core/audio/providers/ReplicateAudioProvider.d.ts +200 -0
- package/dist/core/audio/providers/ReplicateAudioProvider.d.ts.map +1 -0
- package/dist/core/audio/providers/ReplicateAudioProvider.js +346 -0
- package/dist/core/audio/providers/ReplicateAudioProvider.js.map +1 -0
- package/dist/core/audio/providers/StableAudioProvider.d.ts +138 -0
- package/dist/core/audio/providers/StableAudioProvider.d.ts.map +1 -0
- package/dist/core/audio/providers/StableAudioProvider.js +192 -0
- package/dist/core/audio/providers/StableAudioProvider.js.map +1 -0
- package/dist/core/audio/providers/SunoProvider.d.ts +182 -0
- package/dist/core/audio/providers/SunoProvider.d.ts.map +1 -0
- package/dist/core/audio/providers/SunoProvider.js +312 -0
- package/dist/core/audio/providers/SunoProvider.js.map +1 -0
- package/dist/core/audio/providers/UdioProvider.d.ts +177 -0
- package/dist/core/audio/providers/UdioProvider.d.ts.map +1 -0
- package/dist/core/audio/providers/UdioProvider.js +305 -0
- package/dist/core/audio/providers/UdioProvider.js.map +1 -0
- package/dist/core/audio/types.d.ts +257 -0
- package/dist/core/audio/types.d.ts.map +1 -0
- package/dist/core/audio/types.js +21 -0
- package/dist/core/audio/types.js.map +1 -0
- package/dist/core/images/FallbackImageProxy.d.ts +183 -0
- package/dist/core/images/FallbackImageProxy.d.ts.map +1 -0
- package/dist/core/images/FallbackImageProxy.js +283 -0
- package/dist/core/images/FallbackImageProxy.js.map +1 -0
- package/dist/core/images/IImageProvider.d.ts +1 -1
- package/dist/core/images/IImageProvider.d.ts.map +1 -1
- package/dist/core/images/index.d.ts +1 -0
- package/dist/core/images/index.d.ts.map +1 -1
- package/dist/core/images/index.js +1 -0
- package/dist/core/images/index.js.map +1 -1
- package/dist/core/llm/providers/AIModelProviderManager.d.ts +3 -1
- package/dist/core/llm/providers/AIModelProviderManager.d.ts.map +1 -1
- package/dist/core/llm/providers/AIModelProviderManager.js +8 -0
- package/dist/core/llm/providers/AIModelProviderManager.js.map +1 -1
- package/dist/core/llm/providers/errors/ClaudeCodeProviderError.d.ts +52 -0
- package/dist/core/llm/providers/errors/ClaudeCodeProviderError.d.ts.map +1 -0
- package/dist/core/llm/providers/errors/ClaudeCodeProviderError.js +36 -0
- package/dist/core/llm/providers/errors/ClaudeCodeProviderError.js.map +1 -0
- package/dist/core/llm/providers/errors/GeminiCLIProviderError.d.ts +32 -0
- package/dist/core/llm/providers/errors/GeminiCLIProviderError.d.ts.map +1 -0
- package/dist/core/llm/providers/errors/GeminiCLIProviderError.js +27 -0
- package/dist/core/llm/providers/errors/GeminiCLIProviderError.js.map +1 -0
- package/dist/core/llm/providers/implementations/ClaudeCodeCLIBridge.d.ts +38 -0
- package/dist/core/llm/providers/implementations/ClaudeCodeCLIBridge.d.ts.map +1 -0
- package/dist/core/llm/providers/implementations/ClaudeCodeCLIBridge.js +128 -0
- package/dist/core/llm/providers/implementations/ClaudeCodeCLIBridge.js.map +1 -0
- package/dist/core/llm/providers/implementations/ClaudeCodeProvider.d.ts +107 -0
- package/dist/core/llm/providers/implementations/ClaudeCodeProvider.d.ts.map +1 -0
- package/dist/core/llm/providers/implementations/ClaudeCodeProvider.js +504 -0
- package/dist/core/llm/providers/implementations/ClaudeCodeProvider.js.map +1 -0
- package/dist/core/llm/providers/implementations/GeminiCLIBridge.d.ts +60 -0
- package/dist/core/llm/providers/implementations/GeminiCLIBridge.d.ts.map +1 -0
- package/dist/core/llm/providers/implementations/GeminiCLIBridge.js +177 -0
- package/dist/core/llm/providers/implementations/GeminiCLIBridge.js.map +1 -0
- package/dist/core/llm/providers/implementations/GeminiCLIProvider.d.ts +55 -0
- package/dist/core/llm/providers/implementations/GeminiCLIProvider.d.ts.map +1 -0
- package/dist/core/llm/providers/implementations/GeminiCLIProvider.js +447 -0
- package/dist/core/llm/providers/implementations/GeminiCLIProvider.js.map +1 -0
- package/dist/core/media/ProviderPreferences.d.ts +158 -0
- package/dist/core/media/ProviderPreferences.d.ts.map +1 -0
- package/dist/core/media/ProviderPreferences.js +183 -0
- package/dist/core/media/ProviderPreferences.js.map +1 -0
- package/dist/core/subprocess/CLIRegistry.d.ts +71 -0
- package/dist/core/subprocess/CLIRegistry.d.ts.map +1 -0
- package/dist/core/subprocess/CLIRegistry.js +210 -0
- package/dist/core/subprocess/CLIRegistry.js.map +1 -0
- package/dist/core/subprocess/CLISubprocessBridge.d.ts +117 -0
- package/dist/core/subprocess/CLISubprocessBridge.d.ts.map +1 -0
- package/dist/core/subprocess/CLISubprocessBridge.js +199 -0
- package/dist/core/subprocess/CLISubprocessBridge.js.map +1 -0
- package/dist/core/subprocess/errors.d.ts +76 -0
- package/dist/core/subprocess/errors.d.ts.map +1 -0
- package/dist/core/subprocess/errors.js +75 -0
- package/dist/core/subprocess/errors.js.map +1 -0
- package/dist/core/subprocess/index.d.ts +11 -0
- package/dist/core/subprocess/index.d.ts.map +1 -0
- package/dist/core/subprocess/index.js +10 -0
- package/dist/core/subprocess/index.js.map +1 -0
- package/dist/core/subprocess/types.d.ts +100 -0
- package/dist/core/subprocess/types.d.ts.map +1 -0
- package/dist/core/subprocess/types.js +9 -0
- package/dist/core/subprocess/types.js.map +1 -0
- package/dist/core/video/FallbackVideoProxy.d.ts +166 -0
- package/dist/core/video/FallbackVideoProxy.d.ts.map +1 -0
- package/dist/core/video/FallbackVideoProxy.js +228 -0
- package/dist/core/video/FallbackVideoProxy.js.map +1 -0
- package/dist/core/video/IVideoAnalyzer.d.ts +29 -0
- package/dist/core/video/IVideoAnalyzer.d.ts.map +1 -0
- package/dist/core/video/IVideoAnalyzer.js +12 -0
- package/dist/core/video/IVideoAnalyzer.js.map +1 -0
- package/dist/core/video/IVideoGenerator.d.ts +76 -0
- package/dist/core/video/IVideoGenerator.d.ts.map +1 -0
- package/dist/core/video/IVideoGenerator.js +13 -0
- package/dist/core/video/IVideoGenerator.js.map +1 -0
- package/dist/core/video/VideoAnalyzer.d.ts +278 -0
- package/dist/core/video/VideoAnalyzer.d.ts.map +1 -0
- package/dist/core/video/VideoAnalyzer.js +648 -0
- package/dist/core/video/VideoAnalyzer.js.map +1 -0
- package/dist/core/video/index.d.ts +55 -0
- package/dist/core/video/index.d.ts.map +1 -0
- package/dist/core/video/index.js +78 -0
- package/dist/core/video/index.js.map +1 -0
- package/dist/core/video/providers/FalVideoProvider.d.ts +195 -0
- package/dist/core/video/providers/FalVideoProvider.d.ts.map +1 -0
- package/dist/core/video/providers/FalVideoProvider.js +322 -0
- package/dist/core/video/providers/FalVideoProvider.js.map +1 -0
- package/dist/core/video/providers/ReplicateVideoProvider.d.ts +194 -0
- package/dist/core/video/providers/ReplicateVideoProvider.d.ts.map +1 -0
- package/dist/core/video/providers/ReplicateVideoProvider.js +356 -0
- package/dist/core/video/providers/ReplicateVideoProvider.js.map +1 -0
- package/dist/core/video/providers/RunwayVideoProvider.d.ts +175 -0
- package/dist/core/video/providers/RunwayVideoProvider.d.ts.map +1 -0
- package/dist/core/video/providers/RunwayVideoProvider.js +293 -0
- package/dist/core/video/providers/RunwayVideoProvider.js.map +1 -0
- package/dist/core/video/types.d.ts +441 -0
- package/dist/core/video/types.d.ts.map +1 -0
- package/dist/core/video/types.js +10 -0
- package/dist/core/video/types.js.map +1 -0
- package/dist/core/vision/SceneDetector.d.ts +180 -0
- package/dist/core/vision/SceneDetector.d.ts.map +1 -0
- package/dist/core/vision/SceneDetector.js +366 -0
- package/dist/core/vision/SceneDetector.js.map +1 -0
- package/dist/core/vision/index.d.ts +2 -1
- package/dist/core/vision/index.d.ts.map +1 -1
- package/dist/core/vision/index.js +1 -0
- package/dist/core/vision/index.js.map +1 -1
- package/dist/core/vision/types.d.ts +125 -0
- package/dist/core/vision/types.d.ts.map +1 -1
- package/dist/discovery/CapabilityDiscoveryEngine.d.ts +32 -0
- package/dist/discovery/CapabilityDiscoveryEngine.d.ts.map +1 -1
- package/dist/discovery/CapabilityDiscoveryEngine.js +46 -0
- package/dist/discovery/CapabilityDiscoveryEngine.js.map +1 -1
- package/dist/extensions/MultiRegistryLoader.js.map +1 -1
- package/dist/index.d.ts +17 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/memory/CognitiveMemoryManager.d.ts +40 -0
- package/dist/memory/CognitiveMemoryManager.d.ts.map +1 -1
- package/dist/memory/CognitiveMemoryManager.js +54 -1
- package/dist/memory/CognitiveMemoryManager.js.map +1 -1
- package/dist/memory/facade/Memory.d.ts +4 -0
- package/dist/memory/facade/Memory.d.ts.map +1 -1
- package/dist/memory/facade/Memory.js +140 -4
- package/dist/memory/facade/Memory.js.map +1 -1
- package/dist/memory/facade/types.d.ts +30 -2
- package/dist/memory/facade/types.d.ts.map +1 -1
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +1 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/store/HnswSidecar.d.ts +115 -0
- package/dist/memory/store/HnswSidecar.d.ts.map +1 -0
- package/dist/memory/store/HnswSidecar.js +256 -0
- package/dist/memory/store/HnswSidecar.js.map +1 -0
- package/dist/memory/types.d.ts +15 -0
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/query-router/QueryClassifier.d.ts +192 -21
- package/dist/query-router/QueryClassifier.d.ts.map +1 -1
- package/dist/query-router/QueryClassifier.js +604 -23
- package/dist/query-router/QueryClassifier.js.map +1 -1
- package/dist/query-router/QueryDispatcher.d.ts +106 -8
- package/dist/query-router/QueryDispatcher.d.ts.map +1 -1
- package/dist/query-router/QueryDispatcher.js +387 -8
- package/dist/query-router/QueryDispatcher.js.map +1 -1
- package/dist/query-router/QueryRouter.d.ts +198 -14
- package/dist/query-router/QueryRouter.d.ts.map +1 -1
- package/dist/query-router/QueryRouter.js +738 -50
- package/dist/query-router/QueryRouter.js.map +1 -1
- package/dist/query-router/index.d.ts +1 -1
- package/dist/query-router/index.d.ts.map +1 -1
- package/dist/query-router/index.js +1 -1
- package/dist/query-router/index.js.map +1 -1
- package/dist/query-router/types.d.ts +396 -3
- package/dist/query-router/types.d.ts.map +1 -1
- package/dist/query-router/types.js +35 -0
- package/dist/query-router/types.js.map +1 -1
- package/dist/rag/HydeRetriever.d.ts +108 -0
- package/dist/rag/HydeRetriever.d.ts.map +1 -1
- package/dist/rag/HydeRetriever.js +184 -0
- package/dist/rag/HydeRetriever.js.map +1 -1
- package/dist/rag/IRetrievalAugmentor.d.ts +15 -0
- package/dist/rag/IRetrievalAugmentor.d.ts.map +1 -1
- package/dist/rag/RetrievalAugmentor.d.ts +58 -0
- package/dist/rag/RetrievalAugmentor.d.ts.map +1 -1
- package/dist/rag/RetrievalAugmentor.js +200 -32
- package/dist/rag/RetrievalAugmentor.js.map +1 -1
- package/dist/rag/VectorStoreManager.js +1 -1
- package/dist/rag/audit/RAGAuditCollector.d.ts +7 -0
- package/dist/rag/audit/RAGAuditCollector.d.ts.map +1 -1
- package/dist/rag/audit/RAGAuditCollector.js +10 -0
- package/dist/rag/audit/RAGAuditCollector.js.map +1 -1
- package/dist/rag/audit/RAGAuditTypes.d.ts +10 -1
- package/dist/rag/audit/RAGAuditTypes.d.ts.map +1 -1
- package/dist/rag/chunking/SemanticChunker.d.ts +210 -0
- package/dist/rag/chunking/SemanticChunker.d.ts.map +1 -0
- package/dist/rag/chunking/SemanticChunker.js +460 -0
- package/dist/rag/chunking/SemanticChunker.js.map +1 -0
- package/dist/rag/chunking/index.d.ts +10 -0
- package/dist/rag/chunking/index.d.ts.map +1 -0
- package/dist/rag/chunking/index.js +10 -0
- package/dist/rag/chunking/index.js.map +1 -0
- package/dist/rag/implementations/vector_stores/PineconeVectorStore.d.ts +103 -0
- package/dist/rag/implementations/vector_stores/PineconeVectorStore.d.ts.map +1 -0
- package/dist/rag/implementations/vector_stores/PineconeVectorStore.js +315 -0
- package/dist/rag/implementations/vector_stores/PineconeVectorStore.js.map +1 -0
- package/dist/rag/implementations/vector_stores/PostgresVectorStore.d.ts +107 -0
- package/dist/rag/implementations/vector_stores/PostgresVectorStore.d.ts.map +1 -0
- package/dist/rag/implementations/vector_stores/PostgresVectorStore.js +438 -0
- package/dist/rag/implementations/vector_stores/PostgresVectorStore.js.map +1 -0
- package/dist/rag/index.d.ts +15 -1
- package/dist/rag/index.d.ts.map +1 -1
- package/dist/rag/index.js +32 -0
- package/dist/rag/index.js.map +1 -1
- package/dist/rag/migration/MigrationEngine.d.ts +47 -0
- package/dist/rag/migration/MigrationEngine.d.ts.map +1 -0
- package/dist/rag/migration/MigrationEngine.js +168 -0
- package/dist/rag/migration/MigrationEngine.js.map +1 -0
- package/dist/rag/migration/adapters/PineconeSourceAdapter.d.ts +23 -0
- package/dist/rag/migration/adapters/PineconeSourceAdapter.d.ts.map +1 -0
- package/dist/rag/migration/adapters/PineconeSourceAdapter.js +63 -0
- package/dist/rag/migration/adapters/PineconeSourceAdapter.js.map +1 -0
- package/dist/rag/migration/adapters/PostgresSourceAdapter.d.ts +30 -0
- package/dist/rag/migration/adapters/PostgresSourceAdapter.d.ts.map +1 -0
- package/dist/rag/migration/adapters/PostgresSourceAdapter.js +71 -0
- package/dist/rag/migration/adapters/PostgresSourceAdapter.js.map +1 -0
- package/dist/rag/migration/adapters/PostgresTargetAdapter.d.ts +38 -0
- package/dist/rag/migration/adapters/PostgresTargetAdapter.d.ts.map +1 -0
- package/dist/rag/migration/adapters/PostgresTargetAdapter.js +114 -0
- package/dist/rag/migration/adapters/PostgresTargetAdapter.js.map +1 -0
- package/dist/rag/migration/adapters/QdrantSourceAdapter.d.ts +36 -0
- package/dist/rag/migration/adapters/QdrantSourceAdapter.d.ts.map +1 -0
- package/dist/rag/migration/adapters/QdrantSourceAdapter.js +109 -0
- package/dist/rag/migration/adapters/QdrantSourceAdapter.js.map +1 -0
- package/dist/rag/migration/adapters/QdrantTargetAdapter.d.ts +35 -0
- package/dist/rag/migration/adapters/QdrantTargetAdapter.d.ts.map +1 -0
- package/dist/rag/migration/adapters/QdrantTargetAdapter.js +110 -0
- package/dist/rag/migration/adapters/QdrantTargetAdapter.js.map +1 -0
- package/dist/rag/migration/adapters/SqliteSourceAdapter.d.ts +37 -0
- package/dist/rag/migration/adapters/SqliteSourceAdapter.d.ts.map +1 -0
- package/dist/rag/migration/adapters/SqliteSourceAdapter.js +72 -0
- package/dist/rag/migration/adapters/SqliteSourceAdapter.js.map +1 -0
- package/dist/rag/migration/adapters/SqliteTargetAdapter.d.ts +47 -0
- package/dist/rag/migration/adapters/SqliteTargetAdapter.d.ts.map +1 -0
- package/dist/rag/migration/adapters/SqliteTargetAdapter.js +93 -0
- package/dist/rag/migration/adapters/SqliteTargetAdapter.js.map +1 -0
- package/dist/rag/migration/types.d.ts +108 -0
- package/dist/rag/migration/types.d.ts.map +1 -0
- package/dist/rag/migration/types.js +11 -0
- package/dist/rag/migration/types.js.map +1 -0
- package/dist/rag/multimodal/MultimodalIndexer.d.ts +35 -0
- package/dist/rag/multimodal/MultimodalIndexer.d.ts.map +1 -1
- package/dist/rag/multimodal/MultimodalIndexer.js +66 -1
- package/dist/rag/multimodal/MultimodalIndexer.js.map +1 -1
- package/dist/rag/multimodal/types.d.ts +24 -0
- package/dist/rag/multimodal/types.d.ts.map +1 -1
- package/dist/rag/raptor/RaptorTree.d.ts +268 -0
- package/dist/rag/raptor/RaptorTree.d.ts.map +1 -0
- package/dist/rag/raptor/RaptorTree.js +443 -0
- package/dist/rag/raptor/RaptorTree.js.map +1 -0
- package/dist/rag/raptor/index.d.ts +11 -0
- package/dist/rag/raptor/index.d.ts.map +1 -0
- package/dist/rag/raptor/index.js +11 -0
- package/dist/rag/raptor/index.js.map +1 -0
- package/dist/rag/reranking/providers/CohereReranker.js.map +1 -1
- package/dist/rag/search/BM25Index.d.ts +282 -0
- package/dist/rag/search/BM25Index.d.ts.map +1 -0
- package/dist/rag/search/BM25Index.js +344 -0
- package/dist/rag/search/BM25Index.js.map +1 -0
- package/dist/rag/search/HybridSearcher.d.ts +198 -0
- package/dist/rag/search/HybridSearcher.d.ts.map +1 -0
- package/dist/rag/search/HybridSearcher.js +316 -0
- package/dist/rag/search/HybridSearcher.js.map +1 -0
- package/dist/rag/search/index.d.ts +12 -0
- package/dist/rag/search/index.d.ts.map +1 -0
- package/dist/rag/search/index.js +12 -0
- package/dist/rag/search/index.js.map +1 -0
- package/dist/rag/setup/DockerDetector.d.ts +67 -0
- package/dist/rag/setup/DockerDetector.d.ts.map +1 -0
- package/dist/rag/setup/DockerDetector.js +125 -0
- package/dist/rag/setup/DockerDetector.js.map +1 -0
- package/dist/rag/setup/PostgresSetup.d.ts +20 -0
- package/dist/rag/setup/PostgresSetup.d.ts.map +1 -0
- package/dist/rag/setup/PostgresSetup.js +133 -0
- package/dist/rag/setup/PostgresSetup.js.map +1 -0
- package/dist/rag/setup/QdrantSetup.d.ts +26 -0
- package/dist/rag/setup/QdrantSetup.d.ts.map +1 -0
- package/dist/rag/setup/QdrantSetup.js +96 -0
- package/dist/rag/setup/QdrantSetup.js.map +1 -0
- package/dist/rag/setup/types.d.ts +55 -0
- package/dist/rag/setup/types.d.ts.map +1 -0
- package/dist/rag/setup/types.js +6 -0
- package/dist/rag/setup/types.js.map +1 -0
- package/dist/rag/unified/UnifiedRetriever.d.ts +472 -0
- package/dist/rag/unified/UnifiedRetriever.d.ts.map +1 -0
- package/dist/rag/unified/UnifiedRetriever.js +887 -0
- package/dist/rag/unified/UnifiedRetriever.js.map +1 -0
- package/dist/rag/unified/index.d.ts +24 -0
- package/dist/rag/unified/index.d.ts.map +1 -0
- package/dist/rag/unified/index.js +23 -0
- package/dist/rag/unified/index.js.map +1 -0
- package/dist/rag/unified/types.d.ts +546 -0
- package/dist/rag/unified/types.d.ts.map +1 -0
- package/dist/rag/unified/types.js +177 -0
- package/dist/rag/unified/types.js.map +1 -0
- package/dist/speech/providers/AssemblyAISTTProvider.js.map +1 -1
- package/dist/speech/providers/AzureSpeechSTTProvider.js.map +1 -1
- package/dist/speech/providers/BuiltInAdaptiveVadProvider.d.ts +1 -1
- package/dist/speech/providers/DeepgramBatchSTTProvider.js.map +1 -1
- package/package.json +5 -1
|
@@ -1,38 +1,57 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview QueryClassifier — chain-of-thought LLM classifier that
|
|
3
|
-
* determines the retrieval depth tier (T0-T3)
|
|
3
|
+
* determines both the retrieval depth tier (T0-T3) and the retrieval
|
|
4
|
+
* strategy (`none` / `simple` / `moderate` / `complex`) for each query,
|
|
5
|
+
* along with capability recommendations (skills, tools, extensions).
|
|
4
6
|
*
|
|
5
7
|
* The classifier is the first stage of the QueryRouter pipeline. It examines
|
|
6
8
|
* the user's query (and optional conversation history) to decide how much
|
|
7
9
|
* retrieval effort is needed:
|
|
8
10
|
*
|
|
9
|
-
* - **T0 (Trivial)
|
|
10
|
-
* - **T1 (Simple
|
|
11
|
-
* - **T2 (Multi-source)
|
|
12
|
-
*
|
|
11
|
+
* - **T0 (Trivial)** / `none`: No retrieval — answer from internal knowledge.
|
|
12
|
+
* - **T1 (Simple)** / `simple`: Direct embedding search — fast, cheap.
|
|
13
|
+
* - **T2 (Multi-source)** / `moderate`: HyDE retrieval — hypothesis-based
|
|
14
|
+
* embedding bridges vocabulary mismatch between questions and docs.
|
|
15
|
+
* - **T3 (Research)** / `complex`: HyDE + deep research — decompose multi-part
|
|
16
|
+
* queries into sub-queries, HyDE per sub-query, then merge + synthesize.
|
|
13
17
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
18
|
+
* **Strategy selection criteria** (LLM-as-judge evaluates):
|
|
19
|
+
* - Is the query factual/concrete or abstract/vague?
|
|
20
|
+
* - Does it require reasoning across multiple documents?
|
|
21
|
+
* - Would vocabulary mismatch between query and docs degrade direct search?
|
|
22
|
+
* - Is decomposition needed (multi-part question)?
|
|
17
23
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
24
|
+
* **Capability selection** (when a CapabilityDiscoveryEngine is attached):
|
|
25
|
+
* - Tier 0 summaries (~150 tokens) from the discovery engine are injected
|
|
26
|
+
* into the classification prompt so the LLM can recommend which skills,
|
|
27
|
+
* tools, and extensions to activate.
|
|
28
|
+
* - When no discovery engine is available, a keyword-based heuristic
|
|
29
|
+
* selects capabilities as a zero-cost fallback.
|
|
30
|
+
*
|
|
31
|
+
* The classifier also includes a zero-cost **heuristic fallback** for offline
|
|
32
|
+
* and cost-constrained scenarios.
|
|
20
33
|
*
|
|
21
34
|
* @module @framers/agentos/query-router/QueryClassifier
|
|
22
35
|
*/
|
|
23
36
|
import { generateText } from '../api/generateText.js';
|
|
37
|
+
import { STRATEGY_TO_TIER, TIER_TO_STRATEGY, } from './types.js';
|
|
38
|
+
import { buildDefaultPlan, buildDefaultExecutionPlan } from '../rag/unified/types.js';
|
|
24
39
|
// ============================================================================
|
|
25
40
|
// System Prompt Template
|
|
26
41
|
// ============================================================================
|
|
27
42
|
/**
|
|
28
43
|
* Chain-of-thought system prompt template for the query classifier.
|
|
29
44
|
*
|
|
45
|
+
* This prompt asks the LLM to evaluate both the complexity tier AND the
|
|
46
|
+
* optimal retrieval strategy, including whether HyDE (Hypothetical Document
|
|
47
|
+
* Embedding) should be used to bridge vocabulary gaps.
|
|
48
|
+
*
|
|
30
49
|
* Placeholders:
|
|
31
50
|
* - `{{TOPIC_LIST}}` — known corpus topics
|
|
32
51
|
* - `{{TOOL_LIST}}` — available tools
|
|
33
52
|
* - `{{CONVERSATION_CONTEXT}}` — recent conversation history (may be empty)
|
|
34
53
|
*/
|
|
35
|
-
const SYSTEM_PROMPT_TEMPLATE = `You are a query complexity classifier. Your job is to analyze the user's query and determine
|
|
54
|
+
const SYSTEM_PROMPT_TEMPLATE = `You are a query complexity classifier and retrieval strategy selector. Your job is to analyze the user's query and determine both the complexity tier AND the optimal retrieval strategy.
|
|
36
55
|
|
|
37
56
|
## Tier Definitions
|
|
38
57
|
|
|
@@ -41,6 +60,22 @@ const SYSTEM_PROMPT_TEMPLATE = `You are a query complexity classifier. Your job
|
|
|
41
60
|
- **T2 (Multi-source)**: Questions that span multiple documents or require combining information from different parts of the codebase. May need graph traversal.
|
|
42
61
|
- **T3 (Research)**: Deep investigation questions that require iterative multi-pass retrieval, synthesis, and comparison across the entire corpus.
|
|
43
62
|
|
|
63
|
+
## Retrieval Strategies
|
|
64
|
+
|
|
65
|
+
- **none**: Skip retrieval entirely. Use when the query is answerable from context alone (T0).
|
|
66
|
+
- **simple**: Direct embedding search. Use when the query uses concrete, specific vocabulary that likely matches stored documents. Fast and cheap.
|
|
67
|
+
- **moderate**: HyDE (Hypothetical Document Embedding) retrieval. Use when the query is abstract, uses different vocabulary than docs might, or asks "how" / "why" / "explain" questions where generating a hypothetical answer first would improve search quality.
|
|
68
|
+
- **complex**: HyDE + query decomposition. Use for multi-part questions, comparative analysis, or queries requiring information synthesis across many sources.
|
|
69
|
+
|
|
70
|
+
## Strategy Selection Criteria
|
|
71
|
+
|
|
72
|
+
Evaluate these dimensions:
|
|
73
|
+
1. **Vocabulary match**: Would the query terms directly match document terms? If not, HyDE helps.
|
|
74
|
+
2. **Abstraction level**: Abstract/vague queries benefit from HyDE (moderate). Concrete lookups do not (simple).
|
|
75
|
+
3. **Multi-part**: Questions with "and", "also", "compare", "differences" → complex.
|
|
76
|
+
4. **Reasoning depth**: "Explain implications", "analyze tradeoffs" → moderate or complex.
|
|
77
|
+
5. **Decomposability**: Can the query be split into independent sub-questions? → complex.
|
|
78
|
+
|
|
44
79
|
## Known Topics
|
|
45
80
|
{{TOPIC_LIST}}
|
|
46
81
|
|
|
@@ -56,23 +91,205 @@ Think step-by-step about the query:
|
|
|
56
91
|
1. What is the user actually asking?
|
|
57
92
|
2. Can this be answered from general knowledge or conversation context alone?
|
|
58
93
|
3. How many sources/documents would be needed?
|
|
59
|
-
4.
|
|
94
|
+
4. Would the query vocabulary match stored document vocabulary directly?
|
|
95
|
+
5. Should HyDE be used to bridge semantic gaps?
|
|
96
|
+
6. Does the query need decomposition into sub-queries?
|
|
97
|
+
7. Are any tools required?
|
|
60
98
|
|
|
61
99
|
Respond with ONLY a JSON object (no markdown fences, no extra text):
|
|
62
100
|
{
|
|
63
101
|
"thinking": "<your step-by-step reasoning>",
|
|
64
102
|
"tier": <0|1|2|3>,
|
|
103
|
+
"strategy": "<none|simple|moderate|complex>",
|
|
65
104
|
"confidence": <0.0 to 1.0>,
|
|
66
105
|
"internal_knowledge_sufficient": <true|false>,
|
|
67
106
|
"suggested_sources": [<"vector"|"graph"|"research">],
|
|
68
107
|
"tools_needed": [<tool names or empty>]
|
|
69
108
|
}`;
|
|
70
109
|
// ============================================================================
|
|
110
|
+
// Plan-Aware System Prompt Template (for classifyWithPlan)
|
|
111
|
+
// ============================================================================
|
|
112
|
+
/**
|
|
113
|
+
* Enhanced chain-of-thought system prompt for the plan-aware classifier.
|
|
114
|
+
*
|
|
115
|
+
* This prompt asks the LLM to evaluate MORE dimensions than the base classifier:
|
|
116
|
+
* complexity, source selection, memory relevance, modality, temporal preferences,
|
|
117
|
+
* and decomposability. It produces a full {@link RetrievalPlan} as output.
|
|
118
|
+
*
|
|
119
|
+
* Placeholders:
|
|
120
|
+
* - `{{TOPIC_LIST}}` — known corpus topics
|
|
121
|
+
* - `{{TOOL_LIST}}` — available tools
|
|
122
|
+
* - `{{CONVERSATION_CONTEXT}}` — recent conversation history (may be empty)
|
|
123
|
+
*/
|
|
124
|
+
const PLAN_SYSTEM_PROMPT_TEMPLATE = `You are an advanced query classifier, retrieval plan generator, and capability recommender. Your job is to analyze the user's query and produce a structured execution plan specifying:
|
|
125
|
+
1. Which retrieval sources to query and how to combine them
|
|
126
|
+
2. What memory types to consult
|
|
127
|
+
3. Which skills, tools, and extensions should be activated to fulfill the request
|
|
128
|
+
|
|
129
|
+
## Source Definitions
|
|
130
|
+
|
|
131
|
+
- **vector**: Dense vector similarity search. Good for semantic matching.
|
|
132
|
+
- **bm25**: Sparse keyword search. Good for exact terms, error codes, function names.
|
|
133
|
+
- **graph**: GraphRAG entity/relationship traversal. Good for "how does X relate to Y" queries.
|
|
134
|
+
- **raptor**: RAPTOR hierarchical summary tree. Good for theme/overview queries.
|
|
135
|
+
- **memory**: Cognitive memory (episodic/semantic/procedural). Good for recalling past interactions.
|
|
136
|
+
- **multimodal**: Image/audio/video search. Only needed when query references visual or audio content.
|
|
137
|
+
|
|
138
|
+
## Memory Types
|
|
139
|
+
|
|
140
|
+
- **episodic**: Past events, interactions, conversations the agent experienced.
|
|
141
|
+
- **semantic**: Facts, knowledge, learned concepts.
|
|
142
|
+
- **procedural**: Workflows, how-to knowledge, step-by-step processes.
|
|
143
|
+
- **prospective**: Upcoming intentions, reminders, planned future actions.
|
|
144
|
+
|
|
145
|
+
## Known Topics
|
|
146
|
+
{{TOPIC_LIST}}
|
|
147
|
+
|
|
148
|
+
## Available Tools
|
|
149
|
+
{{TOOL_LIST}}
|
|
150
|
+
|
|
151
|
+
## Available Skill Categories
|
|
152
|
+
{{SKILL_SUMMARIES}}
|
|
153
|
+
|
|
154
|
+
## Available Tool Categories
|
|
155
|
+
{{TOOL_SUMMARIES}}
|
|
156
|
+
|
|
157
|
+
## Available Extension Categories
|
|
158
|
+
{{EXTENSION_SUMMARIES}}
|
|
159
|
+
|
|
160
|
+
## Conversation Context
|
|
161
|
+
{{CONVERSATION_CONTEXT}}
|
|
162
|
+
|
|
163
|
+
## Instructions
|
|
164
|
+
|
|
165
|
+
Think step by step about this query:
|
|
166
|
+
|
|
167
|
+
1. COMPLEXITY: Is this a simple lookup, moderate analysis, or complex research?
|
|
168
|
+
2. RETRIEVAL SOURCES: Would keyword search help? Would entity relationships help? Would hierarchical summaries help?
|
|
169
|
+
3. MEMORY RELEVANCE: Has the agent seen related information before? Should we check episodic or semantic memory?
|
|
170
|
+
4. MODALITY: Does this query reference images, audio, or visual content?
|
|
171
|
+
5. TEMPORAL: Is this about recent events? Should we prefer newer information?
|
|
172
|
+
6. DECOMPOSABILITY: Can this be broken into sub-questions?
|
|
173
|
+
7. SKILLS NEEDED: Based on the available skill categories above, which skills should be activated? Consider skills that would help fulfill the user's request (e.g., web-search for finding information, coding-agent for code tasks, email-intelligence for email tasks). Only recommend skills that are genuinely needed.
|
|
174
|
+
8. TOOLS NEEDED: Based on the available tool categories above, which specific tools should be made available? Consider tools the agent will need to invoke (e.g., generateImage for image requests, webSearch for web queries). Only recommend tools that are genuinely needed.
|
|
175
|
+
9. EXTENSIONS NEEDED: Based on the available extension categories above, which extensions should be loaded? Extensions are heavier than individual tools, so only recommend when their full bundle is needed (e.g., browser-automation for web scraping tasks, voice-synthesis for audio output).
|
|
176
|
+
10. EXTERNAL CALLS: Does this query require calling external APIs or services beyond internal knowledge retrieval?
|
|
177
|
+
|
|
178
|
+
Based on your analysis, output ONLY a JSON object (no markdown fences, no extra text):
|
|
179
|
+
{
|
|
180
|
+
"thinking": "<your step-by-step reasoning covering ALL 10 dimensions above>",
|
|
181
|
+
"strategy": "none|simple|moderate|complex",
|
|
182
|
+
"sources": {
|
|
183
|
+
"vector": true,
|
|
184
|
+
"bm25": true,
|
|
185
|
+
"graph": false,
|
|
186
|
+
"raptor": false,
|
|
187
|
+
"memory": true,
|
|
188
|
+
"multimodal": false
|
|
189
|
+
},
|
|
190
|
+
"hyde": {
|
|
191
|
+
"enabled": false,
|
|
192
|
+
"hypothesisCount": 1
|
|
193
|
+
},
|
|
194
|
+
"memoryTypes": ["semantic"],
|
|
195
|
+
"modalities": ["text"],
|
|
196
|
+
"temporal": {
|
|
197
|
+
"preferRecent": false,
|
|
198
|
+
"recencyBoost": 1.0,
|
|
199
|
+
"maxAgeMs": null
|
|
200
|
+
},
|
|
201
|
+
"graphConfig": {
|
|
202
|
+
"maxDepth": 2,
|
|
203
|
+
"minEdgeWeight": 0.3
|
|
204
|
+
},
|
|
205
|
+
"raptorLayers": [0],
|
|
206
|
+
"deepResearch": false,
|
|
207
|
+
"skills": [
|
|
208
|
+
{"skillId": "skill-name", "reasoning": "why needed", "confidence": 0.9, "priority": 0}
|
|
209
|
+
],
|
|
210
|
+
"tools": [
|
|
211
|
+
{"toolId": "tool-name", "reasoning": "why needed", "confidence": 0.9, "priority": 0}
|
|
212
|
+
],
|
|
213
|
+
"extensions": [
|
|
214
|
+
{"extensionId": "ext-name", "reasoning": "why needed", "confidence": 0.8, "priority": 0}
|
|
215
|
+
],
|
|
216
|
+
"requires_external_calls": false,
|
|
217
|
+
"confidence": 0.9,
|
|
218
|
+
"reasoning": "<concise explanation of why this plan was chosen>",
|
|
219
|
+
"tier": 1,
|
|
220
|
+
"internal_knowledge_sufficient": false,
|
|
221
|
+
"suggested_sources": ["vector"],
|
|
222
|
+
"tools_needed": []
|
|
223
|
+
}`;
|
|
224
|
+
// ============================================================================
|
|
225
|
+
// Valid strategy values for runtime validation
|
|
226
|
+
// ============================================================================
|
|
227
|
+
/** Set of valid retrieval strategy string values. */
|
|
228
|
+
const VALID_STRATEGIES = new Set(['none', 'simple', 'moderate', 'complex']);
|
|
229
|
+
// ============================================================================
|
|
230
|
+
// Heuristic Classifier
|
|
231
|
+
// ============================================================================
|
|
232
|
+
/**
|
|
233
|
+
* Rule-based heuristic classifier for retrieval strategy selection.
|
|
234
|
+
*
|
|
235
|
+
* Provides a zero-cost, zero-latency alternative to the LLM classifier.
|
|
236
|
+
* Evaluates query characteristics (word count, question words, multi-part
|
|
237
|
+
* indicators, abstraction signals) to recommend a retrieval strategy.
|
|
238
|
+
*
|
|
239
|
+
* Heuristic rules (evaluated in order):
|
|
240
|
+
* 1. Very short queries (<=5 words) without question words → `simple`
|
|
241
|
+
* 2. Multi-part indicators ("and also", "compare", "differences") → `complex`
|
|
242
|
+
* 3. Long queries (>30 words) → `complex`
|
|
243
|
+
* 4. Abstract/reasoning question words with >10 words → `moderate`
|
|
244
|
+
* 5. Greeting patterns → `none`
|
|
245
|
+
* 6. Default → `simple`
|
|
246
|
+
*
|
|
247
|
+
* @param query - The raw user query string.
|
|
248
|
+
* @returns The recommended retrieval strategy.
|
|
249
|
+
*/
|
|
250
|
+
export function heuristicClassify(query) {
|
|
251
|
+
const trimmed = query.trim();
|
|
252
|
+
// Greeting / trivial detection
|
|
253
|
+
if (/^(hi|hello|hey|howdy|good\s+(morning|afternoon|evening)|thanks|thank\s+you|bye|goodbye)\b/i.test(trimmed)) {
|
|
254
|
+
return 'none';
|
|
255
|
+
}
|
|
256
|
+
const wordCount = trimmed.split(/\s+/).length;
|
|
257
|
+
const hasAbstractQuestionWords = /\b(how|why|explain|compare|analyze|analyse|implications|impact|tradeoffs?|trade-offs?|differences?|pros\s+and\s+cons)\b/i.test(trimmed);
|
|
258
|
+
const hasSimpleQuestionWords = /\b(what|where|which|when|who|is|does|can)\b/i.test(trimmed);
|
|
259
|
+
const hasMultipleParts = /\b(and\s+also|additionally|furthermore|plus|as\s+well\s+as|compare|versus|vs\.?|differences?\s+between)\b/i.test(trimmed);
|
|
260
|
+
const hasDecompositionSignals = /\b(first.*then|both.*and|each|all\s+of|every|respectively|steps?\s+to|outline)\b/i.test(trimmed);
|
|
261
|
+
// Short, concrete query → simple direct search
|
|
262
|
+
if (wordCount <= 5 && !hasAbstractQuestionWords) {
|
|
263
|
+
return 'simple';
|
|
264
|
+
}
|
|
265
|
+
// Multi-part or decomposable → complex (HyDE + decompose)
|
|
266
|
+
if (hasMultipleParts || hasDecompositionSignals || wordCount > 30) {
|
|
267
|
+
return 'complex';
|
|
268
|
+
}
|
|
269
|
+
// Abstract/reasoning with moderate length → moderate (HyDE)
|
|
270
|
+
if (hasAbstractQuestionWords && wordCount > 10) {
|
|
271
|
+
return 'moderate';
|
|
272
|
+
}
|
|
273
|
+
// Simple question words → simple
|
|
274
|
+
if (hasSimpleQuestionWords && wordCount <= 15) {
|
|
275
|
+
return 'simple';
|
|
276
|
+
}
|
|
277
|
+
// Medium-length queries with question words → moderate (benefit from HyDE)
|
|
278
|
+
if ((hasAbstractQuestionWords || hasSimpleQuestionWords) && wordCount > 15) {
|
|
279
|
+
return 'moderate';
|
|
280
|
+
}
|
|
281
|
+
return 'simple';
|
|
282
|
+
}
|
|
283
|
+
// ============================================================================
|
|
71
284
|
// QueryClassifier
|
|
72
285
|
// ============================================================================
|
|
73
286
|
/**
|
|
74
287
|
* Chain-of-thought LLM classifier that determines retrieval depth (T0-T3)
|
|
75
|
-
* for each
|
|
288
|
+
* and retrieval strategy (`none`/`simple`/`moderate`/`complex`) for each
|
|
289
|
+
* incoming query.
|
|
290
|
+
*
|
|
291
|
+
* The strategy field controls whether HyDE (Hypothetical Document Embedding)
|
|
292
|
+
* is engaged during retrieval and at what depth.
|
|
76
293
|
*
|
|
77
294
|
* @example
|
|
78
295
|
* ```ts
|
|
@@ -86,7 +303,8 @@ Respond with ONLY a JSON object (no markdown fences, no extra text):
|
|
|
86
303
|
* });
|
|
87
304
|
*
|
|
88
305
|
* const result = await classifier.classify('How does auth work?');
|
|
89
|
-
* console.log(result.tier);
|
|
306
|
+
* console.log(result.tier); // 1
|
|
307
|
+
* console.log(result.strategy); // 'moderate'
|
|
90
308
|
* ```
|
|
91
309
|
*/
|
|
92
310
|
export class QueryClassifier {
|
|
@@ -95,23 +313,61 @@ export class QueryClassifier {
|
|
|
95
313
|
* @param config - Classifier configuration with model, provider, and thresholds.
|
|
96
314
|
*/
|
|
97
315
|
constructor(config) {
|
|
316
|
+
/**
|
|
317
|
+
* Optional capability discovery engine for Tier 0 summaries.
|
|
318
|
+
*
|
|
319
|
+
* When set, the plan-aware classifier injects category-level capability
|
|
320
|
+
* summaries (~150 tokens) into the LLM prompt so it can recommend which
|
|
321
|
+
* skills, tools, and extensions to activate. When absent, the classifier
|
|
322
|
+
* falls back to keyword-based heuristic capability selection.
|
|
323
|
+
*/
|
|
324
|
+
this.discoveryEngine = null;
|
|
98
325
|
this.config = config;
|
|
99
326
|
}
|
|
100
327
|
/**
|
|
101
|
-
*
|
|
328
|
+
* Attach a {@link CapabilityDiscoveryEngine} for Tier 0 capability summaries.
|
|
329
|
+
*
|
|
330
|
+
* When attached, the plan-aware classifier (`classifyWithPlan`) injects
|
|
331
|
+
* category-level summaries of all available skills, tools, and extensions
|
|
332
|
+
* into the LLM prompt. This allows the LLM to recommend capability
|
|
333
|
+
* activations alongside the retrieval plan, without loading full schemas.
|
|
334
|
+
*
|
|
335
|
+
* @param engine - A configured and initialized CapabilityDiscoveryEngine, or `null` to detach.
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```typescript
|
|
339
|
+
* const engine = new CapabilityDiscoveryEngine(embeddingManager, vectorStore);
|
|
340
|
+
* await engine.initialize({ tools, skills, extensions, channels });
|
|
341
|
+
* classifier.setCapabilityDiscoveryEngine(engine);
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
setCapabilityDiscoveryEngine(engine) {
|
|
345
|
+
this.discoveryEngine = engine;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Get the attached CapabilityDiscoveryEngine, if any.
|
|
349
|
+
*
|
|
350
|
+
* @returns The discovery engine instance, or `null` if not configured.
|
|
351
|
+
*/
|
|
352
|
+
getCapabilityDiscoveryEngine() {
|
|
353
|
+
return this.discoveryEngine;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Classifies a user query into a retrieval tier and strategy.
|
|
102
357
|
*
|
|
103
358
|
* Steps:
|
|
104
|
-
* 1. Builds a chain-of-thought system prompt with tier definitions,
|
|
105
|
-
* tool list, and optional conversation context.
|
|
359
|
+
* 1. Builds a chain-of-thought system prompt with tier definitions, strategy
|
|
360
|
+
* definitions, topic list, tool list, and optional conversation context.
|
|
106
361
|
* 2. Calls the LLM via `generateText`.
|
|
107
362
|
* 3. Parses the JSON response (handling optional markdown code fences).
|
|
108
|
-
* 4.
|
|
109
|
-
* 5.
|
|
110
|
-
* 6.
|
|
363
|
+
* 4. Validates and normalises the `strategy` field (falls back to tier-inferred).
|
|
364
|
+
* 5. Applies confidence-based tier bumping: if confidence < threshold, tier += 1.
|
|
365
|
+
* 6. Caps the tier at the configured `maxTier`.
|
|
366
|
+
* 7. On ANY error, returns a safe T1/simple fallback with confidence 0.
|
|
111
367
|
*
|
|
112
368
|
* @param query - The user's query text to classify.
|
|
113
369
|
* @param conversationHistory - Optional recent conversation messages for context.
|
|
114
|
-
* @returns A {@link ClassificationResult} with tier, confidence, reasoning, and metadata.
|
|
370
|
+
* @returns A {@link ClassificationResult} with tier, strategy, confidence, reasoning, and metadata.
|
|
115
371
|
*/
|
|
116
372
|
async classify(query, conversationHistory) {
|
|
117
373
|
try {
|
|
@@ -133,8 +389,221 @@ export class QueryClassifier {
|
|
|
133
389
|
}
|
|
134
390
|
}
|
|
135
391
|
// --------------------------------------------------------------------------
|
|
392
|
+
// Plan-aware classification
|
|
393
|
+
// --------------------------------------------------------------------------
|
|
394
|
+
/**
|
|
395
|
+
* Classifies a query and produces a full {@link ExecutionPlan}.
|
|
396
|
+
*
|
|
397
|
+
* This is an enhanced alternative to {@link classify} that evaluates more
|
|
398
|
+
* dimensions (source selection, memory relevance, modality, temporal
|
|
399
|
+
* preferences, decomposability, capability recommendations) and outputs a
|
|
400
|
+
* structured plan that the {@link UnifiedRetriever} can execute directly,
|
|
401
|
+
* along with skill/tool/extension recommendations for the agent runtime.
|
|
402
|
+
*
|
|
403
|
+
* When a {@link CapabilityDiscoveryEngine} is attached (via
|
|
404
|
+
* {@link setCapabilityDiscoveryEngine}), the LLM prompt includes Tier 0
|
|
405
|
+
* summaries (~150 tokens) of all available capabilities, enabling the LLM
|
|
406
|
+
* to recommend specific skills, tools, and extensions.
|
|
407
|
+
*
|
|
408
|
+
* Falls back to {@link buildDefaultExecutionPlan} with heuristic capability
|
|
409
|
+
* selection when classification fails or the LLM response is malformed.
|
|
410
|
+
*
|
|
411
|
+
* @param query - The user's query text to classify.
|
|
412
|
+
* @param conversationHistory - Optional recent conversation messages for context.
|
|
413
|
+
* @returns A tuple of [ClassificationResult, ExecutionPlan].
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```typescript
|
|
417
|
+
* const [classification, plan] = await classifier.classifyWithPlan(
|
|
418
|
+
* 'Search the web for recent AI news and summarize findings',
|
|
419
|
+
* );
|
|
420
|
+
* // plan.skills → [{ skillId: 'web-search', ... }]
|
|
421
|
+
* // plan.tools → []
|
|
422
|
+
* const result = await unifiedRetriever.retrieve(query, plan);
|
|
423
|
+
* ```
|
|
424
|
+
*
|
|
425
|
+
* @see classify for the simpler tier+strategy classification
|
|
426
|
+
* @see buildDefaultExecutionPlan for execution plan defaults per strategy level
|
|
427
|
+
*/
|
|
428
|
+
async classifyWithPlan(query, conversationHistory) {
|
|
429
|
+
try {
|
|
430
|
+
const systemPrompt = this.buildPlanSystemPrompt(conversationHistory);
|
|
431
|
+
const response = await generateText({
|
|
432
|
+
provider: this.config.provider,
|
|
433
|
+
model: this.config.model,
|
|
434
|
+
system: systemPrompt,
|
|
435
|
+
prompt: query,
|
|
436
|
+
temperature: 0.1,
|
|
437
|
+
apiKey: this.config.apiKey,
|
|
438
|
+
baseUrl: this.config.baseUrl,
|
|
439
|
+
});
|
|
440
|
+
const { classification, plan } = this.parsePlanResponse(response.text);
|
|
441
|
+
const constrainedClassification = this.applyConstraints(classification);
|
|
442
|
+
// Re-sync plan strategy with constrained classification
|
|
443
|
+
const constrainedPlan = {
|
|
444
|
+
...plan,
|
|
445
|
+
strategy: constrainedClassification.strategy,
|
|
446
|
+
confidence: constrainedClassification.confidence,
|
|
447
|
+
};
|
|
448
|
+
return [constrainedClassification, constrainedPlan];
|
|
449
|
+
}
|
|
450
|
+
catch {
|
|
451
|
+
const fallback = this.fallbackResult();
|
|
452
|
+
const heuristicCaps = heuristicCapabilitySelect(query);
|
|
453
|
+
return [fallback, buildDefaultExecutionPlan(fallback.strategy, {
|
|
454
|
+
skills: heuristicCaps.skills,
|
|
455
|
+
tools: heuristicCaps.tools,
|
|
456
|
+
requiresExternalCalls: heuristicCaps.skills.length > 0 || heuristicCaps.tools.length > 0,
|
|
457
|
+
internalKnowledgeSufficient: heuristicCaps.skills.length === 0 && heuristicCaps.tools.length === 0,
|
|
458
|
+
})];
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
// --------------------------------------------------------------------------
|
|
136
462
|
// Private helpers
|
|
137
463
|
// --------------------------------------------------------------------------
|
|
464
|
+
/**
|
|
465
|
+
* Builds the plan-aware system prompt by replacing template placeholders.
|
|
466
|
+
*
|
|
467
|
+
* When a {@link CapabilityDiscoveryEngine} is attached, Tier 0 summaries
|
|
468
|
+
* for skills, tools, and extensions are injected into the prompt via the
|
|
469
|
+
* `{{SKILL_SUMMARIES}}`, `{{TOOL_SUMMARIES}}`, and `{{EXTENSION_SUMMARIES}}`
|
|
470
|
+
* placeholders. This costs ~150 extra tokens total but enables the LLM to
|
|
471
|
+
* make informed capability activation recommendations.
|
|
472
|
+
*
|
|
473
|
+
* When no discovery engine is attached, the capability summary placeholders
|
|
474
|
+
* are replaced with a "Not available" message.
|
|
475
|
+
*
|
|
476
|
+
* @param conversationHistory - Optional conversation messages to include.
|
|
477
|
+
* @returns The fully rendered plan system prompt string.
|
|
478
|
+
*/
|
|
479
|
+
buildPlanSystemPrompt(conversationHistory) {
|
|
480
|
+
let conversationContext = 'No prior conversation.';
|
|
481
|
+
if (conversationHistory && conversationHistory.length > 0) {
|
|
482
|
+
conversationContext = conversationHistory
|
|
483
|
+
.map((msg) => `${msg.role}: ${msg.content}`)
|
|
484
|
+
.join('\n');
|
|
485
|
+
}
|
|
486
|
+
// Resolve Tier 0 capability summaries from the discovery engine
|
|
487
|
+
let skillSummaries = 'No skill categories available.';
|
|
488
|
+
let toolSummaries = 'No tool categories available.';
|
|
489
|
+
let extensionSummaries = 'No extension categories available.';
|
|
490
|
+
if (this.discoveryEngine?.isInitialized()) {
|
|
491
|
+
const byKind = this.discoveryEngine.getTier0SummariesByKind();
|
|
492
|
+
if (byKind.skills)
|
|
493
|
+
skillSummaries = byKind.skills;
|
|
494
|
+
if (byKind.tools)
|
|
495
|
+
toolSummaries = byKind.tools;
|
|
496
|
+
if (byKind.extensions)
|
|
497
|
+
extensionSummaries = byKind.extensions;
|
|
498
|
+
}
|
|
499
|
+
return PLAN_SYSTEM_PROMPT_TEMPLATE
|
|
500
|
+
.replace('{{TOPIC_LIST}}', this.config.topicList)
|
|
501
|
+
.replace('{{TOOL_LIST}}', this.config.toolList)
|
|
502
|
+
.replace('{{SKILL_SUMMARIES}}', skillSummaries)
|
|
503
|
+
.replace('{{TOOL_SUMMARIES}}', toolSummaries)
|
|
504
|
+
.replace('{{EXTENSION_SUMMARIES}}', extensionSummaries)
|
|
505
|
+
.replace('{{CONVERSATION_CONTEXT}}', conversationContext);
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Parses the LLM response for plan-aware classification.
|
|
509
|
+
*
|
|
510
|
+
* Extracts the base {@link ClassificationResult}, the full retrieval
|
|
511
|
+
* configuration, AND capability recommendations (skills, tools, extensions)
|
|
512
|
+
* from the LLM JSON output. Missing plan fields are filled from
|
|
513
|
+
* {@link buildDefaultPlan} defaults. Missing capability arrays default to empty.
|
|
514
|
+
*
|
|
515
|
+
* @param text - Raw text from the LLM response.
|
|
516
|
+
* @returns Parsed classification result and execution plan.
|
|
517
|
+
* @throws If the response cannot be parsed as valid JSON.
|
|
518
|
+
*/
|
|
519
|
+
parsePlanResponse(text) {
|
|
520
|
+
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
521
|
+
if (!jsonMatch) {
|
|
522
|
+
throw new Error(`Failed to extract JSON from plan classifier response: ${text.slice(0, 200)}`);
|
|
523
|
+
}
|
|
524
|
+
const raw = JSON.parse(jsonMatch[0]);
|
|
525
|
+
const tier = raw.tier;
|
|
526
|
+
const strategy = raw.strategy && VALID_STRATEGIES.has(raw.strategy)
|
|
527
|
+
? raw.strategy
|
|
528
|
+
: TIER_TO_STRATEGY[tier] ?? 'simple';
|
|
529
|
+
const classification = {
|
|
530
|
+
tier,
|
|
531
|
+
strategy,
|
|
532
|
+
confidence: raw.confidence,
|
|
533
|
+
reasoning: raw.thinking,
|
|
534
|
+
internalKnowledgeSufficient: raw.internal_knowledge_sufficient,
|
|
535
|
+
suggestedSources: raw.suggested_sources,
|
|
536
|
+
toolsNeeded: raw.tools_needed,
|
|
537
|
+
};
|
|
538
|
+
// Build the plan from LLM output, filling gaps from defaults
|
|
539
|
+
const defaults = buildDefaultPlan(strategy);
|
|
540
|
+
// Parse capability recommendations — validate and normalize each entry
|
|
541
|
+
const skills = (raw.skills ?? [])
|
|
542
|
+
.filter((s) => s.skillId)
|
|
543
|
+
.map((s, i) => ({
|
|
544
|
+
skillId: s.skillId,
|
|
545
|
+
reasoning: s.reasoning ?? 'Recommended by classifier',
|
|
546
|
+
confidence: Math.max(0, Math.min(1, s.confidence ?? 0.5)),
|
|
547
|
+
priority: s.priority ?? i,
|
|
548
|
+
}))
|
|
549
|
+
.sort((a, b) => a.priority - b.priority);
|
|
550
|
+
const tools = (raw.tools ?? [])
|
|
551
|
+
.filter((t) => t.toolId)
|
|
552
|
+
.map((t, i) => ({
|
|
553
|
+
toolId: t.toolId,
|
|
554
|
+
reasoning: t.reasoning ?? 'Recommended by classifier',
|
|
555
|
+
confidence: Math.max(0, Math.min(1, t.confidence ?? 0.5)),
|
|
556
|
+
priority: t.priority ?? i,
|
|
557
|
+
}))
|
|
558
|
+
.sort((a, b) => a.priority - b.priority);
|
|
559
|
+
const extensions = (raw.extensions ?? [])
|
|
560
|
+
.filter((e) => e.extensionId)
|
|
561
|
+
.map((e, i) => ({
|
|
562
|
+
extensionId: e.extensionId,
|
|
563
|
+
reasoning: e.reasoning ?? 'Recommended by classifier',
|
|
564
|
+
confidence: Math.max(0, Math.min(1, e.confidence ?? 0.5)),
|
|
565
|
+
priority: e.priority ?? i,
|
|
566
|
+
}))
|
|
567
|
+
.sort((a, b) => a.priority - b.priority);
|
|
568
|
+
const requiresExternalCalls = raw.requires_external_calls ??
|
|
569
|
+
(skills.length > 0 || tools.length > 0 || strategy !== 'none');
|
|
570
|
+
const plan = {
|
|
571
|
+
strategy,
|
|
572
|
+
sources: {
|
|
573
|
+
vector: raw.sources?.vector ?? defaults.sources.vector,
|
|
574
|
+
bm25: raw.sources?.bm25 ?? defaults.sources.bm25,
|
|
575
|
+
graph: raw.sources?.graph ?? defaults.sources.graph,
|
|
576
|
+
raptor: raw.sources?.raptor ?? defaults.sources.raptor,
|
|
577
|
+
memory: raw.sources?.memory ?? defaults.sources.memory,
|
|
578
|
+
multimodal: raw.sources?.multimodal ?? defaults.sources.multimodal,
|
|
579
|
+
},
|
|
580
|
+
hyde: {
|
|
581
|
+
enabled: raw.hyde?.enabled ?? defaults.hyde.enabled,
|
|
582
|
+
hypothesisCount: raw.hyde?.hypothesisCount ?? defaults.hyde.hypothesisCount,
|
|
583
|
+
},
|
|
584
|
+
memoryTypes: (raw.memoryTypes ?? defaults.memoryTypes),
|
|
585
|
+
modalities: (raw.modalities ?? defaults.modalities),
|
|
586
|
+
temporal: {
|
|
587
|
+
preferRecent: raw.temporal?.preferRecent ?? defaults.temporal.preferRecent,
|
|
588
|
+
recencyBoost: raw.temporal?.recencyBoost ?? defaults.temporal.recencyBoost,
|
|
589
|
+
maxAgeMs: raw.temporal?.maxAgeMs !== undefined ? raw.temporal.maxAgeMs : defaults.temporal.maxAgeMs,
|
|
590
|
+
},
|
|
591
|
+
graphConfig: {
|
|
592
|
+
maxDepth: raw.graphConfig?.maxDepth ?? defaults.graphConfig.maxDepth,
|
|
593
|
+
minEdgeWeight: raw.graphConfig?.minEdgeWeight ?? defaults.graphConfig.minEdgeWeight,
|
|
594
|
+
},
|
|
595
|
+
raptorLayers: raw.raptorLayers ?? defaults.raptorLayers,
|
|
596
|
+
deepResearch: raw.deepResearch ?? defaults.deepResearch,
|
|
597
|
+
confidence: raw.confidence,
|
|
598
|
+
reasoning: raw.reasoning ?? raw.thinking,
|
|
599
|
+
skills,
|
|
600
|
+
tools,
|
|
601
|
+
extensions,
|
|
602
|
+
requiresExternalCalls,
|
|
603
|
+
internalKnowledgeSufficient: raw.internal_knowledge_sufficient,
|
|
604
|
+
};
|
|
605
|
+
return { classification, plan };
|
|
606
|
+
}
|
|
138
607
|
/**
|
|
139
608
|
* Builds the system prompt by replacing template placeholders with actual
|
|
140
609
|
* topic list, tool list, and conversation context.
|
|
@@ -161,6 +630,10 @@ export class QueryClassifier {
|
|
|
161
630
|
* - Raw JSON object
|
|
162
631
|
* - JSON wrapped in markdown code fences (```json ... ```)
|
|
163
632
|
*
|
|
633
|
+
* The `strategy` field is validated against the set of known strategies.
|
|
634
|
+
* If the LLM returns an unrecognized strategy or omits it, the strategy
|
|
635
|
+
* is inferred from the tier via {@link TIER_TO_STRATEGY}.
|
|
636
|
+
*
|
|
164
637
|
* @param text - Raw text from the LLM response.
|
|
165
638
|
* @returns A parsed {@link ClassificationResult}.
|
|
166
639
|
* @throws If the response cannot be parsed as valid JSON.
|
|
@@ -172,8 +645,14 @@ export class QueryClassifier {
|
|
|
172
645
|
throw new Error(`Failed to extract JSON from classifier response: ${text.slice(0, 200)}`);
|
|
173
646
|
}
|
|
174
647
|
const raw = JSON.parse(jsonMatch[0]);
|
|
648
|
+
const tier = raw.tier;
|
|
649
|
+
// Validate the strategy field — fall back to tier-inferred if invalid or missing
|
|
650
|
+
const strategy = raw.strategy && VALID_STRATEGIES.has(raw.strategy)
|
|
651
|
+
? raw.strategy
|
|
652
|
+
: TIER_TO_STRATEGY[tier] ?? 'simple';
|
|
175
653
|
return {
|
|
176
|
-
tier
|
|
654
|
+
tier,
|
|
655
|
+
strategy,
|
|
177
656
|
confidence: raw.confidence,
|
|
178
657
|
reasoning: raw.thinking,
|
|
179
658
|
internalKnowledgeSufficient: raw.internal_knowledge_sufficient,
|
|
@@ -185,33 +664,49 @@ export class QueryClassifier {
|
|
|
185
664
|
* Applies post-classification constraints:
|
|
186
665
|
* 1. If confidence < threshold, bump tier by 1 (request broader retrieval).
|
|
187
666
|
* 2. Cap tier at the configured maxTier.
|
|
667
|
+
* 3. Re-synchronise the strategy with the potentially adjusted tier.
|
|
188
668
|
*
|
|
189
669
|
* @param result - The raw classification result from the LLM.
|
|
190
670
|
* @returns The constrained classification result.
|
|
191
671
|
*/
|
|
192
672
|
applyConstraints(result) {
|
|
193
673
|
let tier = result.tier;
|
|
674
|
+
let strategy = result.strategy;
|
|
194
675
|
// Bump tier when confidence is below the threshold
|
|
195
676
|
if (result.confidence < this.config.confidenceThreshold) {
|
|
196
677
|
tier = Math.min(tier + 1, 3);
|
|
197
678
|
}
|
|
198
679
|
// Cap at maxTier
|
|
199
680
|
tier = Math.min(tier, this.config.maxTier);
|
|
681
|
+
// Re-synchronise strategy with the (possibly adjusted) tier.
|
|
682
|
+
// If the tier was bumped and strategy didn't change, upgrade strategy
|
|
683
|
+
// to match the new tier level.
|
|
684
|
+
if (tier !== result.tier) {
|
|
685
|
+
const tierStrategy = TIER_TO_STRATEGY[tier];
|
|
686
|
+
// Only upgrade, never downgrade — STRATEGY_TO_TIER values ascend
|
|
687
|
+
if (STRATEGY_TO_TIER[tierStrategy] > STRATEGY_TO_TIER[strategy]) {
|
|
688
|
+
strategy = tierStrategy;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
200
691
|
return {
|
|
201
692
|
...result,
|
|
202
693
|
tier,
|
|
694
|
+
strategy,
|
|
203
695
|
};
|
|
204
696
|
}
|
|
205
697
|
/**
|
|
206
|
-
* Returns a safe T1 fallback result when classification fails
|
|
698
|
+
* Returns a safe T1/simple fallback result when classification fails.
|
|
699
|
+
*
|
|
207
700
|
* T1 ensures at least a basic vector search is performed, which is a
|
|
208
701
|
* reasonable default when the classifier cannot determine the right tier.
|
|
702
|
+
* Strategy `simple` avoids the overhead of HyDE when the LLM is down.
|
|
209
703
|
*
|
|
210
704
|
* @returns A T1 {@link ClassificationResult} with confidence 0.
|
|
211
705
|
*/
|
|
212
706
|
fallbackResult() {
|
|
213
707
|
return {
|
|
214
708
|
tier: 1,
|
|
709
|
+
strategy: 'simple',
|
|
215
710
|
confidence: 0,
|
|
216
711
|
reasoning: 'Classification failed; falling back to T1 for safety.',
|
|
217
712
|
internalKnowledgeSufficient: false,
|
|
@@ -220,4 +715,90 @@ export class QueryClassifier {
|
|
|
220
715
|
};
|
|
221
716
|
}
|
|
222
717
|
}
|
|
718
|
+
// ============================================================================
|
|
719
|
+
// Heuristic Capability Selection
|
|
720
|
+
// ============================================================================
|
|
721
|
+
/**
|
|
722
|
+
* Keyword-pattern-based capability matching rules.
|
|
723
|
+
*
|
|
724
|
+
* Each entry maps a regex pattern (tested against the lowercased query)
|
|
725
|
+
* to either a skill ID or a tool ID. When the pattern matches, the
|
|
726
|
+
* corresponding recommendation is included in the heuristic result.
|
|
727
|
+
*
|
|
728
|
+
* @internal
|
|
729
|
+
*/
|
|
730
|
+
const HEURISTIC_SKILL_PATTERNS = [
|
|
731
|
+
{ pattern: /\b(search|find|look\s*up|research|google|browse)\b/i, skillId: 'web-search', reasoning: 'Query involves finding external information' },
|
|
732
|
+
{ pattern: /\b(code|program|function|debug|refactor|implement|write\s*code|fix\s*bug)\b/i, skillId: 'coding-agent', reasoning: 'Query involves code creation or analysis' },
|
|
733
|
+
{ pattern: /\b(email|send\s*mail|inbox|compose\s*email|mail\s*to)\b/i, skillId: 'email-intelligence', reasoning: 'Query involves email operations' },
|
|
734
|
+
{ pattern: /\b(summarize|tldr|brief|digest|condense|synopsis)\b/i, skillId: 'summarize', reasoning: 'Query asks for content summarization' },
|
|
735
|
+
{ pattern: /\b(deep\s*research|investigate|thorough\s*analysis|literature\s*review)\b/i, skillId: 'deep-research', reasoning: 'Query requires deep investigation' },
|
|
736
|
+
{ pattern: /\b(translate|translation|in\s+\w+\s+language)\b/i, skillId: 'translation', reasoning: 'Query involves language translation' },
|
|
737
|
+
{ pattern: /\b(post\s+to|tweet|publish|share\s+on|social\s*media)\b/i, skillId: 'social-broadcast', reasoning: 'Query involves social media posting' },
|
|
738
|
+
{ pattern: /\b(youtube|video|tiktok|upload\s+video)\b/i, skillId: 'youtube-bot', reasoning: 'Query involves video platform operations' },
|
|
739
|
+
{ pattern: /\b(blog|article|write\s*post|publish\s*article)\b/i, skillId: 'blog-publisher', reasoning: 'Query involves blog or article creation' },
|
|
740
|
+
];
|
|
741
|
+
/**
|
|
742
|
+
* Keyword-pattern-based tool matching rules.
|
|
743
|
+
*
|
|
744
|
+
* @internal
|
|
745
|
+
*/
|
|
746
|
+
const HEURISTIC_TOOL_PATTERNS = [
|
|
747
|
+
{ pattern: /\b(image|picture|photo|draw|generate\s*image|illustration|artwork)\b/i, toolId: 'generateImage', reasoning: 'Query involves image generation' },
|
|
748
|
+
{ pattern: /\b(schedule|calendar|meeting|appointment|event|reminder)\b/i, toolId: 'calendar', reasoning: 'Query involves scheduling or calendar' },
|
|
749
|
+
{ pattern: /\b(web\s*search|search\s*online|look\s*up\s*online)\b/i, toolId: 'webSearch', reasoning: 'Query needs web search tool' },
|
|
750
|
+
{ pattern: /\b(file|read\s*file|write\s*file|save|open\s*document)\b/i, toolId: 'fileSystem', reasoning: 'Query involves file operations' },
|
|
751
|
+
{ pattern: /\b(run\s*code|execute|shell|terminal|command)\b/i, toolId: 'codeExecution', reasoning: 'Query requires code execution' },
|
|
752
|
+
{ pattern: /\b(analyze\s*data|chart|graph|plot|statistics|metrics)\b/i, toolId: 'dataAnalysis', reasoning: 'Query involves data analysis' },
|
|
753
|
+
];
|
|
754
|
+
/**
|
|
755
|
+
* Rule-based heuristic capability selection for when no LLM is available.
|
|
756
|
+
*
|
|
757
|
+
* Evaluates the query against a curated set of keyword patterns to recommend
|
|
758
|
+
* skills and tools. This provides zero-latency capability recommendations
|
|
759
|
+
* as a fallback when the LLM classifier is unavailable, times out, or
|
|
760
|
+
* returns an error.
|
|
761
|
+
*
|
|
762
|
+
* The heuristic is intentionally conservative — it only recommends
|
|
763
|
+
* capabilities when there is a strong keyword signal. False negatives
|
|
764
|
+
* (missing a recommendation) are preferred over false positives (recommending
|
|
765
|
+
* unnecessary capabilities) to avoid activation overhead.
|
|
766
|
+
*
|
|
767
|
+
* @param query - The raw user query string.
|
|
768
|
+
* @returns Object with `skills` and `tools` recommendation arrays.
|
|
769
|
+
*
|
|
770
|
+
* @example
|
|
771
|
+
* ```typescript
|
|
772
|
+
* const caps = heuristicCapabilitySelect('Search the web for AI news and generate an image');
|
|
773
|
+
* // caps.skills → [{ skillId: 'web-search', ... }]
|
|
774
|
+
* // caps.tools → [{ toolId: 'generateImage', ... }]
|
|
775
|
+
* ```
|
|
776
|
+
*/
|
|
777
|
+
export function heuristicCapabilitySelect(query) {
|
|
778
|
+
const skills = [];
|
|
779
|
+
const tools = [];
|
|
780
|
+
let skillPriority = 0;
|
|
781
|
+
let toolPriority = 0;
|
|
782
|
+
for (const { pattern, skillId, reasoning } of HEURISTIC_SKILL_PATTERNS) {
|
|
783
|
+
if (pattern.test(query)) {
|
|
784
|
+
skills.push({
|
|
785
|
+
skillId,
|
|
786
|
+
reasoning,
|
|
787
|
+
confidence: 0.6, // Heuristic confidence is lower than LLM
|
|
788
|
+
priority: skillPriority++,
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
for (const { pattern, toolId, reasoning } of HEURISTIC_TOOL_PATTERNS) {
|
|
793
|
+
if (pattern.test(query)) {
|
|
794
|
+
tools.push({
|
|
795
|
+
toolId,
|
|
796
|
+
reasoning,
|
|
797
|
+
confidence: 0.6, // Heuristic confidence is lower than LLM
|
|
798
|
+
priority: toolPriority++,
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
return { skills, tools };
|
|
803
|
+
}
|
|
223
804
|
//# sourceMappingURL=QueryClassifier.js.map
|