@framers/agentos 0.1.112 → 0.1.114
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 +39 -5
- package/dist/api/AgentOS.d.ts +45 -12
- package/dist/api/AgentOS.d.ts.map +1 -1
- package/dist/api/AgentOS.js +225 -78
- package/dist/api/AgentOS.js.map +1 -1
- package/dist/api/AgentOSOrchestrator.d.ts +8 -0
- package/dist/api/AgentOSOrchestrator.d.ts.map +1 -1
- package/dist/api/AgentOSOrchestrator.js +350 -59
- package/dist/api/AgentOSOrchestrator.js.map +1 -1
- package/dist/api/StreamChunkEmitter.d.ts.map +1 -1
- package/dist/api/StreamChunkEmitter.js +2 -0
- package/dist/api/StreamChunkEmitter.js.map +1 -1
- package/dist/api/agency.d.ts.map +1 -1
- package/dist/api/agency.js +47 -1
- package/dist/api/agency.js.map +1 -1
- package/dist/api/agent.d.ts +18 -5
- package/dist/api/agent.d.ts.map +1 -1
- package/dist/api/agent.js +48 -9
- package/dist/api/agent.js.map +1 -1
- package/dist/api/agentExport.d.ts +202 -0
- package/dist/api/agentExport.d.ts.map +1 -0
- package/dist/api/agentExport.js +323 -0
- package/dist/api/agentExport.js.map +1 -0
- package/dist/api/editImage.d.ts +119 -0
- package/dist/api/editImage.d.ts.map +1 -0
- package/dist/api/editImage.js +150 -0
- package/dist/api/editImage.js.map +1 -0
- package/dist/api/embedText.d.ts +137 -0
- package/dist/api/embedText.d.ts.map +1 -0
- package/dist/api/embedText.js +229 -0
- package/dist/api/embedText.js.map +1 -0
- package/dist/api/externalToolRegistry.d.ts +44 -0
- package/dist/api/externalToolRegistry.d.ts.map +1 -0
- package/dist/api/externalToolRegistry.js +245 -0
- package/dist/api/externalToolRegistry.js.map +1 -0
- package/dist/api/generateImage.d.ts +1 -1
- package/dist/api/generateImage.d.ts.map +1 -1
- package/dist/api/generateImage.js +17 -13
- package/dist/api/generateImage.js.map +1 -1
- package/dist/api/generateObject.d.ts +185 -0
- package/dist/api/generateObject.d.ts.map +1 -0
- package/dist/api/generateObject.js +249 -0
- package/dist/api/generateObject.js.map +1 -0
- package/dist/api/generateText.d.ts +13 -3
- package/dist/api/generateText.d.ts.map +1 -1
- package/dist/api/generateText.js +20 -5
- package/dist/api/generateText.js.map +1 -1
- package/dist/api/interfaces/IAgentOS.d.ts +29 -1
- package/dist/api/interfaces/IAgentOS.d.ts.map +1 -1
- package/dist/api/model.d.ts +7 -7
- package/dist/api/model.d.ts.map +1 -1
- package/dist/api/model.js +22 -16
- package/dist/api/model.js.map +1 -1
- package/dist/api/processRequestWithExternalTools.d.ts +26 -0
- package/dist/api/processRequestWithExternalTools.d.ts.map +1 -0
- package/dist/api/processRequestWithExternalTools.js +52 -0
- package/dist/api/processRequestWithExternalTools.js.map +1 -0
- package/dist/api/processRequestWithRegisteredTools.d.ts +56 -0
- package/dist/api/processRequestWithRegisteredTools.d.ts.map +1 -0
- package/dist/api/processRequestWithRegisteredTools.js +125 -0
- package/dist/api/processRequestWithRegisteredTools.js.map +1 -0
- package/dist/api/provider-defaults.d.ts.map +1 -1
- package/dist/api/provider-defaults.js +28 -0
- package/dist/api/provider-defaults.js.map +1 -1
- package/dist/api/resumeExternalToolRequestWithRegisteredTools.d.ts +71 -0
- package/dist/api/resumeExternalToolRequestWithRegisteredTools.d.ts.map +1 -0
- package/dist/api/resumeExternalToolRequestWithRegisteredTools.js +159 -0
- package/dist/api/resumeExternalToolRequestWithRegisteredTools.js.map +1 -0
- package/dist/api/strategies/agentGraphBuilder.d.ts +170 -0
- package/dist/api/strategies/agentGraphBuilder.d.ts.map +1 -0
- package/dist/api/strategies/agentGraphBuilder.js +299 -0
- package/dist/api/strategies/agentGraphBuilder.js.map +1 -0
- package/dist/api/strategies/debate.d.ts +12 -1
- package/dist/api/strategies/debate.d.ts.map +1 -1
- package/dist/api/strategies/debate.js +41 -5
- package/dist/api/strategies/debate.js.map +1 -1
- package/dist/api/strategies/graphCompiler.d.ts +84 -0
- package/dist/api/strategies/graphCompiler.d.ts.map +1 -0
- package/dist/api/strategies/graphCompiler.js +617 -0
- package/dist/api/strategies/graphCompiler.js.map +1 -0
- package/dist/api/strategies/hierarchical.d.ts +15 -1
- package/dist/api/strategies/hierarchical.d.ts.map +1 -1
- package/dist/api/strategies/hierarchical.js +53 -8
- package/dist/api/strategies/hierarchical.js.map +1 -1
- package/dist/api/strategies/index.d.ts +29 -4
- package/dist/api/strategies/index.d.ts.map +1 -1
- package/dist/api/strategies/index.js +28 -4
- package/dist/api/strategies/index.js.map +1 -1
- package/dist/api/strategies/parallel.d.ts +15 -4
- package/dist/api/strategies/parallel.d.ts.map +1 -1
- package/dist/api/strategies/parallel.js +53 -16
- package/dist/api/strategies/parallel.js.map +1 -1
- package/dist/api/strategies/review-loop.d.ts +15 -1
- package/dist/api/strategies/review-loop.d.ts.map +1 -1
- package/dist/api/strategies/review-loop.js +36 -10
- package/dist/api/strategies/review-loop.js.map +1 -1
- package/dist/api/strategies/sequential.d.ts +11 -1
- package/dist/api/strategies/sequential.d.ts.map +1 -1
- package/dist/api/strategies/sequential.js +39 -8
- package/dist/api/strategies/sequential.js.map +1 -1
- package/dist/api/strategies/shared.d.ts +72 -8
- package/dist/api/strategies/shared.d.ts.map +1 -1
- package/dist/api/strategies/shared.js +92 -12
- package/dist/api/strategies/shared.js.map +1 -1
- package/dist/api/streamObject.d.ts +166 -0
- package/dist/api/streamObject.d.ts.map +1 -0
- package/dist/api/streamObject.js +268 -0
- package/dist/api/streamObject.js.map +1 -0
- package/dist/api/streamText.d.ts +1 -1
- package/dist/api/streamText.d.ts.map +1 -1
- package/dist/api/streamText.js +26 -8
- package/dist/api/streamText.js.map +1 -1
- package/dist/api/toolAdapter.d.ts +44 -8
- package/dist/api/toolAdapter.d.ts.map +1 -1
- package/dist/api/toolAdapter.js +224 -45
- package/dist/api/toolAdapter.js.map +1 -1
- package/dist/api/types/AgentOSExternalToolRequest.d.ts +35 -0
- package/dist/api/types/AgentOSExternalToolRequest.d.ts.map +1 -0
- package/dist/api/types/AgentOSExternalToolRequest.js +2 -0
- package/dist/api/types/AgentOSExternalToolRequest.js.map +1 -0
- package/dist/api/types/AgentOSResponse.d.ts +25 -0
- package/dist/api/types/AgentOSResponse.d.ts.map +1 -1
- package/dist/api/types/AgentOSResponse.js +20 -0
- package/dist/api/types/AgentOSResponse.js.map +1 -1
- package/dist/api/types/AgentOSToolResult.d.ts +11 -0
- package/dist/api/types/AgentOSToolResult.d.ts.map +1 -0
- package/dist/api/types/AgentOSToolResult.js +2 -0
- package/dist/api/types/AgentOSToolResult.js.map +1 -0
- package/dist/api/types.d.ts +81 -4
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/types.js.map +1 -1
- package/dist/api/upscaleImage.d.ts +92 -0
- package/dist/api/upscaleImage.d.ts.map +1 -0
- package/dist/api/upscaleImage.js +133 -0
- package/dist/api/upscaleImage.js.map +1 -0
- package/dist/api/variateImage.d.ts +102 -0
- package/dist/api/variateImage.d.ts.map +1 -0
- package/dist/api/variateImage.js +154 -0
- package/dist/api/variateImage.js.map +1 -0
- package/dist/cognitive_substrate/GMI.d.ts +16 -2
- package/dist/cognitive_substrate/GMI.d.ts.map +1 -1
- package/dist/cognitive_substrate/GMI.js +188 -56
- package/dist/cognitive_substrate/GMI.js.map +1 -1
- package/dist/cognitive_substrate/IGMI.d.ts +10 -0
- package/dist/cognitive_substrate/IGMI.d.ts.map +1 -1
- package/dist/cognitive_substrate/IGMI.js.map +1 -1
- package/dist/config/AgentOSConfig.d.ts +19 -2
- package/dist/config/AgentOSConfig.d.ts.map +1 -1
- package/dist/config/AgentOSConfig.js +46 -29
- package/dist/config/AgentOSConfig.js.map +1 -1
- package/dist/core/guardrails/IGuardrailService.d.ts +1 -1
- package/dist/core/images/IImageProvider.d.ts +93 -0
- package/dist/core/images/IImageProvider.d.ts.map +1 -1
- package/dist/core/images/IImageProvider.js.map +1 -1
- package/dist/core/images/ImageOperationError.d.ts +52 -0
- package/dist/core/images/ImageOperationError.d.ts.map +1 -0
- package/dist/core/images/ImageOperationError.js +58 -0
- package/dist/core/images/ImageOperationError.js.map +1 -0
- package/dist/core/images/imageToBuffer.d.ts +41 -0
- package/dist/core/images/imageToBuffer.d.ts.map +1 -0
- package/dist/core/images/imageToBuffer.js +95 -0
- package/dist/core/images/imageToBuffer.js.map +1 -0
- package/dist/core/images/index.d.ts +4 -0
- package/dist/core/images/index.d.ts.map +1 -1
- package/dist/core/images/index.js +8 -0
- package/dist/core/images/index.js.map +1 -1
- package/dist/core/images/providers/FalImageProvider.d.ts +208 -0
- package/dist/core/images/providers/FalImageProvider.d.ts.map +1 -0
- package/dist/core/images/providers/FalImageProvider.js +301 -0
- package/dist/core/images/providers/FalImageProvider.js.map +1 -0
- package/dist/core/images/providers/FluxImageProvider.d.ts +197 -0
- package/dist/core/images/providers/FluxImageProvider.d.ts.map +1 -0
- package/dist/core/images/providers/FluxImageProvider.js +271 -0
- package/dist/core/images/providers/FluxImageProvider.js.map +1 -0
- package/dist/core/images/providers/OpenAIImageProvider.d.ts +33 -1
- package/dist/core/images/providers/OpenAIImageProvider.d.ts.map +1 -1
- package/dist/core/images/providers/OpenAIImageProvider.js +125 -0
- package/dist/core/images/providers/OpenAIImageProvider.js.map +1 -1
- package/dist/core/images/providers/ReplicateImageProvider.d.ts +26 -1
- package/dist/core/images/providers/ReplicateImageProvider.d.ts.map +1 -1
- package/dist/core/images/providers/ReplicateImageProvider.js +118 -0
- package/dist/core/images/providers/ReplicateImageProvider.js.map +1 -1
- package/dist/core/images/providers/StabilityImageProvider.d.ts +41 -1
- package/dist/core/images/providers/StabilityImageProvider.d.ts.map +1 -1
- package/dist/core/images/providers/StabilityImageProvider.js +180 -7
- package/dist/core/images/providers/StabilityImageProvider.js.map +1 -1
- package/dist/core/images/providers/StableDiffusionLocalProvider.d.ts +29 -1
- package/dist/core/images/providers/StableDiffusionLocalProvider.d.ts.map +1 -1
- package/dist/core/images/providers/StableDiffusionLocalProvider.js +124 -0
- package/dist/core/images/providers/StableDiffusionLocalProvider.js.map +1 -1
- package/dist/core/llm/IPromptEngine.d.ts +2 -2
- package/dist/core/llm/IPromptEngine.d.ts.map +1 -1
- package/dist/core/llm/IPromptEngine.js +2 -2
- package/dist/core/llm/IPromptEngine.js.map +1 -1
- package/dist/core/llm/providers/AIModelProviderManager.d.ts +7 -1
- package/dist/core/llm/providers/AIModelProviderManager.d.ts.map +1 -1
- package/dist/core/llm/providers/AIModelProviderManager.js +24 -0
- package/dist/core/llm/providers/AIModelProviderManager.js.map +1 -1
- package/dist/core/llm/providers/errors/AnthropicProviderError.d.ts +42 -0
- package/dist/core/llm/providers/errors/AnthropicProviderError.d.ts.map +1 -0
- package/dist/core/llm/providers/errors/AnthropicProviderError.js +45 -0
- package/dist/core/llm/providers/errors/AnthropicProviderError.js.map +1 -0
- package/dist/core/llm/providers/errors/GeminiProviderError.d.ts +45 -0
- package/dist/core/llm/providers/errors/GeminiProviderError.d.ts.map +1 -0
- package/dist/core/llm/providers/errors/GeminiProviderError.js +46 -0
- package/dist/core/llm/providers/errors/GeminiProviderError.js.map +1 -0
- package/dist/core/llm/providers/errors/OllamaProviderError.d.ts +1 -1
- package/dist/core/llm/providers/errors/OllamaProviderError.d.ts.map +1 -1
- package/dist/core/llm/providers/errors/OllamaProviderError.js +1 -1
- package/dist/core/llm/providers/errors/OllamaProviderError.js.map +1 -1
- package/dist/core/llm/providers/errors/OpenAIProviderError.d.ts +1 -1
- package/dist/core/llm/providers/errors/OpenAIProviderError.js +1 -1
- package/dist/core/llm/providers/errors/OpenRouterProviderError.d.ts +1 -1
- package/dist/core/llm/providers/errors/OpenRouterProviderError.js +1 -1
- package/dist/core/llm/providers/implementations/AnthropicProvider.d.ts +340 -0
- package/dist/core/llm/providers/implementations/AnthropicProvider.d.ts.map +1 -0
- package/dist/core/llm/providers/implementations/AnthropicProvider.js +959 -0
- package/dist/core/llm/providers/implementations/AnthropicProvider.js.map +1 -0
- package/dist/core/llm/providers/implementations/GeminiProvider.d.ts +339 -0
- package/dist/core/llm/providers/implementations/GeminiProvider.d.ts.map +1 -0
- package/dist/core/llm/providers/implementations/GeminiProvider.js +1004 -0
- package/dist/core/llm/providers/implementations/GeminiProvider.js.map +1 -0
- package/dist/core/llm/providers/implementations/GroqProvider.d.ts +105 -0
- package/dist/core/llm/providers/implementations/GroqProvider.d.ts.map +1 -0
- package/dist/core/llm/providers/implementations/GroqProvider.js +134 -0
- package/dist/core/llm/providers/implementations/GroqProvider.js.map +1 -0
- package/dist/core/llm/providers/implementations/MistralProvider.d.ts +105 -0
- package/dist/core/llm/providers/implementations/MistralProvider.d.ts.map +1 -0
- package/dist/core/llm/providers/implementations/MistralProvider.js +146 -0
- package/dist/core/llm/providers/implementations/MistralProvider.js.map +1 -0
- package/dist/core/llm/providers/implementations/TogetherProvider.d.ts +107 -0
- package/dist/core/llm/providers/implementations/TogetherProvider.d.ts.map +1 -0
- package/dist/core/llm/providers/implementations/TogetherProvider.js +138 -0
- package/dist/core/llm/providers/implementations/TogetherProvider.js.map +1 -0
- package/dist/core/llm/providers/implementations/XAIProvider.d.ts +102 -0
- package/dist/core/llm/providers/implementations/XAIProvider.d.ts.map +1 -0
- package/dist/core/llm/providers/implementations/XAIProvider.js +123 -0
- package/dist/core/llm/providers/implementations/XAIProvider.js.map +1 -0
- package/dist/core/orchestration/AgentOrchestrator.d.ts.map +1 -1
- package/dist/core/orchestration/AgentOrchestrator.js +26 -5
- package/dist/core/orchestration/AgentOrchestrator.js.map +1 -1
- package/dist/core/tools/IToolOrchestrator.d.ts +2 -2
- package/dist/core/tools/IToolOrchestrator.d.ts.map +1 -1
- package/dist/core/tools/ToolExecutor.d.ts +3 -0
- package/dist/core/tools/ToolExecutor.d.ts.map +1 -1
- package/dist/core/tools/ToolExecutor.js +2 -1
- package/dist/core/tools/ToolExecutor.js.map +1 -1
- package/dist/core/tools/ToolOrchestrator.d.ts +7 -7
- package/dist/core/tools/ToolOrchestrator.d.ts.map +1 -1
- package/dist/core/tools/ToolOrchestrator.js +135 -36
- package/dist/core/tools/ToolOrchestrator.js.map +1 -1
- package/dist/core/tools/permissions/ToolPermissionManager.d.ts +6 -5
- package/dist/core/tools/permissions/ToolPermissionManager.d.ts.map +1 -1
- package/dist/core/tools/permissions/ToolPermissionManager.js +47 -21
- package/dist/core/tools/permissions/ToolPermissionManager.js.map +1 -1
- package/dist/core/vision/VisionPipeline.d.ts +437 -0
- package/dist/core/vision/VisionPipeline.d.ts.map +1 -0
- package/dist/core/vision/VisionPipeline.js +1113 -0
- package/dist/core/vision/VisionPipeline.js.map +1 -0
- package/dist/core/vision/index.d.ts +97 -0
- package/dist/core/vision/index.d.ts.map +1 -0
- package/dist/core/vision/index.js +182 -0
- package/dist/core/vision/index.js.map +1 -0
- package/dist/core/vision/providers/LLMVisionProvider.d.ts +135 -0
- package/dist/core/vision/providers/LLMVisionProvider.d.ts.map +1 -0
- package/dist/core/vision/providers/LLMVisionProvider.js +136 -0
- package/dist/core/vision/providers/LLMVisionProvider.js.map +1 -0
- package/dist/core/vision/providers/PipelineVisionProvider.d.ts +154 -0
- package/dist/core/vision/providers/PipelineVisionProvider.d.ts.map +1 -0
- package/dist/core/vision/providers/PipelineVisionProvider.js +160 -0
- package/dist/core/vision/providers/PipelineVisionProvider.js.map +1 -0
- package/dist/core/vision/types.d.ts +286 -0
- package/dist/core/vision/types.d.ts.map +1 -0
- package/dist/core/vision/types.js +24 -0
- package/dist/core/vision/types.js.map +1 -0
- package/dist/discovery/CapabilityDiscoveryEngine.d.ts +1 -1
- package/dist/discovery/CapabilityDiscoveryEngine.d.ts.map +1 -1
- package/dist/discovery/CapabilityDiscoveryEngine.js +1 -1
- package/dist/discovery/CapabilityDiscoveryEngine.js.map +1 -1
- package/dist/emergent/ComposableToolBuilder.d.ts +15 -4
- package/dist/emergent/ComposableToolBuilder.d.ts.map +1 -1
- package/dist/emergent/ComposableToolBuilder.js +29 -14
- package/dist/emergent/ComposableToolBuilder.js.map +1 -1
- package/dist/emergent/EmergentCapabilityEngine.d.ts +3 -3
- package/dist/emergent/EmergentCapabilityEngine.d.ts.map +1 -1
- package/dist/emergent/EmergentCapabilityEngine.js +15 -12
- package/dist/emergent/EmergentCapabilityEngine.js.map +1 -1
- package/dist/emergent/EmergentJudge.d.ts +20 -0
- package/dist/emergent/EmergentJudge.d.ts.map +1 -1
- package/dist/emergent/EmergentJudge.js +121 -26
- package/dist/emergent/EmergentJudge.js.map +1 -1
- package/dist/emergent/EmergentToolRegistry.d.ts +17 -0
- package/dist/emergent/EmergentToolRegistry.d.ts.map +1 -1
- package/dist/emergent/EmergentToolRegistry.js +26 -0
- package/dist/emergent/EmergentToolRegistry.js.map +1 -1
- package/dist/emergent/ForgeToolMetaTool.d.ts +1 -1
- package/dist/emergent/ForgeToolMetaTool.d.ts.map +1 -1
- package/dist/emergent/ForgeToolMetaTool.js +15 -2
- package/dist/emergent/ForgeToolMetaTool.js.map +1 -1
- package/dist/emergent/SandboxedToolForge.d.ts +2 -2
- package/dist/emergent/SandboxedToolForge.d.ts.map +1 -1
- package/dist/emergent/SandboxedToolForge.js +13 -23
- package/dist/emergent/SandboxedToolForge.js.map +1 -1
- package/dist/emergent/SkillExporter.d.ts +119 -0
- package/dist/emergent/SkillExporter.d.ts.map +1 -0
- package/dist/emergent/SkillExporter.js +344 -0
- package/dist/emergent/SkillExporter.js.map +1 -0
- package/dist/emergent/index.d.ts +1 -0
- package/dist/emergent/index.d.ts.map +1 -1
- package/dist/emergent/index.js +1 -0
- package/dist/emergent/index.js.map +1 -1
- package/dist/emergent/types.d.ts +4 -4
- package/dist/index.d.ts +30 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -2
- package/dist/index.js.map +1 -1
- package/dist/memory/facade/Memory.d.ts.map +1 -1
- package/dist/memory/facade/Memory.js +8 -0
- package/dist/memory/facade/Memory.js.map +1 -1
- package/dist/memory/facade/types.d.ts +10 -0
- package/dist/memory/facade/types.d.ts.map +1 -1
- package/dist/memory/index.d.ts +15 -7
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +7 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/ingestion/DoclingLoader.d.ts +3 -3
- package/dist/memory/ingestion/DoclingLoader.d.ts.map +1 -1
- package/dist/memory/ingestion/DoclingLoader.js +12 -8
- package/dist/memory/ingestion/DoclingLoader.js.map +1 -1
- package/dist/memory/ingestion/FolderScanner.d.ts +7 -7
- package/dist/memory/ingestion/FolderScanner.d.ts.map +1 -1
- package/dist/memory/ingestion/FolderScanner.js +6 -6
- package/dist/memory/ingestion/FolderScanner.js.map +1 -1
- package/dist/memory/ingestion/LoaderRegistry.d.ts +8 -8
- package/dist/memory/ingestion/LoaderRegistry.d.ts.map +1 -1
- package/dist/memory/ingestion/LoaderRegistry.js +9 -11
- package/dist/memory/ingestion/LoaderRegistry.js.map +1 -1
- package/dist/memory/ingestion/MultimodalAggregator.d.ts +1 -1
- package/dist/memory/ingestion/MultimodalAggregator.js +1 -1
- package/dist/memory/ingestion/OcrPdfLoader.d.ts +2 -2
- package/dist/memory/ingestion/OcrPdfLoader.d.ts.map +1 -1
- package/dist/memory/ingestion/OcrPdfLoader.js +12 -8
- package/dist/memory/ingestion/OcrPdfLoader.js.map +1 -1
- package/dist/memory/ingestion/PdfLoader.d.ts +8 -8
- package/dist/memory/ingestion/PdfLoader.d.ts.map +1 -1
- package/dist/memory/ingestion/PdfLoader.js +13 -10
- package/dist/memory/ingestion/PdfLoader.js.map +1 -1
- package/dist/memory/io/MarkdownExporter.d.ts +1 -1
- package/dist/memory/io/MarkdownExporter.d.ts.map +1 -1
- package/dist/memory/io/MarkdownExporter.js +1 -1
- package/dist/memory/io/MarkdownExporter.js.map +1 -1
- package/dist/memory/observation/MemoryObserver.d.ts +63 -1
- package/dist/memory/observation/MemoryObserver.d.ts.map +1 -1
- package/dist/memory/observation/MemoryObserver.js +115 -4
- package/dist/memory/observation/MemoryObserver.js.map +1 -1
- package/dist/memory/observation/ObservationCompressor.d.ts +88 -0
- package/dist/memory/observation/ObservationCompressor.d.ts.map +1 -0
- package/dist/memory/observation/ObservationCompressor.js +207 -0
- package/dist/memory/observation/ObservationCompressor.js.map +1 -0
- package/dist/memory/observation/ObservationReflector.d.ts +82 -0
- package/dist/memory/observation/ObservationReflector.d.ts.map +1 -0
- package/dist/memory/observation/ObservationReflector.js +212 -0
- package/dist/memory/observation/ObservationReflector.js.map +1 -0
- package/dist/memory/observation/temporal.d.ts +54 -0
- package/dist/memory/observation/temporal.d.ts.map +1 -0
- package/dist/memory/observation/temporal.js +115 -0
- package/dist/memory/observation/temporal.js.map +1 -0
- package/dist/memory/tools/MemoryAddTool.d.ts +2 -2
- package/dist/memory/tools/MemoryAddTool.d.ts.map +1 -1
- package/dist/memory/tools/MemoryAddTool.js +8 -3
- package/dist/memory/tools/MemoryAddTool.js.map +1 -1
- package/dist/memory/tools/MemorySearchTool.d.ts +3 -3
- package/dist/memory/tools/MemorySearchTool.d.ts.map +1 -1
- package/dist/memory/tools/MemorySearchTool.js +11 -9
- package/dist/memory/tools/MemorySearchTool.js.map +1 -1
- package/dist/memory/tools/scopeContext.d.ts +11 -0
- package/dist/memory/tools/scopeContext.d.ts.map +1 -0
- package/dist/memory/tools/scopeContext.js +46 -0
- package/dist/memory/tools/scopeContext.js.map +1 -0
- package/dist/orchestration/builders/AgentGraph.d.ts +12 -11
- package/dist/orchestration/builders/AgentGraph.d.ts.map +1 -1
- package/dist/orchestration/builders/AgentGraph.js +12 -11
- package/dist/orchestration/builders/AgentGraph.js.map +1 -1
- package/dist/orchestration/builders/VoiceNodeBuilder.d.ts +82 -25
- package/dist/orchestration/builders/VoiceNodeBuilder.d.ts.map +1 -1
- package/dist/orchestration/builders/VoiceNodeBuilder.js +86 -26
- package/dist/orchestration/builders/VoiceNodeBuilder.js.map +1 -1
- package/dist/orchestration/builders/WorkflowBuilder.d.ts +1 -1
- package/dist/orchestration/builders/WorkflowBuilder.d.ts.map +1 -1
- package/dist/orchestration/builders/WorkflowBuilder.js +1 -1
- package/dist/orchestration/builders/WorkflowBuilder.js.map +1 -1
- package/dist/orchestration/checkpoint/InMemoryCheckpointStore.d.ts +7 -54
- package/dist/orchestration/checkpoint/InMemoryCheckpointStore.d.ts.map +1 -1
- package/dist/orchestration/checkpoint/InMemoryCheckpointStore.js +8 -56
- package/dist/orchestration/checkpoint/InMemoryCheckpointStore.js.map +1 -1
- package/dist/orchestration/events/GraphEvent.d.ts +67 -5
- package/dist/orchestration/events/GraphEvent.d.ts.map +1 -1
- package/dist/orchestration/events/GraphEvent.js.map +1 -1
- package/dist/orchestration/runtime/GraphRuntime.d.ts.map +1 -1
- package/dist/orchestration/runtime/GraphRuntime.js +151 -1
- package/dist/orchestration/runtime/GraphRuntime.js.map +1 -1
- package/dist/orchestration/runtime/LoopController.d.ts +3 -3
- package/dist/orchestration/runtime/LoopController.d.ts.map +1 -1
- package/dist/orchestration/runtime/LoopController.js.map +1 -1
- package/dist/orchestration/runtime/StateManager.d.ts +3 -3
- package/dist/orchestration/runtime/StateManager.js +3 -3
- package/dist/orchestration/runtime/VoiceNodeExecutor.d.ts +103 -26
- package/dist/orchestration/runtime/VoiceNodeExecutor.d.ts.map +1 -1
- package/dist/orchestration/runtime/VoiceNodeExecutor.js +155 -43
- package/dist/orchestration/runtime/VoiceNodeExecutor.js.map +1 -1
- package/dist/orchestration/runtime/VoiceTransportAdapter.d.ts +95 -33
- package/dist/orchestration/runtime/VoiceTransportAdapter.d.ts.map +1 -1
- package/dist/orchestration/runtime/VoiceTransportAdapter.js +83 -29
- package/dist/orchestration/runtime/VoiceTransportAdapter.js.map +1 -1
- package/dist/orchestration/runtime/VoiceTurnCollector.d.ts +73 -20
- package/dist/orchestration/runtime/VoiceTurnCollector.d.ts.map +1 -1
- package/dist/orchestration/runtime/VoiceTurnCollector.js +84 -23
- package/dist/orchestration/runtime/VoiceTurnCollector.js.map +1 -1
- package/dist/query-router/KeywordFallback.d.ts +70 -0
- package/dist/query-router/KeywordFallback.d.ts.map +1 -0
- package/dist/query-router/KeywordFallback.js +132 -0
- package/dist/query-router/KeywordFallback.js.map +1 -0
- package/dist/query-router/QueryClassifier.d.ts +140 -0
- package/dist/query-router/QueryClassifier.d.ts.map +1 -0
- package/dist/query-router/QueryClassifier.js +223 -0
- package/dist/query-router/QueryClassifier.js.map +1 -0
- package/dist/query-router/QueryDispatcher.d.ts +139 -0
- package/dist/query-router/QueryDispatcher.d.ts.map +1 -0
- package/dist/query-router/QueryDispatcher.js +297 -0
- package/dist/query-router/QueryDispatcher.js.map +1 -0
- package/dist/query-router/QueryGenerator.d.ts +184 -0
- package/dist/query-router/QueryGenerator.d.ts.map +1 -0
- package/dist/query-router/QueryGenerator.js +241 -0
- package/dist/query-router/QueryGenerator.js.map +1 -0
- package/dist/query-router/QueryRouter.d.ts +292 -0
- package/dist/query-router/QueryRouter.d.ts.map +1 -0
- package/dist/query-router/QueryRouter.js +803 -0
- package/dist/query-router/QueryRouter.js.map +1 -0
- package/dist/query-router/TopicExtractor.d.ts +73 -0
- package/dist/query-router/TopicExtractor.d.ts.map +1 -0
- package/dist/query-router/TopicExtractor.js +95 -0
- package/dist/query-router/TopicExtractor.js.map +1 -0
- package/dist/query-router/index.d.ts +40 -0
- package/dist/query-router/index.d.ts.map +1 -0
- package/dist/query-router/index.js +46 -0
- package/dist/query-router/index.js.map +1 -0
- package/dist/query-router/types.d.ts +508 -0
- package/dist/query-router/types.d.ts.map +1 -0
- package/dist/query-router/types.js +39 -0
- package/dist/query-router/types.js.map +1 -0
- package/dist/rag/index.d.ts +5 -0
- package/dist/rag/index.d.ts.map +1 -1
- package/dist/rag/index.js +7 -0
- package/dist/rag/index.js.map +1 -1
- package/dist/rag/multimodal/LLMVisionAdapter.d.ts +43 -0
- package/dist/rag/multimodal/LLMVisionAdapter.d.ts.map +1 -0
- package/dist/rag/multimodal/LLMVisionAdapter.js +46 -0
- package/dist/rag/multimodal/LLMVisionAdapter.js.map +1 -0
- package/dist/rag/multimodal/MultimodalIndexer.d.ts +244 -0
- package/dist/rag/multimodal/MultimodalIndexer.d.ts.map +1 -0
- package/dist/rag/multimodal/MultimodalIndexer.js +411 -0
- package/dist/rag/multimodal/MultimodalIndexer.js.map +1 -0
- package/dist/rag/multimodal/MultimodalMemoryBridge.d.ts +448 -0
- package/dist/rag/multimodal/MultimodalMemoryBridge.d.ts.map +1 -0
- package/dist/rag/multimodal/MultimodalMemoryBridge.js +941 -0
- package/dist/rag/multimodal/MultimodalMemoryBridge.js.map +1 -0
- package/dist/rag/multimodal/SpeechProviderAdapter.d.ts +139 -0
- package/dist/rag/multimodal/SpeechProviderAdapter.d.ts.map +1 -0
- package/dist/rag/multimodal/SpeechProviderAdapter.js +143 -0
- package/dist/rag/multimodal/SpeechProviderAdapter.js.map +1 -0
- package/dist/rag/multimodal/createMultimodalIndexerFromResolver.d.ts +172 -0
- package/dist/rag/multimodal/createMultimodalIndexerFromResolver.d.ts.map +1 -0
- package/dist/rag/multimodal/createMultimodalIndexerFromResolver.js +152 -0
- package/dist/rag/multimodal/createMultimodalIndexerFromResolver.js.map +1 -0
- package/dist/rag/multimodal/index.d.ts +44 -0
- package/dist/rag/multimodal/index.d.ts.map +1 -0
- package/dist/rag/multimodal/index.js +42 -0
- package/dist/rag/multimodal/index.js.map +1 -0
- package/dist/rag/multimodal/types.d.ts +276 -0
- package/dist/rag/multimodal/types.d.ts.map +1 -0
- package/dist/rag/multimodal/types.js +26 -0
- package/dist/rag/multimodal/types.js.map +1 -0
- package/dist/social-posting/SocialPostManager.d.ts +3 -3
- package/dist/social-posting/SocialPostManager.d.ts.map +1 -1
- package/dist/social-posting/SocialPostManager.js +3 -5
- package/dist/social-posting/SocialPostManager.js.map +1 -1
- package/dist/speech/FallbackProxy.d.ts +6 -6
- package/dist/speech/FallbackProxy.d.ts.map +1 -1
- package/dist/speech/FallbackProxy.js +3 -3
- package/dist/speech/FallbackProxy.js.map +1 -1
- package/dist/speech/SpeechProviderResolver.d.ts +8 -8
- package/dist/speech/SpeechProviderResolver.d.ts.map +1 -1
- package/dist/speech/SpeechProviderResolver.js +22 -11
- package/dist/speech/SpeechProviderResolver.js.map +1 -1
- package/dist/speech/SpeechRuntime.d.ts +1 -5
- package/dist/speech/SpeechRuntime.d.ts.map +1 -1
- package/dist/speech/SpeechRuntime.js +17 -9
- package/dist/speech/SpeechRuntime.js.map +1 -1
- package/dist/speech/providers/AssemblyAISTTProvider.d.ts +4 -4
- package/dist/speech/providers/AssemblyAISTTProvider.js +4 -4
- package/dist/speech/providers/AzureSpeechTTSProvider.d.ts +3 -3
- package/dist/speech/providers/AzureSpeechTTSProvider.js +2 -2
- package/dist/speech/providers/AzureSpeechTTSProvider.js.map +1 -1
- package/dist/speech/providers/BuiltInAdaptiveVadProvider.d.ts +9 -9
- package/dist/speech/providers/BuiltInAdaptiveVadProvider.d.ts.map +1 -1
- package/dist/speech/providers/BuiltInAdaptiveVadProvider.js +5 -5
- package/dist/speech/providers/BuiltInAdaptiveVadProvider.js.map +1 -1
- package/dist/speech/providers/DeepgramBatchSTTProvider.d.ts +2 -2
- package/dist/speech/providers/DeepgramBatchSTTProvider.js +2 -2
- package/dist/speech/providers/OpenAITextToSpeechProvider.d.ts +3 -3
- package/dist/speech/providers/OpenAITextToSpeechProvider.js +2 -2
- package/dist/speech/providers/OpenAIWhisperSpeechToTextProvider.d.ts +1 -1
- package/dist/speech/providers/OpenAIWhisperSpeechToTextProvider.d.ts.map +1 -1
- package/dist/speech/providers/OpenAIWhisperSpeechToTextProvider.js +1 -1
- package/dist/speech/providers/OpenAIWhisperSpeechToTextProvider.js.map +1 -1
- package/dist/voice/TelephonyStreamTransport.d.ts +6 -6
- package/dist/voice/TelephonyStreamTransport.d.ts.map +1 -1
- package/dist/voice/TelephonyStreamTransport.js +5 -5
- package/dist/voice/TelephonyStreamTransport.js.map +1 -1
- package/dist/voice-pipeline/AcousticEndpointDetector.d.ts +4 -4
- package/dist/voice-pipeline/AcousticEndpointDetector.d.ts.map +1 -1
- package/dist/voice-pipeline/AcousticEndpointDetector.js +4 -4
- package/dist/voice-pipeline/AcousticEndpointDetector.js.map +1 -1
- package/dist/voice-pipeline/HardCutBargeinHandler.d.ts +3 -3
- package/dist/voice-pipeline/HardCutBargeinHandler.js +3 -3
- package/dist/voice-pipeline/HeuristicEndpointDetector.d.ts +3 -3
- package/dist/voice-pipeline/HeuristicEndpointDetector.d.ts.map +1 -1
- package/dist/voice-pipeline/HeuristicEndpointDetector.js +3 -3
- package/dist/voice-pipeline/HeuristicEndpointDetector.js.map +1 -1
- package/dist/voice-pipeline/SoftFadeBargeinHandler.d.ts +5 -5
- package/dist/voice-pipeline/SoftFadeBargeinHandler.js +1 -1
- package/dist/voice-pipeline/VoiceInterruptError.d.ts +6 -6
- package/dist/voice-pipeline/VoiceInterruptError.d.ts.map +1 -1
- package/dist/voice-pipeline/VoiceInterruptError.js +4 -4
- package/dist/voice-pipeline/VoiceInterruptError.js.map +1 -1
- package/dist/voice-pipeline/VoicePipelineOrchestrator.d.ts +9 -9
- package/dist/voice-pipeline/VoicePipelineOrchestrator.d.ts.map +1 -1
- package/dist/voice-pipeline/VoicePipelineOrchestrator.js +8 -8
- package/dist/voice-pipeline/VoicePipelineOrchestrator.js.map +1 -1
- package/dist/voice-pipeline/WebRTCStreamTransport.d.ts +421 -0
- package/dist/voice-pipeline/WebRTCStreamTransport.d.ts.map +1 -0
- package/dist/voice-pipeline/WebRTCStreamTransport.js +573 -0
- package/dist/voice-pipeline/WebRTCStreamTransport.js.map +1 -0
- package/dist/voice-pipeline/WebSocketStreamTransport.d.ts +8 -8
- package/dist/voice-pipeline/WebSocketStreamTransport.js +5 -5
- package/dist/voice-pipeline/index.d.ts +1 -0
- package/dist/voice-pipeline/index.d.ts.map +1 -1
- package/dist/voice-pipeline/index.js +2 -0
- package/dist/voice-pipeline/index.js.map +1 -1
- package/dist/voice-pipeline/types.d.ts +43 -43
- package/dist/voice-pipeline/types.d.ts.map +1 -1
- package/package.json +19 -1
|
@@ -0,0 +1,959 @@
|
|
|
1
|
+
// File: backend/agentos/core/llm/providers/implementations/AnthropicProvider.ts
|
|
2
|
+
import { AnthropicProviderError } from '../errors/AnthropicProviderError.js';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Known model catalog — used by listAvailableModels / getModelInfo
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
/** Static catalog of well-known Anthropic models and their metadata. */
|
|
7
|
+
const ANTHROPIC_MODELS = [
|
|
8
|
+
{
|
|
9
|
+
modelId: 'claude-opus-4-20250514',
|
|
10
|
+
providerId: 'anthropic',
|
|
11
|
+
displayName: 'Claude Opus 4',
|
|
12
|
+
description: 'Most capable model for complex reasoning and analysis.',
|
|
13
|
+
capabilities: ['chat', 'tool_use', 'vision_input'],
|
|
14
|
+
contextWindowSize: 200000,
|
|
15
|
+
outputTokenLimit: 32000,
|
|
16
|
+
pricePer1MTokensInput: 15,
|
|
17
|
+
pricePer1MTokensOutput: 75,
|
|
18
|
+
supportsStreaming: true,
|
|
19
|
+
status: 'active',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
modelId: 'claude-sonnet-4-20250514',
|
|
23
|
+
providerId: 'anthropic',
|
|
24
|
+
displayName: 'Claude Sonnet 4',
|
|
25
|
+
description: 'Best balance of speed and intelligence for everyday tasks.',
|
|
26
|
+
capabilities: ['chat', 'tool_use', 'vision_input'],
|
|
27
|
+
contextWindowSize: 200000,
|
|
28
|
+
outputTokenLimit: 16000,
|
|
29
|
+
pricePer1MTokensInput: 3,
|
|
30
|
+
pricePer1MTokensOutput: 15,
|
|
31
|
+
supportsStreaming: true,
|
|
32
|
+
status: 'active',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
modelId: 'claude-haiku-4-5-20251001',
|
|
36
|
+
providerId: 'anthropic',
|
|
37
|
+
displayName: 'Claude Haiku 4.5',
|
|
38
|
+
description: 'Fastest and most cost-effective model for lightweight tasks.',
|
|
39
|
+
capabilities: ['chat', 'tool_use', 'vision_input'],
|
|
40
|
+
contextWindowSize: 200000,
|
|
41
|
+
outputTokenLimit: 8192,
|
|
42
|
+
pricePer1MTokensInput: 0.80,
|
|
43
|
+
pricePer1MTokensOutput: 4,
|
|
44
|
+
supportsStreaming: true,
|
|
45
|
+
status: 'active',
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Provider implementation
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
/**
|
|
52
|
+
* @class AnthropicProvider
|
|
53
|
+
* @implements {IProvider}
|
|
54
|
+
*
|
|
55
|
+
* Provides native integration with Anthropic's Messages API.
|
|
56
|
+
* Handles the significant structural differences between Anthropic's API
|
|
57
|
+
* and the OpenAI-style conventions used by IProvider, including system
|
|
58
|
+
* prompt extraction, tool schema remapping, and stop reason normalization.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* const provider = new AnthropicProvider();
|
|
62
|
+
* await provider.initialize({ apiKey: 'sk-ant-...' });
|
|
63
|
+
* const response = await provider.generateCompletion(
|
|
64
|
+
* 'claude-sonnet-4-20250514',
|
|
65
|
+
* [{ role: 'user', content: 'Hello!' }],
|
|
66
|
+
* { maxTokens: 1024 },
|
|
67
|
+
* );
|
|
68
|
+
*/
|
|
69
|
+
export class AnthropicProvider {
|
|
70
|
+
constructor() {
|
|
71
|
+
/** @inheritdoc */
|
|
72
|
+
this.providerId = 'anthropic';
|
|
73
|
+
/** @inheritdoc */
|
|
74
|
+
this.isInitialized = false;
|
|
75
|
+
}
|
|
76
|
+
// -------------------------------------------------------------------------
|
|
77
|
+
// Lifecycle
|
|
78
|
+
// -------------------------------------------------------------------------
|
|
79
|
+
/**
|
|
80
|
+
* Initialize the Anthropic provider with the given configuration.
|
|
81
|
+
*
|
|
82
|
+
* Validates that an API key is present — Anthropic's API will reject
|
|
83
|
+
* unauthenticated requests. Does NOT make a network call on startup
|
|
84
|
+
* because Anthropic has no lightweight health endpoint like OpenAI's
|
|
85
|
+
* `/models` list.
|
|
86
|
+
*
|
|
87
|
+
* @param {AnthropicProviderConfig} config - Provider configuration.
|
|
88
|
+
* @returns {Promise<void>}
|
|
89
|
+
* @throws {AnthropicProviderError} If the API key is missing.
|
|
90
|
+
*/
|
|
91
|
+
async initialize(config) {
|
|
92
|
+
if (!config.apiKey) {
|
|
93
|
+
throw new AnthropicProviderError('API key is required for AnthropicProvider initialization. Set ANTHROPIC_API_KEY.', 'INIT_FAILED_MISSING_API_KEY');
|
|
94
|
+
}
|
|
95
|
+
this.config = {
|
|
96
|
+
baseURL: 'https://api.anthropic.com',
|
|
97
|
+
maxRetries: 3,
|
|
98
|
+
requestTimeout: 120000,
|
|
99
|
+
defaultMaxTokens: 4096,
|
|
100
|
+
...config,
|
|
101
|
+
};
|
|
102
|
+
this.defaultModelId = config.defaultModelId;
|
|
103
|
+
this.isInitialized = true;
|
|
104
|
+
console.log(`AnthropicProvider initialized. Default model: ${this.defaultModelId || 'Not set'}.`);
|
|
105
|
+
}
|
|
106
|
+
// -------------------------------------------------------------------------
|
|
107
|
+
// Chat completions
|
|
108
|
+
// -------------------------------------------------------------------------
|
|
109
|
+
/**
|
|
110
|
+
* Generates a non-streaming chat completion via Anthropic's Messages API.
|
|
111
|
+
*
|
|
112
|
+
* Extracts system messages from the conversation and promotes them to the
|
|
113
|
+
* top-level `system` field, converts tool definitions from OpenAI format
|
|
114
|
+
* to Anthropic's `input_schema` format, and normalizes the response back
|
|
115
|
+
* to IProvider conventions.
|
|
116
|
+
*
|
|
117
|
+
* @param {string} modelId - The Anthropic model to use (e.g., "claude-sonnet-4-20250514").
|
|
118
|
+
* @param {ChatMessage[]} messages - Conversation messages. System-role messages are
|
|
119
|
+
* extracted and sent as the top-level `system` parameter.
|
|
120
|
+
* @param {ModelCompletionOptions} options - Completion options. `maxTokens` is strongly
|
|
121
|
+
* recommended; defaults to {@link AnthropicProviderConfig.defaultMaxTokens} if omitted.
|
|
122
|
+
* @returns {Promise<ModelCompletionResponse>} A normalized completion response.
|
|
123
|
+
* @throws {AnthropicProviderError} On authentication, validation, or network errors.
|
|
124
|
+
*/
|
|
125
|
+
async generateCompletion(modelId, messages, options) {
|
|
126
|
+
this.ensureInitialized();
|
|
127
|
+
const payload = this.buildRequestPayload(modelId, messages, options, false);
|
|
128
|
+
const apiResponse = await this.makeApiRequest('/v1/messages', 'POST', payload);
|
|
129
|
+
return this.mapResponseToCompletion(apiResponse);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Generates a streaming chat completion via Anthropic's Messages API.
|
|
133
|
+
*
|
|
134
|
+
* Anthropic's streaming uses distinct SSE event types:
|
|
135
|
+
* - `message_start` — initial metadata and usage
|
|
136
|
+
* - `content_block_start` — beginning of a text or tool_use block
|
|
137
|
+
* - `content_block_delta` — incremental text or tool argument JSON
|
|
138
|
+
* - `content_block_stop` — end of a block
|
|
139
|
+
* - `message_delta` — final stop_reason and output token count
|
|
140
|
+
* - `message_stop` — terminal event
|
|
141
|
+
*
|
|
142
|
+
* This method normalizes all of the above into the IProvider streaming
|
|
143
|
+
* contract with `responseTextDelta`, `toolCallsDeltas`, and `isFinal`.
|
|
144
|
+
*
|
|
145
|
+
* @param {string} modelId - The Anthropic model to use.
|
|
146
|
+
* @param {ChatMessage[]} messages - Conversation messages.
|
|
147
|
+
* @param {ModelCompletionOptions} options - Completion options.
|
|
148
|
+
* @returns {AsyncGenerator<ModelCompletionResponse>} Incremental response chunks.
|
|
149
|
+
* @throws {AnthropicProviderError} On connection or stream errors.
|
|
150
|
+
*/
|
|
151
|
+
async *generateCompletionStream(modelId, messages, options) {
|
|
152
|
+
this.ensureInitialized();
|
|
153
|
+
const payload = this.buildRequestPayload(modelId, messages, options, true);
|
|
154
|
+
// Handle pre-aborted signals
|
|
155
|
+
const abortSignal = options.abortSignal;
|
|
156
|
+
if (abortSignal?.aborted) {
|
|
157
|
+
yield this.buildAbortChunk(modelId);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const stream = await this.makeStreamRequest('/v1/messages', payload);
|
|
161
|
+
// State accumulators across SSE events
|
|
162
|
+
let responseId = `anthropic-${modelId}-${Date.now()}`;
|
|
163
|
+
let accumulatedContent = '';
|
|
164
|
+
let inputTokens = 0;
|
|
165
|
+
let outputTokens = 0;
|
|
166
|
+
/** Map from content block index → tool call accumulator */
|
|
167
|
+
const toolCallAccum = new Map();
|
|
168
|
+
const abortHandler = () => { };
|
|
169
|
+
abortSignal?.addEventListener('abort', abortHandler, { once: true });
|
|
170
|
+
try {
|
|
171
|
+
for await (const rawEvent of this.parseSseStream(stream)) {
|
|
172
|
+
if (abortSignal?.aborted) {
|
|
173
|
+
yield this.buildAbortChunk(modelId);
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
let event;
|
|
177
|
+
try {
|
|
178
|
+
event = JSON.parse(rawEvent);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// Malformed JSON — skip this event
|
|
182
|
+
console.warn('AnthropicProvider: Could not parse SSE event JSON:', rawEvent);
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
switch (event.type) {
|
|
186
|
+
case 'message_start': {
|
|
187
|
+
responseId = event.message.id;
|
|
188
|
+
inputTokens = event.message.usage?.input_tokens ?? 0;
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
case 'content_block_start': {
|
|
192
|
+
// A new tool_use block registers a placeholder in the accumulator
|
|
193
|
+
if (event.content_block.type === 'tool_use') {
|
|
194
|
+
toolCallAccum.set(event.index, {
|
|
195
|
+
id: event.content_block.id ?? `call_${Date.now()}_${event.index}`,
|
|
196
|
+
name: event.content_block.name ?? 'unknown',
|
|
197
|
+
argsJson: '',
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
case 'content_block_delta': {
|
|
203
|
+
if (event.delta.type === 'text_delta' && event.delta.text) {
|
|
204
|
+
// Incremental text content
|
|
205
|
+
const textDelta = event.delta.text;
|
|
206
|
+
accumulatedContent += textDelta;
|
|
207
|
+
yield {
|
|
208
|
+
id: responseId,
|
|
209
|
+
object: 'chat.completion.chunk',
|
|
210
|
+
created: Math.floor(Date.now() / 1000),
|
|
211
|
+
modelId,
|
|
212
|
+
choices: [{
|
|
213
|
+
index: 0,
|
|
214
|
+
message: { role: 'assistant', content: textDelta },
|
|
215
|
+
finishReason: null,
|
|
216
|
+
}],
|
|
217
|
+
responseTextDelta: textDelta,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
else if (event.delta.type === 'input_json_delta' && event.delta.partial_json) {
|
|
221
|
+
// Incremental tool argument JSON fragment
|
|
222
|
+
const accum = toolCallAccum.get(event.index);
|
|
223
|
+
if (accum) {
|
|
224
|
+
accum.argsJson += event.delta.partial_json;
|
|
225
|
+
yield {
|
|
226
|
+
id: responseId,
|
|
227
|
+
object: 'chat.completion.chunk',
|
|
228
|
+
created: Math.floor(Date.now() / 1000),
|
|
229
|
+
modelId,
|
|
230
|
+
choices: [{
|
|
231
|
+
index: 0,
|
|
232
|
+
message: { role: 'assistant', content: null },
|
|
233
|
+
finishReason: null,
|
|
234
|
+
}],
|
|
235
|
+
toolCallsDeltas: [{
|
|
236
|
+
index: event.index,
|
|
237
|
+
id: accum.id,
|
|
238
|
+
type: 'function',
|
|
239
|
+
function: {
|
|
240
|
+
name: accum.name,
|
|
241
|
+
arguments_delta: event.delta.partial_json,
|
|
242
|
+
},
|
|
243
|
+
}],
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
case 'message_delta': {
|
|
250
|
+
// Contains stop_reason and final output token count
|
|
251
|
+
outputTokens += event.usage?.output_tokens ?? 0;
|
|
252
|
+
const stopReason = this.mapStopReason(event.delta.stop_reason);
|
|
253
|
+
// Assemble final tool_calls array from accumulated blocks
|
|
254
|
+
const toolCalls = this.assembleToolCalls(toolCallAccum);
|
|
255
|
+
const hasToolCalls = toolCalls.length > 0;
|
|
256
|
+
const usage = {
|
|
257
|
+
promptTokens: inputTokens,
|
|
258
|
+
completionTokens: outputTokens,
|
|
259
|
+
totalTokens: inputTokens + outputTokens,
|
|
260
|
+
costUSD: this.estimateCost(inputTokens, outputTokens, modelId),
|
|
261
|
+
};
|
|
262
|
+
yield {
|
|
263
|
+
id: responseId,
|
|
264
|
+
object: 'chat.completion.chunk',
|
|
265
|
+
created: Math.floor(Date.now() / 1000),
|
|
266
|
+
modelId,
|
|
267
|
+
choices: [{
|
|
268
|
+
index: 0,
|
|
269
|
+
message: {
|
|
270
|
+
role: 'assistant',
|
|
271
|
+
content: accumulatedContent || null,
|
|
272
|
+
...(hasToolCalls && { tool_calls: toolCalls }),
|
|
273
|
+
},
|
|
274
|
+
finishReason: stopReason,
|
|
275
|
+
}],
|
|
276
|
+
usage,
|
|
277
|
+
isFinal: true,
|
|
278
|
+
};
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
case 'error': {
|
|
282
|
+
// Stream-level error from Anthropic
|
|
283
|
+
yield {
|
|
284
|
+
id: responseId,
|
|
285
|
+
object: 'chat.completion.chunk',
|
|
286
|
+
created: Math.floor(Date.now() / 1000),
|
|
287
|
+
modelId,
|
|
288
|
+
choices: [],
|
|
289
|
+
error: {
|
|
290
|
+
message: event.error.message,
|
|
291
|
+
type: event.error.type,
|
|
292
|
+
},
|
|
293
|
+
isFinal: true,
|
|
294
|
+
};
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
// 'content_block_stop', 'message_stop', 'ping' — no action needed
|
|
298
|
+
default:
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
catch (streamError) {
|
|
304
|
+
const message = streamError instanceof Error ? streamError.message : 'Anthropic stream processing error';
|
|
305
|
+
console.error(`AnthropicProvider stream error for model ${modelId}:`, message);
|
|
306
|
+
yield {
|
|
307
|
+
id: responseId,
|
|
308
|
+
object: 'chat.completion.chunk',
|
|
309
|
+
created: Math.floor(Date.now() / 1000),
|
|
310
|
+
modelId,
|
|
311
|
+
choices: [],
|
|
312
|
+
isFinal: true,
|
|
313
|
+
error: { message, type: 'STREAM_PROCESSING_ERROR' },
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
finally {
|
|
317
|
+
abortSignal?.removeEventListener('abort', abortHandler);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// -------------------------------------------------------------------------
|
|
321
|
+
// Embeddings (not natively supported by Anthropic)
|
|
322
|
+
// -------------------------------------------------------------------------
|
|
323
|
+
/**
|
|
324
|
+
* Anthropic does not offer an embeddings API. This method always throws.
|
|
325
|
+
*
|
|
326
|
+
* @param {string} _modelId - Unused.
|
|
327
|
+
* @param {string[]} _texts - Unused.
|
|
328
|
+
* @param {ProviderEmbeddingOptions} [_options] - Unused.
|
|
329
|
+
* @returns {Promise<ProviderEmbeddingResponse>} Never returns.
|
|
330
|
+
* @throws {AnthropicProviderError} Always — embeddings are not supported.
|
|
331
|
+
*/
|
|
332
|
+
async generateEmbeddings(_modelId, _texts, _options) {
|
|
333
|
+
throw new AnthropicProviderError('Anthropic does not provide an embeddings API. Use a dedicated embedding provider (e.g., OpenAI, Voyage).', 'EMBEDDINGS_NOT_SUPPORTED');
|
|
334
|
+
}
|
|
335
|
+
// -------------------------------------------------------------------------
|
|
336
|
+
// Introspection
|
|
337
|
+
// -------------------------------------------------------------------------
|
|
338
|
+
/**
|
|
339
|
+
* Returns a static catalog of known Anthropic models.
|
|
340
|
+
*
|
|
341
|
+
* Anthropic does not expose a `/models` list endpoint, so this uses a
|
|
342
|
+
* hardcoded catalog that is kept up-to-date with major releases.
|
|
343
|
+
*
|
|
344
|
+
* @param {{ capability?: string }} [filter] - Optional capability filter.
|
|
345
|
+
* @returns {Promise<ModelInfo[]>} Array of known Anthropic models.
|
|
346
|
+
*/
|
|
347
|
+
async listAvailableModels(filter) {
|
|
348
|
+
this.ensureInitialized();
|
|
349
|
+
if (filter?.capability) {
|
|
350
|
+
return ANTHROPIC_MODELS.filter(m => m.capabilities.includes(filter.capability));
|
|
351
|
+
}
|
|
352
|
+
return [...ANTHROPIC_MODELS];
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Retrieves metadata for a specific model from the static catalog.
|
|
356
|
+
*
|
|
357
|
+
* @param {string} modelId - Model identifier (e.g., "claude-sonnet-4-20250514").
|
|
358
|
+
* @returns {Promise<ModelInfo | undefined>} Model info or undefined if not found.
|
|
359
|
+
*/
|
|
360
|
+
async getModelInfo(modelId) {
|
|
361
|
+
this.ensureInitialized();
|
|
362
|
+
return ANTHROPIC_MODELS.find(m => m.modelId === modelId);
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Performs a lightweight health check by sending a minimal Messages request.
|
|
366
|
+
*
|
|
367
|
+
* @returns {Promise<{ isHealthy: boolean; details?: unknown }>} Health status.
|
|
368
|
+
*/
|
|
369
|
+
async checkHealth() {
|
|
370
|
+
try {
|
|
371
|
+
// Anthropic has no /health or /models endpoint, so we send a tiny
|
|
372
|
+
// completion request with max_tokens=1 to verify credentials + connectivity.
|
|
373
|
+
await this.makeApiRequest('/v1/messages', 'POST', {
|
|
374
|
+
model: this.defaultModelId || 'claude-haiku-4-5-20251001',
|
|
375
|
+
max_tokens: 1,
|
|
376
|
+
messages: [{ role: 'user', content: 'ping' }],
|
|
377
|
+
});
|
|
378
|
+
return { isHealthy: true };
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
const message = error instanceof Error ? error.message : 'Health check failed';
|
|
382
|
+
return { isHealthy: false, details: { message, error } };
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/** @inheritdoc */
|
|
386
|
+
async shutdown() {
|
|
387
|
+
this.isInitialized = false;
|
|
388
|
+
console.log('AnthropicProvider shutdown complete.');
|
|
389
|
+
}
|
|
390
|
+
// =========================================================================
|
|
391
|
+
// Private helpers
|
|
392
|
+
// =========================================================================
|
|
393
|
+
/**
|
|
394
|
+
* Guard that throws if the provider has not been initialized.
|
|
395
|
+
* @private
|
|
396
|
+
* @throws {AnthropicProviderError} If not initialized.
|
|
397
|
+
*/
|
|
398
|
+
ensureInitialized() {
|
|
399
|
+
if (!this.isInitialized) {
|
|
400
|
+
throw new AnthropicProviderError('AnthropicProvider is not initialized. Call initialize() first.', 'PROVIDER_NOT_INITIALIZED');
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// -------------------------------------------------------------------------
|
|
404
|
+
// Payload construction
|
|
405
|
+
// -------------------------------------------------------------------------
|
|
406
|
+
/**
|
|
407
|
+
* Builds the Anthropic Messages API request payload from IProvider inputs.
|
|
408
|
+
*
|
|
409
|
+
* The key transformation is extracting system-role messages from the
|
|
410
|
+
* conversation array and placing their content into the top-level `system`
|
|
411
|
+
* field, since Anthropic does not accept system as a message role.
|
|
412
|
+
*
|
|
413
|
+
* @param {string} modelId - Target model.
|
|
414
|
+
* @param {ChatMessage[]} messages - Conversation messages.
|
|
415
|
+
* @param {ModelCompletionOptions} options - Completion options.
|
|
416
|
+
* @param {boolean} stream - Whether to request streaming.
|
|
417
|
+
* @returns {Record<string, unknown>} The request body for Anthropic's API.
|
|
418
|
+
* @private
|
|
419
|
+
*/
|
|
420
|
+
buildRequestPayload(modelId, messages, options, stream) {
|
|
421
|
+
// --- Extract system messages and join them into a single string ---
|
|
422
|
+
// Anthropic treats system as a top-level field, not a conversation role.
|
|
423
|
+
const systemParts = [];
|
|
424
|
+
const conversationMessages = [];
|
|
425
|
+
for (const msg of messages) {
|
|
426
|
+
if (msg.role === 'system') {
|
|
427
|
+
const text = typeof msg.content === 'string'
|
|
428
|
+
? msg.content
|
|
429
|
+
: Array.isArray(msg.content)
|
|
430
|
+
? msg.content.filter(p => p.type === 'text').map(p => p.text).join('\n')
|
|
431
|
+
: '';
|
|
432
|
+
if (text)
|
|
433
|
+
systemParts.push(text);
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
conversationMessages.push(msg);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
// --- Convert remaining messages to Anthropic format ---
|
|
440
|
+
const anthropicMessages = conversationMessages.map(msg => this.toAnthropicMessage(msg));
|
|
441
|
+
const payload = {
|
|
442
|
+
model: modelId,
|
|
443
|
+
// max_tokens is REQUIRED by Anthropic — enforce a sane default
|
|
444
|
+
max_tokens: options.maxTokens ?? this.config.defaultMaxTokens ?? 4096,
|
|
445
|
+
messages: anthropicMessages,
|
|
446
|
+
stream,
|
|
447
|
+
};
|
|
448
|
+
// Only include system if we actually have system content
|
|
449
|
+
if (systemParts.length > 0) {
|
|
450
|
+
payload.system = systemParts.join('\n\n');
|
|
451
|
+
}
|
|
452
|
+
// --- Optional parameters ---
|
|
453
|
+
if (options.temperature !== undefined)
|
|
454
|
+
payload.temperature = options.temperature;
|
|
455
|
+
if (options.topP !== undefined)
|
|
456
|
+
payload.top_p = options.topP;
|
|
457
|
+
if (options.stopSequences?.length)
|
|
458
|
+
payload.stop_sequences = options.stopSequences;
|
|
459
|
+
// --- Tool definitions ---
|
|
460
|
+
const tools = this.convertToolDefs(options.tools);
|
|
461
|
+
if (tools.length > 0) {
|
|
462
|
+
payload.tools = tools;
|
|
463
|
+
// Map toolChoice to Anthropic's format
|
|
464
|
+
if (options.toolChoice) {
|
|
465
|
+
payload.tool_choice = this.convertToolChoice(options.toolChoice);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
// Pass through any custom model params
|
|
469
|
+
if (options.customModelParams) {
|
|
470
|
+
Object.assign(payload, options.customModelParams);
|
|
471
|
+
}
|
|
472
|
+
return payload;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Converts a single ChatMessage to Anthropic's message format.
|
|
476
|
+
*
|
|
477
|
+
* Handles three cases:
|
|
478
|
+
* 1. Assistant messages with tool_calls → content blocks with tool_use entries
|
|
479
|
+
* 2. Tool-role messages → content blocks with tool_result entries
|
|
480
|
+
* 3. Standard user/assistant text or multimodal messages
|
|
481
|
+
*
|
|
482
|
+
* @param {ChatMessage} msg - The source message.
|
|
483
|
+
* @returns {Record<string, unknown>} Anthropic-formatted message.
|
|
484
|
+
* @private
|
|
485
|
+
*/
|
|
486
|
+
toAnthropicMessage(msg) {
|
|
487
|
+
// --- Assistant with tool_calls ---
|
|
488
|
+
if (msg.role === 'assistant' && msg.tool_calls?.length) {
|
|
489
|
+
const content = [];
|
|
490
|
+
// Include any text content first
|
|
491
|
+
if (typeof msg.content === 'string' && msg.content) {
|
|
492
|
+
content.push({ type: 'text', text: msg.content });
|
|
493
|
+
}
|
|
494
|
+
// Add tool_use blocks
|
|
495
|
+
for (const tc of msg.tool_calls) {
|
|
496
|
+
let parsedInput;
|
|
497
|
+
try {
|
|
498
|
+
parsedInput = typeof tc.function.arguments === 'string'
|
|
499
|
+
? JSON.parse(tc.function.arguments)
|
|
500
|
+
: tc.function.arguments ?? {};
|
|
501
|
+
}
|
|
502
|
+
catch {
|
|
503
|
+
parsedInput = {};
|
|
504
|
+
}
|
|
505
|
+
content.push({
|
|
506
|
+
type: 'tool_use',
|
|
507
|
+
id: tc.id,
|
|
508
|
+
name: tc.function.name,
|
|
509
|
+
input: parsedInput,
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
return { role: 'assistant', content };
|
|
513
|
+
}
|
|
514
|
+
// --- Tool result messages ---
|
|
515
|
+
if (msg.role === 'tool') {
|
|
516
|
+
const resultContent = typeof msg.content === 'string'
|
|
517
|
+
? msg.content
|
|
518
|
+
: JSON.stringify(msg.content ?? '');
|
|
519
|
+
return {
|
|
520
|
+
role: 'user',
|
|
521
|
+
content: [{
|
|
522
|
+
type: 'tool_result',
|
|
523
|
+
tool_use_id: msg.tool_call_id ?? 'unknown',
|
|
524
|
+
content: resultContent,
|
|
525
|
+
}],
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
// --- Multimodal content (vision) ---
|
|
529
|
+
if (Array.isArray(msg.content)) {
|
|
530
|
+
const anthropicContent = [];
|
|
531
|
+
for (const part of msg.content) {
|
|
532
|
+
if (part.type === 'text') {
|
|
533
|
+
anthropicContent.push({ type: 'text', text: part.text });
|
|
534
|
+
}
|
|
535
|
+
else if (part.type === 'image_url') {
|
|
536
|
+
const url = part.image_url.url;
|
|
537
|
+
// Extract base64 data from data: URLs
|
|
538
|
+
const dataMatch = url.match(/^data:(image\/\w+);base64,(.+)$/);
|
|
539
|
+
if (dataMatch) {
|
|
540
|
+
anthropicContent.push({
|
|
541
|
+
type: 'image',
|
|
542
|
+
source: {
|
|
543
|
+
type: 'base64',
|
|
544
|
+
media_type: dataMatch[1],
|
|
545
|
+
data: dataMatch[2],
|
|
546
|
+
},
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
// For external URLs, Anthropic supports URL source type
|
|
551
|
+
anthropicContent.push({
|
|
552
|
+
type: 'image',
|
|
553
|
+
source: { type: 'url', url },
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return { role: msg.role, content: anthropicContent };
|
|
559
|
+
}
|
|
560
|
+
// --- Simple text ---
|
|
561
|
+
return {
|
|
562
|
+
role: msg.role,
|
|
563
|
+
content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content ?? ''),
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Converts OpenAI-style tool definitions to Anthropic's format.
|
|
568
|
+
*
|
|
569
|
+
* OpenAI uses `{ type: 'function', function: { name, description, parameters } }`
|
|
570
|
+
* while Anthropic uses `{ name, description, input_schema }`.
|
|
571
|
+
*
|
|
572
|
+
* @param {Array<Record<string, unknown>>} [tools] - OpenAI-formatted tool defs.
|
|
573
|
+
* @returns {AnthropicToolDef[]} Anthropic-formatted tool definitions.
|
|
574
|
+
* @private
|
|
575
|
+
*/
|
|
576
|
+
convertToolDefs(tools) {
|
|
577
|
+
if (!tools || tools.length === 0)
|
|
578
|
+
return [];
|
|
579
|
+
return tools.map(tool => {
|
|
580
|
+
// OpenAI format: { type: 'function', function: { name, description, parameters } }
|
|
581
|
+
const fn = tool?.function;
|
|
582
|
+
if (fn?.name) {
|
|
583
|
+
return {
|
|
584
|
+
name: fn.name,
|
|
585
|
+
description: (fn.description ?? ''),
|
|
586
|
+
// Anthropic calls it input_schema, OpenAI calls it parameters
|
|
587
|
+
input_schema: fn.parameters ?? { type: 'object' },
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
// AgentOS ITool format: { name, description, inputSchema }
|
|
591
|
+
return {
|
|
592
|
+
name: tool.name ?? 'unknown',
|
|
593
|
+
description: tool.description ?? '',
|
|
594
|
+
input_schema: tool.inputSchema ?? tool.parameters ?? { type: 'object' },
|
|
595
|
+
};
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Converts an OpenAI-style toolChoice value to Anthropic's tool_choice format.
|
|
600
|
+
*
|
|
601
|
+
* @param {string | Record<string, unknown>} choice - OpenAI tool choice.
|
|
602
|
+
* @returns {Record<string, unknown>} Anthropic tool_choice value.
|
|
603
|
+
* @private
|
|
604
|
+
*/
|
|
605
|
+
convertToolChoice(choice) {
|
|
606
|
+
if (typeof choice === 'string') {
|
|
607
|
+
// "auto" → { type: "auto" }, "none" → { type: "auto" } (no direct "none" in Anthropic),
|
|
608
|
+
// "required" → { type: "any" }
|
|
609
|
+
if (choice === 'required')
|
|
610
|
+
return { type: 'any' };
|
|
611
|
+
return { type: 'auto' };
|
|
612
|
+
}
|
|
613
|
+
// Object form: { type: "function", function: { name: "..." } } → { type: "tool", name: "..." }
|
|
614
|
+
const fn = choice?.function;
|
|
615
|
+
if (fn?.name) {
|
|
616
|
+
return { type: 'tool', name: fn.name };
|
|
617
|
+
}
|
|
618
|
+
return { type: 'auto' };
|
|
619
|
+
}
|
|
620
|
+
// -------------------------------------------------------------------------
|
|
621
|
+
// Response mapping
|
|
622
|
+
// -------------------------------------------------------------------------
|
|
623
|
+
/**
|
|
624
|
+
* Maps a non-streaming Anthropic Messages response to IProvider format.
|
|
625
|
+
*
|
|
626
|
+
* Extracts text content, tool_use blocks, and usage metrics, then normalizes
|
|
627
|
+
* the stop reason from Anthropic's vocabulary to IProvider conventions.
|
|
628
|
+
*
|
|
629
|
+
* @param {AnthropicMessagesResponse} apiResponse - Raw Anthropic response.
|
|
630
|
+
* @returns {ModelCompletionResponse} Normalized completion response.
|
|
631
|
+
* @private
|
|
632
|
+
*/
|
|
633
|
+
mapResponseToCompletion(apiResponse) {
|
|
634
|
+
// Collect text content
|
|
635
|
+
const textParts = apiResponse.content
|
|
636
|
+
.filter(block => block.type === 'text' && block.text)
|
|
637
|
+
.map(block => block.text);
|
|
638
|
+
const fullText = textParts.join('');
|
|
639
|
+
// Collect tool_use blocks and convert to OpenAI-style tool_calls
|
|
640
|
+
const toolCalls = apiResponse.content
|
|
641
|
+
.filter(block => block.type === 'tool_use')
|
|
642
|
+
.map(block => ({
|
|
643
|
+
id: block.id,
|
|
644
|
+
type: 'function',
|
|
645
|
+
function: {
|
|
646
|
+
name: block.name,
|
|
647
|
+
arguments: JSON.stringify(block.input ?? {}),
|
|
648
|
+
},
|
|
649
|
+
}));
|
|
650
|
+
const hasToolCalls = toolCalls.length > 0;
|
|
651
|
+
const finishReason = this.mapStopReason(apiResponse.stop_reason);
|
|
652
|
+
const usage = {
|
|
653
|
+
promptTokens: apiResponse.usage.input_tokens,
|
|
654
|
+
completionTokens: apiResponse.usage.output_tokens,
|
|
655
|
+
totalTokens: apiResponse.usage.input_tokens + apiResponse.usage.output_tokens,
|
|
656
|
+
costUSD: this.estimateCost(apiResponse.usage.input_tokens, apiResponse.usage.output_tokens, apiResponse.model),
|
|
657
|
+
};
|
|
658
|
+
const choice = {
|
|
659
|
+
index: 0,
|
|
660
|
+
message: {
|
|
661
|
+
role: 'assistant',
|
|
662
|
+
content: fullText || null,
|
|
663
|
+
...(hasToolCalls && { tool_calls: toolCalls }),
|
|
664
|
+
},
|
|
665
|
+
finishReason,
|
|
666
|
+
};
|
|
667
|
+
return {
|
|
668
|
+
id: apiResponse.id,
|
|
669
|
+
object: 'chat.completion',
|
|
670
|
+
created: Math.floor(Date.now() / 1000),
|
|
671
|
+
modelId: apiResponse.model,
|
|
672
|
+
choices: [choice],
|
|
673
|
+
usage,
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Maps Anthropic stop reasons to IProvider-convention finish reasons.
|
|
678
|
+
*
|
|
679
|
+
* - `end_turn` → `"stop"` (natural completion)
|
|
680
|
+
* - `tool_use` → `"tool_calls"` (model wants to invoke tools)
|
|
681
|
+
* - `max_tokens` → `"length"` (hit token limit)
|
|
682
|
+
* - `stop_sequence` → `"stop"` (hit a caller-specified stop sequence)
|
|
683
|
+
*
|
|
684
|
+
* @param {string | null} stopReason - Anthropic's stop_reason value.
|
|
685
|
+
* @returns {string} Normalized finish reason.
|
|
686
|
+
* @private
|
|
687
|
+
*/
|
|
688
|
+
mapStopReason(stopReason) {
|
|
689
|
+
switch (stopReason) {
|
|
690
|
+
case 'end_turn': return 'stop';
|
|
691
|
+
case 'tool_use': return 'tool_calls';
|
|
692
|
+
case 'max_tokens': return 'length';
|
|
693
|
+
case 'stop_sequence': return 'stop';
|
|
694
|
+
default: return stopReason ?? 'stop';
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Assembles completed tool calls from the streaming accumulator.
|
|
699
|
+
*
|
|
700
|
+
* @param {Map<number, { id: string; name: string; argsJson: string }>} accum - Tool call accumulators.
|
|
701
|
+
* @returns {NonNullable<ChatMessage['tool_calls']>} Assembled tool calls array.
|
|
702
|
+
* @private
|
|
703
|
+
*/
|
|
704
|
+
assembleToolCalls(accum) {
|
|
705
|
+
if (accum.size === 0)
|
|
706
|
+
return [];
|
|
707
|
+
return Array.from(accum.values()).map(tc => ({
|
|
708
|
+
id: tc.id,
|
|
709
|
+
type: 'function',
|
|
710
|
+
function: {
|
|
711
|
+
name: tc.name,
|
|
712
|
+
arguments: tc.argsJson || '{}',
|
|
713
|
+
},
|
|
714
|
+
}));
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Estimates USD cost for a given model and token counts.
|
|
718
|
+
*
|
|
719
|
+
* Looks up pricing from the static model catalog. Returns undefined
|
|
720
|
+
* if the model is not found in the catalog.
|
|
721
|
+
*
|
|
722
|
+
* @param {number} inputTokens - Number of input tokens.
|
|
723
|
+
* @param {number} outputTokens - Number of output tokens.
|
|
724
|
+
* @param {string} modelId - Model identifier for pricing lookup.
|
|
725
|
+
* @returns {number | undefined} Estimated cost in USD.
|
|
726
|
+
* @private
|
|
727
|
+
*/
|
|
728
|
+
estimateCost(inputTokens, outputTokens, modelId) {
|
|
729
|
+
const info = ANTHROPIC_MODELS.find(m => m.modelId === modelId);
|
|
730
|
+
if (!info?.pricePer1MTokensInput || !info?.pricePer1MTokensOutput)
|
|
731
|
+
return undefined;
|
|
732
|
+
return ((inputTokens / 1000000) * info.pricePer1MTokensInput +
|
|
733
|
+
(outputTokens / 1000000) * info.pricePer1MTokensOutput);
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Builds an abort chunk for early stream termination.
|
|
737
|
+
*
|
|
738
|
+
* @param {string} modelId - The model ID for the response.
|
|
739
|
+
* @returns {ModelCompletionResponse} A terminal chunk with abort error.
|
|
740
|
+
* @private
|
|
741
|
+
*/
|
|
742
|
+
buildAbortChunk(modelId) {
|
|
743
|
+
return {
|
|
744
|
+
id: `anthropic-abort-${Date.now()}`,
|
|
745
|
+
object: 'chat.completion.chunk',
|
|
746
|
+
created: Math.floor(Date.now() / 1000),
|
|
747
|
+
modelId,
|
|
748
|
+
choices: [],
|
|
749
|
+
error: { message: 'Stream aborted by caller', type: 'abort' },
|
|
750
|
+
isFinal: true,
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
// -------------------------------------------------------------------------
|
|
754
|
+
// HTTP transport
|
|
755
|
+
// -------------------------------------------------------------------------
|
|
756
|
+
/**
|
|
757
|
+
* Makes a non-streaming API request to Anthropic's API with retry logic.
|
|
758
|
+
*
|
|
759
|
+
* Uses the `x-api-key` header (Anthropic's auth mechanism) and the required
|
|
760
|
+
* `anthropic-version` header for API versioning.
|
|
761
|
+
*
|
|
762
|
+
* @template T The expected response type.
|
|
763
|
+
* @param {string} endpoint - API endpoint path (e.g., "/v1/messages").
|
|
764
|
+
* @param {'POST'} method - HTTP method (Anthropic Messages API is POST-only).
|
|
765
|
+
* @param {Record<string, unknown>} body - Request body.
|
|
766
|
+
* @returns {Promise<T>} Parsed JSON response.
|
|
767
|
+
* @throws {AnthropicProviderError} On authentication, validation, rate-limit, or network errors.
|
|
768
|
+
* @private
|
|
769
|
+
*/
|
|
770
|
+
async makeApiRequest(endpoint, method, body) {
|
|
771
|
+
const url = `${this.config.baseURL}${endpoint}`;
|
|
772
|
+
const headers = this.buildHeaders();
|
|
773
|
+
let lastError = new AnthropicProviderError('Request failed after all retries.', 'MAX_RETRIES_REACHED');
|
|
774
|
+
for (let attempt = 0; attempt < this.config.maxRetries; attempt++) {
|
|
775
|
+
const controller = new AbortController();
|
|
776
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.requestTimeout);
|
|
777
|
+
try {
|
|
778
|
+
const response = await fetch(url, {
|
|
779
|
+
method,
|
|
780
|
+
headers: { ...headers, 'Content-Type': 'application/json' },
|
|
781
|
+
body: JSON.stringify(body),
|
|
782
|
+
signal: controller.signal,
|
|
783
|
+
});
|
|
784
|
+
clearTimeout(timeoutId);
|
|
785
|
+
if (!response.ok) {
|
|
786
|
+
const errorData = await response.json().catch(() => ({}));
|
|
787
|
+
const errorMessage = errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`;
|
|
788
|
+
const errorType = errorData.error?.type;
|
|
789
|
+
// Non-retryable client errors
|
|
790
|
+
if (response.status === 401 || response.status === 403 || response.status === 400 || response.status === 404) {
|
|
791
|
+
throw new AnthropicProviderError(errorMessage, 'API_CLIENT_ERROR', response.status, errorType, errorData);
|
|
792
|
+
}
|
|
793
|
+
// Rate limit — respect Retry-After header
|
|
794
|
+
if (response.status === 429) {
|
|
795
|
+
lastError = new AnthropicProviderError(errorMessage, 'RATE_LIMIT_EXCEEDED', 429, errorType, errorData);
|
|
796
|
+
const retryAfter = response.headers.get('retry-after');
|
|
797
|
+
const retryAfterMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : (2 ** attempt) * 1000;
|
|
798
|
+
await new Promise(resolve => setTimeout(resolve, retryAfterMs));
|
|
799
|
+
continue;
|
|
800
|
+
}
|
|
801
|
+
// Retryable server errors (5xx)
|
|
802
|
+
if (response.status >= 500) {
|
|
803
|
+
lastError = new AnthropicProviderError(errorMessage, 'API_SERVER_ERROR', response.status, errorType, errorData);
|
|
804
|
+
await new Promise(resolve => setTimeout(resolve, (2 ** attempt) * 1000));
|
|
805
|
+
continue;
|
|
806
|
+
}
|
|
807
|
+
throw new AnthropicProviderError(errorMessage, 'API_REQUEST_FAILED', response.status, errorType, errorData);
|
|
808
|
+
}
|
|
809
|
+
return (await response.json());
|
|
810
|
+
}
|
|
811
|
+
catch (error) {
|
|
812
|
+
clearTimeout(timeoutId);
|
|
813
|
+
if (error instanceof AnthropicProviderError) {
|
|
814
|
+
if (error.code === 'API_CLIENT_ERROR')
|
|
815
|
+
throw error;
|
|
816
|
+
lastError = error;
|
|
817
|
+
}
|
|
818
|
+
else if (error instanceof Error && error.name === 'AbortError') {
|
|
819
|
+
lastError = new AnthropicProviderError(`Request timed out after ${this.config.requestTimeout}ms.`, 'REQUEST_TIMEOUT');
|
|
820
|
+
}
|
|
821
|
+
else {
|
|
822
|
+
lastError = new AnthropicProviderError(error instanceof Error ? error.message : 'Network or unknown error', 'NETWORK_ERROR');
|
|
823
|
+
}
|
|
824
|
+
if (attempt === this.config.maxRetries - 1)
|
|
825
|
+
break;
|
|
826
|
+
const delay = Math.min(30000, (1000 * (2 ** attempt)) + Math.random() * 1000);
|
|
827
|
+
console.warn(`[AnthropicProvider] Retry ${attempt + 1}/${this.config.maxRetries - 1} in ${(delay / 1000).toFixed(1)}s`);
|
|
828
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
throw lastError;
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Makes a streaming API request and returns the raw ReadableStream.
|
|
835
|
+
*
|
|
836
|
+
* @param {string} endpoint - API endpoint.
|
|
837
|
+
* @param {Record<string, unknown>} body - Request body (must include `stream: true`).
|
|
838
|
+
* @returns {Promise<ReadableStream<Uint8Array>>} The response body stream.
|
|
839
|
+
* @throws {AnthropicProviderError} On connection errors.
|
|
840
|
+
* @private
|
|
841
|
+
*/
|
|
842
|
+
async makeStreamRequest(endpoint, body) {
|
|
843
|
+
const url = `${this.config.baseURL}${endpoint}`;
|
|
844
|
+
const headers = this.buildHeaders();
|
|
845
|
+
const controller = new AbortController();
|
|
846
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.requestTimeout);
|
|
847
|
+
try {
|
|
848
|
+
const response = await fetch(url, {
|
|
849
|
+
method: 'POST',
|
|
850
|
+
headers: { ...headers, 'Content-Type': 'application/json' },
|
|
851
|
+
body: JSON.stringify(body),
|
|
852
|
+
signal: controller.signal,
|
|
853
|
+
});
|
|
854
|
+
clearTimeout(timeoutId);
|
|
855
|
+
if (!response.ok) {
|
|
856
|
+
const errorData = await response.json().catch(() => ({}));
|
|
857
|
+
const errorMessage = errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`;
|
|
858
|
+
throw new AnthropicProviderError(errorMessage, 'STREAM_CONNECTION_FAILED', response.status, errorData.error?.type, errorData);
|
|
859
|
+
}
|
|
860
|
+
if (!response.body) {
|
|
861
|
+
throw new AnthropicProviderError('Expected a stream response but body was null.', 'STREAM_BODY_NULL');
|
|
862
|
+
}
|
|
863
|
+
return response.body;
|
|
864
|
+
}
|
|
865
|
+
catch (error) {
|
|
866
|
+
clearTimeout(timeoutId);
|
|
867
|
+
if (error instanceof AnthropicProviderError)
|
|
868
|
+
throw error;
|
|
869
|
+
throw new AnthropicProviderError(error instanceof Error ? error.message : 'Failed to connect to Anthropic stream.', 'STREAM_CONNECTION_FAILED');
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* Builds the common headers for all Anthropic API requests.
|
|
874
|
+
*
|
|
875
|
+
* Includes the `x-api-key` authentication header and the required
|
|
876
|
+
* `anthropic-version` header that pins the API behavior.
|
|
877
|
+
*
|
|
878
|
+
* @returns {Record<string, string>} Request headers.
|
|
879
|
+
* @private
|
|
880
|
+
*/
|
|
881
|
+
buildHeaders() {
|
|
882
|
+
return {
|
|
883
|
+
'x-api-key': this.config.apiKey,
|
|
884
|
+
'anthropic-version': '2023-06-01',
|
|
885
|
+
'User-Agent': 'AgentOS/1.0 (AnthropicProvider)',
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
// -------------------------------------------------------------------------
|
|
889
|
+
// SSE parsing
|
|
890
|
+
// -------------------------------------------------------------------------
|
|
891
|
+
/**
|
|
892
|
+
* Parses an SSE (Server-Sent Events) stream from Anthropic.
|
|
893
|
+
*
|
|
894
|
+
* Anthropic SSE events follow the format:
|
|
895
|
+
* ```
|
|
896
|
+
* event: <event_type>
|
|
897
|
+
* data: <json_payload>
|
|
898
|
+
* ```
|
|
899
|
+
*
|
|
900
|
+
* This parser extracts the `data:` line content for each event and yields
|
|
901
|
+
* the raw JSON strings for the caller to parse and dispatch.
|
|
902
|
+
*
|
|
903
|
+
* @param {ReadableStream<Uint8Array>} stream - The raw SSE byte stream.
|
|
904
|
+
* @returns {AsyncGenerator<string>} Yields JSON string payloads.
|
|
905
|
+
* @private
|
|
906
|
+
*/
|
|
907
|
+
async *parseSseStream(stream) {
|
|
908
|
+
const reader = stream.getReader();
|
|
909
|
+
const decoder = new TextDecoder();
|
|
910
|
+
let buffer = '';
|
|
911
|
+
try {
|
|
912
|
+
while (true) {
|
|
913
|
+
const { done, value } = await reader.read();
|
|
914
|
+
if (done)
|
|
915
|
+
break;
|
|
916
|
+
buffer += decoder.decode(value, { stream: true });
|
|
917
|
+
// SSE events are separated by double newlines
|
|
918
|
+
let eolIndex;
|
|
919
|
+
while ((eolIndex = buffer.indexOf('\n\n')) >= 0) {
|
|
920
|
+
const messageBlock = buffer.substring(0, eolIndex);
|
|
921
|
+
buffer = buffer.substring(eolIndex + 2);
|
|
922
|
+
// Extract data: lines from the event block
|
|
923
|
+
const lines = messageBlock.split('\n');
|
|
924
|
+
for (const line of lines) {
|
|
925
|
+
if (line.startsWith('data: ')) {
|
|
926
|
+
const dataContent = line.substring('data: '.length).trim();
|
|
927
|
+
if (dataContent)
|
|
928
|
+
yield dataContent;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
// Process any trailing content in the buffer
|
|
934
|
+
if (buffer.trim()) {
|
|
935
|
+
const lines = buffer.split('\n');
|
|
936
|
+
for (const line of lines) {
|
|
937
|
+
if (line.startsWith('data: ')) {
|
|
938
|
+
const dataContent = line.substring('data: '.length).trim();
|
|
939
|
+
if (dataContent)
|
|
940
|
+
yield dataContent;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
catch (error) {
|
|
946
|
+
const message = error instanceof Error ? error.message : 'SSE stream parsing error';
|
|
947
|
+
console.error('AnthropicProvider: Error reading SSE stream:', message);
|
|
948
|
+
throw new AnthropicProviderError(message, 'STREAM_PARSING_ERROR');
|
|
949
|
+
}
|
|
950
|
+
finally {
|
|
951
|
+
// Ensure the reader is released
|
|
952
|
+
try {
|
|
953
|
+
await reader.cancel();
|
|
954
|
+
}
|
|
955
|
+
catch { /* swallow cleanup errors */ }
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
//# sourceMappingURL=AnthropicProvider.js.map
|