feat(#125): add Claude (Anthropic) LLM provider

Implement Anthropic Claude provider for Claude Opus, Sonnet, and Haiku models.

Implementation details:
- Created ClaudeProvider class implementing LlmProviderInterface
- Added @anthropic-ai/sdk npm package integration
- Implemented chat completion with streaming support
- Claude-specific message format (system prompt separate from messages)
- Static model list (Claude API doesn't provide list models endpoint)
- Embeddings throw error as Claude doesn't support native embeddings
- Added OpenTelemetry tracing with @TraceLlmCall decorator
- 100% statement, function, and line coverage (79% branch coverage)

Tests:
- Created comprehensive test suite with 20 tests
- All tests follow TDD pattern (written before implementation)
- Tests cover initialization, health checks, chat, streaming, and error handling
- Mocked Anthropic SDK client for isolated unit testing

Quality checks:
- All tests pass (1131 total tests across project)
- ESLint passes with no errors
- TypeScript type checking passes
- Follows existing code patterns from OpenAI and Ollama providers

Co-Authored-By: Claude Opus 4.5 <[email protected]>
This commit is contained in:
2026-01-31 14:29:40 -06:00
co-authored by Claude Opus 4.5
parent 0fdcfa6ed3
commit 772776bfd9
5 changed files with 820 additions and 0 deletions
+32
View File
@@ -54,6 +54,9 @@ importers:
apps/api:
dependencies:
'@anthropic-ai/sdk':
specifier: ^0.72.1
version: 0.72.1([email protected])
'@mosaic/shared':
specifier: workspace:*
version: link:../../packages/shared
@@ -429,6 +432,15 @@ packages:
'@antfu/[email protected]':
resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==}
'@anthropic-ai/[email protected]':
resolution: {integrity: sha512-MiUnue7qN7DvLIoYHgkedN2z05mRf2CutBzjXXY2krzOhG2r/rIfISS2uVkNLikgToB5hYIzw+xp2jdOtRkqYQ==}
hasBin: true
peerDependencies:
zod: ^3.25.0 || ^4.0.0
peerDependenciesMeta:
zod:
optional: true
'@asamuzakjp/[email protected]':
resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==}
@@ -4393,6 +4405,10 @@ packages:
[email protected]:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
[email protected]:
resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==}
engines: {node: '>=16'}
[email protected]:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
@@ -5625,6 +5641,9 @@ packages:
resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
engines: {node: '>=18'}
[email protected]:
resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==}
[email protected]:
resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==}
engines: {node: '>=18.12'}
@@ -6166,6 +6185,12 @@ snapshots:
package-manager-detector: 1.6.0
tinyexec: 1.0.2
'@anthropic-ai/[email protected]([email protected])':
dependencies:
json-schema-to-ts: 3.1.1
optionalDependencies:
zod: 4.3.6
'@asamuzakjp/[email protected]':
dependencies:
'@csstools/css-calc': 2.1.4(@csstools/[email protected](@csstools/[email protected]))(@csstools/[email protected])
@@ -10539,6 +10564,11 @@ snapshots:
[email protected]: {}
[email protected]:
dependencies:
'@babel/runtime': 7.28.6
ts-algebra: 2.0.0
[email protected]: {}
[email protected]: {}
@@ -11844,6 +11874,8 @@ snapshots:
dependencies:
punycode: 2.3.1
[email protected]: {}
[email protected]([email protected]):
dependencies:
typescript: 5.9.3