@holokai/holo-provider-claude 0.1.0

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.
Files changed (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +588 -0
  3. package/dist/claude.auditor.d.ts +12 -0
  4. package/dist/claude.auditor.d.ts.map +1 -0
  5. package/dist/claude.auditor.js +113 -0
  6. package/dist/claude.auditor.js.map +1 -0
  7. package/dist/claude.provider.d.ts +19 -0
  8. package/dist/claude.provider.d.ts.map +1 -0
  9. package/dist/claude.provider.js +53 -0
  10. package/dist/claude.provider.js.map +1 -0
  11. package/dist/claude.response.factory.d.ts +21 -0
  12. package/dist/claude.response.factory.d.ts.map +1 -0
  13. package/dist/claude.response.factory.js +132 -0
  14. package/dist/claude.response.factory.js.map +1 -0
  15. package/dist/claude.translator.d.ts +21 -0
  16. package/dist/claude.translator.d.ts.map +1 -0
  17. package/dist/claude.translator.js +76 -0
  18. package/dist/claude.translator.js.map +1 -0
  19. package/dist/claude.wire.adapter.d.ts +5 -0
  20. package/dist/claude.wire.adapter.d.ts.map +1 -0
  21. package/dist/claude.wire.adapter.js +9 -0
  22. package/dist/claude.wire.adapter.js.map +1 -0
  23. package/dist/index.d.ts +11 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +12 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/manifest.d.ts +3 -0
  28. package/dist/manifest.d.ts.map +1 -0
  29. package/dist/manifest.js +146 -0
  30. package/dist/manifest.js.map +1 -0
  31. package/dist/plugin.d.ts +20 -0
  32. package/dist/plugin.d.ts.map +1 -0
  33. package/dist/plugin.js +53 -0
  34. package/dist/plugin.js.map +1 -0
  35. package/dist/translators/claude.content.translators.d.ts +12 -0
  36. package/dist/translators/claude.content.translators.d.ts.map +1 -0
  37. package/dist/translators/claude.content.translators.js +65 -0
  38. package/dist/translators/claude.content.translators.js.map +1 -0
  39. package/dist/translators/claude.message.translators.d.ts +14 -0
  40. package/dist/translators/claude.message.translators.d.ts.map +1 -0
  41. package/dist/translators/claude.message.translators.js +129 -0
  42. package/dist/translators/claude.message.translators.js.map +1 -0
  43. package/dist/translators/claude.request.translators.d.ts +18 -0
  44. package/dist/translators/claude.request.translators.d.ts.map +1 -0
  45. package/dist/translators/claude.request.translators.js +110 -0
  46. package/dist/translators/claude.request.translators.js.map +1 -0
  47. package/dist/translators/claude.response.content.translators.d.ts +12 -0
  48. package/dist/translators/claude.response.content.translators.d.ts.map +1 -0
  49. package/dist/translators/claude.response.content.translators.js +53 -0
  50. package/dist/translators/claude.response.content.translators.js.map +1 -0
  51. package/dist/translators/claude.response.message.translators.d.ts +14 -0
  52. package/dist/translators/claude.response.message.translators.d.ts.map +1 -0
  53. package/dist/translators/claude.response.message.translators.js +95 -0
  54. package/dist/translators/claude.response.message.translators.js.map +1 -0
  55. package/dist/translators/claude.response.translators.d.ts +18 -0
  56. package/dist/translators/claude.response.translators.d.ts.map +1 -0
  57. package/dist/translators/claude.response.translators.js +109 -0
  58. package/dist/translators/claude.response.translators.js.map +1 -0
  59. package/dist/translators/claude.tool.translators.d.ts +19 -0
  60. package/dist/translators/claude.tool.translators.d.ts.map +1 -0
  61. package/dist/translators/claude.tool.translators.js +68 -0
  62. package/dist/translators/claude.tool.translators.js.map +1 -0
  63. package/dist/translators/claude.usage.translators.d.ts +12 -0
  64. package/dist/translators/claude.usage.translators.d.ts.map +1 -0
  65. package/dist/translators/claude.usage.translators.js +51 -0
  66. package/dist/translators/claude.usage.translators.js.map +1 -0
  67. package/dist/translators/index.d.ts +10 -0
  68. package/dist/translators/index.d.ts.map +1 -0
  69. package/dist/translators/index.js +10 -0
  70. package/dist/translators/index.js.map +1 -0
  71. package/dist/translators/streaming/claude.content.block.delta.event.translator.d.ts +12 -0
  72. package/dist/translators/streaming/claude.content.block.delta.event.translator.d.ts.map +1 -0
  73. package/dist/translators/streaming/claude.content.block.delta.event.translator.js +91 -0
  74. package/dist/translators/streaming/claude.content.block.delta.event.translator.js.map +1 -0
  75. package/dist/translators/streaming/claude.content.block.start.event.translator.d.ts +12 -0
  76. package/dist/translators/streaming/claude.content.block.start.event.translator.d.ts.map +1 -0
  77. package/dist/translators/streaming/claude.content.block.start.event.translator.js +83 -0
  78. package/dist/translators/streaming/claude.content.block.start.event.translator.js.map +1 -0
  79. package/dist/translators/streaming/claude.content.block.stop.event.translator.d.ts +12 -0
  80. package/dist/translators/streaming/claude.content.block.stop.event.translator.d.ts.map +1 -0
  81. package/dist/translators/streaming/claude.content.block.stop.event.translator.js +48 -0
  82. package/dist/translators/streaming/claude.content.block.stop.event.translator.js.map +1 -0
  83. package/dist/translators/streaming/claude.message.delta.event.translator.d.ts +12 -0
  84. package/dist/translators/streaming/claude.message.delta.event.translator.d.ts.map +1 -0
  85. package/dist/translators/streaming/claude.message.delta.event.translator.js +74 -0
  86. package/dist/translators/streaming/claude.message.delta.event.translator.js.map +1 -0
  87. package/dist/translators/streaming/claude.message.start.event.translator.d.ts +14 -0
  88. package/dist/translators/streaming/claude.message.start.event.translator.d.ts.map +1 -0
  89. package/dist/translators/streaming/claude.message.start.event.translator.js +81 -0
  90. package/dist/translators/streaming/claude.message.start.event.translator.js.map +1 -0
  91. package/dist/translators/streaming/claude.message.stop.event.translator.d.ts +12 -0
  92. package/dist/translators/streaming/claude.message.stop.event.translator.d.ts.map +1 -0
  93. package/dist/translators/streaming/claude.message.stop.event.translator.js +52 -0
  94. package/dist/translators/streaming/claude.message.stop.event.translator.js.map +1 -0
  95. package/dist/translators/streaming/claude.stream.translator.d.ts +24 -0
  96. package/dist/translators/streaming/claude.stream.translator.d.ts.map +1 -0
  97. package/dist/translators/streaming/claude.stream.translator.js +136 -0
  98. package/dist/translators/streaming/claude.stream.translator.js.map +1 -0
  99. package/dist/translators/streaming/index.d.ts +8 -0
  100. package/dist/translators/streaming/index.d.ts.map +1 -0
  101. package/dist/translators/streaming/index.js +8 -0
  102. package/dist/translators/streaming/index.js.map +1 -0
  103. package/dist/types/index.d.ts +3 -0
  104. package/dist/types/index.d.ts.map +1 -0
  105. package/dist/types/index.js +3 -0
  106. package/dist/types/index.js.map +1 -0
  107. package/dist/types/request.types.d.ts +8 -0
  108. package/dist/types/request.types.d.ts.map +1 -0
  109. package/dist/types/request.types.js +2 -0
  110. package/dist/types/request.types.js.map +1 -0
  111. package/dist/types/response.types.d.ts +16 -0
  112. package/dist/types/response.types.d.ts.map +1 -0
  113. package/dist/types/response.types.js +2 -0
  114. package/dist/types/response.types.js.map +1 -0
  115. package/dist/utils/finish.reason.mapper.d.ts +5 -0
  116. package/dist/utils/finish.reason.mapper.d.ts.map +1 -0
  117. package/dist/utils/finish.reason.mapper.js +40 -0
  118. package/dist/utils/finish.reason.mapper.js.map +1 -0
  119. package/dist/utils/stable-id.d.ts +2 -0
  120. package/dist/utils/stable-id.d.ts.map +1 -0
  121. package/dist/utils/stable-id.js +13 -0
  122. package/dist/utils/stable-id.js.map +1 -0
  123. package/package.json +73 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Holokai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,588 @@
1
+ # @holokai/holo-provider-claude
2
+
3
+ > **Official Claude (Anthropic) provider plugin for Holo LLM Gateway**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@holokai/holo-provider-claude.svg)](https://www.npmjs.com/package/@holokai/holo-provider-claude)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ---
9
+
10
+ ## Overview
11
+
12
+ The Claude provider plugin enables Holo to communicate with Anthropic's Claude API through the universal Holo format. This plugin is part of the migration from the monolithic provider architecture to a plugin-based system, providing complete bidirectional translation between Claude's native API and the portable Holo format.
13
+
14
+ ### Key Features
15
+
16
+ - ✅ **Full Holo SDK Integration** - Uses `@holokai/sdk` types for strict type safety
17
+ - ✅ **Bidirectional Translation** - Claude ↔ Holo format with lossless core fields
18
+ - ✅ **Streaming Support** - 6 granular event types with proper orchestration
19
+ - ✅ **Tool Calling** - Complete function calling support with proper extraction
20
+ - ✅ **Vision/Multimodal** - Image support via URLs and base64 data URIs
21
+ - ✅ **Prompt Caching** - Cost optimization through content caching
22
+ - ✅ **Extended Thinking** - Claude 3.5 Sonnet+ reasoning capabilities
23
+ - ✅ **Plugin Architecture** - Auto-discovered, hot-reloadable, independently versioned
24
+
25
+ ---
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ npm install @holokai/holo-provider-claude
31
+ ```
32
+
33
+ ### Peer Dependencies
34
+
35
+ This plugin requires:
36
+ - `@holokai/sdk` ^0.1.0 - Holo universal format types and plugin contracts
37
+
38
+ ---
39
+
40
+ ## Quick Start
41
+
42
+ ### Automatic Discovery
43
+
44
+ When installed in a Holo worker environment, this plugin is automatically discovered and loaded by the plugin system. No manual registration required.
45
+
46
+ ### Configuration
47
+
48
+ Add a provider configuration to your Holo deployment:
49
+
50
+ ```json
51
+ {
52
+ "id": "claude-primary",
53
+ "provider_type": "claude",
54
+ "plugin_id": "@holokai/holo-provider-claude",
55
+ "api_key": "${ANTHROPIC_API_KEY}",
56
+ "model": "claude-3-5-sonnet-20241022",
57
+ "config": {
58
+ "defaultModel": "claude-3-5-sonnet-20241022",
59
+ "timeoutMs": 60000,
60
+ "maxRetries": 2,
61
+ "enableVision": true
62
+ }
63
+ }
64
+ ```
65
+
66
+ ### Usage in Code
67
+
68
+ ```typescript
69
+ import { HoloRequest, HoloResponse } from '@holokai/sdk';
70
+
71
+ const request: HoloRequest = {
72
+ model: 'claude-3-5-sonnet-20241022',
73
+ messages: [
74
+ { role: 'user', content: 'Explain quantum computing briefly.' }
75
+ ],
76
+ max_tokens: 1000,
77
+ temperature: 0.7
78
+ };
79
+
80
+ // Plugin handles translation automatically
81
+ const response: HoloResponse = await holoClient.chat(request);
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Migration from Monolithic Architecture
87
+
88
+ ### What Changed
89
+
90
+ This plugin represents the extraction of Claude provider logic from the monolithic `src/providers/claude/` codebase into a standalone, independently versioned package.
91
+
92
+ **Before** (Monolithic):
93
+ ```
94
+ src/providers/claude/
95
+ ├── claude.translator.ts
96
+ ├── translators/
97
+ ├── streaming/
98
+ └── types/
99
+ ```
100
+
101
+ **After** (Plugin):
102
+ ```
103
+ @holokai/holo-provider-claude
104
+ ├── src/
105
+ │ ├── plugin.ts # Plugin entrypoint
106
+ │ ├── manifest.ts # Plugin metadata
107
+ │ ├── claude.provider.ts # Provider implementation
108
+ │ └── translators/ # Translation logic (preserved)
109
+ └── package.json
110
+ ```
111
+
112
+ ### Migration Benefits
113
+
114
+ 1. **Independent Versioning** - Update Claude support without core releases
115
+ 2. **Hot Reload** - Deploy new Claude versions without downtime
116
+ 3. **Type Safety** - Strict SDK types eliminate `Record<string, unknown>`
117
+ 4. **Reduced Coupling** - Plugin contracts enforce clean boundaries
118
+ 5. **Marketplace Ready** - Can be published to NPM independently
119
+
120
+ ### Breaking Changes
121
+
122
+ - **Import paths changed**: Use `@holokai/sdk` for types instead of `../../types`
123
+ - **Configuration schema**: Now validated via plugin manifest
124
+ - **Dependency injection**: Uses plugin container instead of core DI
125
+
126
+ ---
127
+
128
+ ## Architecture
129
+
130
+ ### Plugin Structure
131
+
132
+ ```
133
+ @holokai/holo-provider-claude/
134
+ ├── src/
135
+ │ ├── plugin.ts # ProviderPlugin implementation
136
+ │ ├── manifest.ts # Plugin metadata & config schema
137
+ │ ├── claude.provider.ts # Core provider logic
138
+ │ ├── claude.translator.ts # Main translator facade
139
+ │ ├── translators/
140
+ │ │ ├── claude.request.translator.ts
141
+ │ │ ├── claude.response.translator.ts
142
+ │ │ ├── claude.message.translator.ts
143
+ │ │ ├── claude.tool.translator.ts
144
+ │ │ └── claude.usage.translator.ts
145
+ │ ├── streaming/
146
+ │ │ ├── claude.stream.translator.ts # Orchestrator
147
+ │ │ ├── claude.message.start.event.translator.ts
148
+ │ │ ├── claude.message.delta.event.translator.ts
149
+ │ │ ├── claude.message.stop.event.translator.ts
150
+ │ │ ├── claude.content.block.start.event.translator.ts
151
+ │ │ ├── claude.content.block.delta.event.translator.ts
152
+ │ │ └── claude.content.block.stop.event.translator.ts
153
+ │ ├── types/
154
+ │ │ └── (Re-exports from @anthropic-ai/sdk)
155
+ │ └── utils/
156
+ │ └── (Helper functions)
157
+ └── package.json
158
+ ```
159
+
160
+ ### Translation Flow
161
+
162
+ ```
163
+ ┌─────────────────┐
164
+ │ Holo Request │
165
+ │ (SDK types) │
166
+ └────────┬────────┘
167
+
168
+
169
+ ┌─────────────────────────┐
170
+ │ ClaudeRequestTranslator │
171
+ │ - Maps Holo → Claude │
172
+ │ - Transforms content │
173
+ │ - Renames fields │
174
+ └────────┬────────────────┘
175
+
176
+
177
+ ┌─────────────────┐
178
+ │ Claude API │
179
+ │ (@anthropic) │
180
+ └────────┬────────┘
181
+
182
+
183
+ ┌──────────────────────────┐
184
+ │ ClaudeResponseTranslator │
185
+ │ - Maps Claude → Holo │
186
+ │ - Extracts tool calls │
187
+ │ - Normalizes finish │
188
+ └────────┬─────────────────┘
189
+
190
+
191
+ ┌─────────────────┐
192
+ │ Holo Response │
193
+ │ (SDK types) │
194
+ └─────────────────┘
195
+ ```
196
+
197
+ ---
198
+
199
+ ## Holo Format Mapping
200
+
201
+ This plugin implements the official Holo format mappings as documented in the SDK.
202
+
203
+ ### Request Mapping: Holo → Claude
204
+
205
+ | Holo Field | Claude Field | Transformation | Notes |
206
+ |------------|-------------|----------------|-------|
207
+ | **Direct 1:1** ||||
208
+ | `model` | `model` | Direct | Required |
209
+ | `temperature` | `temperature` | Direct | 0-1 for Claude |
210
+ | `top_p` | `top_p` | Direct | Optional |
211
+ | `top_k` | `top_k` | Direct | Optional |
212
+ | `stream` | `stream` | Direct | Optional |
213
+ | `max_tokens` | `max_tokens` | Direct | Required by Claude |
214
+ | `stop_sequences` | `stop_sequences` | Direct | Array format |
215
+ | **Structure Transforms** ||||
216
+ | `system` (string) | `system` | Direct | Top-level |
217
+ | `system` (string[]) | `system` | Join with `\n\n` + drop metadata | Lossy if structured |
218
+ | `metadata.user_id` | `metadata.user_id` | Direct | Optional |
219
+ | `tools[].parameters` | `tools[].input_schema` | Rename field | JSON Schema |
220
+ | `tool_choice.type: 'specific'` | `tool_choice.type: 'tool'` | Map type + name | Specific tool |
221
+ | `tool_choice.type: 'required'` | `tool_choice.type: 'any'` | Map type | Any tool |
222
+ | `messages[]` | `messages[]` | Transform content | See Content Mapping |
223
+
224
+ **Dropped Fields** (Holo → Claude):
225
+ - `response_format` - Claude doesn't support structured output modes
226
+ - `frequency_penalty` - Not supported
227
+ - `presence_penalty` - Not supported
228
+ - `seed` - Not supported
229
+
230
+ See [SDK Provider Mappings](../../packages/sdk/docs/PROVIDER_MAPPINGS.md#claude--holo-requests) for complete details.
231
+
232
+ ### Response Mapping: Claude → Holo
233
+
234
+ | Claude Field | Holo Field | Transformation | Notes |
235
+ |-------------|------------|----------------|-------|
236
+ | **Direct 1:1** ||||
237
+ | `id` | `id` | Direct | Always present |
238
+ | `model` | `model` | Direct | Always present |
239
+ | `role: 'assistant'` | `messages[0].role` | Wrap in array | Always assistant |
240
+ | **Structure Transforms** ||||
241
+ | `content[]` blocks | `messages[0].content` | Extract text + tools | Multi-part |
242
+ | `stop_reason` | `finish_reason` | Map codes | See table below |
243
+ | `usage.input_tokens` | `usage.input_tokens` | Direct | Optional |
244
+ | `usage.output_tokens` | `usage.output_tokens` | Direct | Optional |
245
+ | `usage.cache_read_input_tokens` | `usage.cache_read_tokens` | Direct | Optional |
246
+ | `usage.cache_creation_input_tokens` | `usage.cache_write_tokens` | Direct | Optional |
247
+ | `usage.service_tier` | `service_tier` | Promote to top-level | Optional |
248
+ | N/A | `created` | Synthesize with `Date.now()` | Claude lacks timestamp |
249
+
250
+ **Finish Reason Mapping**:
251
+
252
+ | Claude `stop_reason` | Holo `finish_reason` |
253
+ |---------------------|---------------------|
254
+ | `end_turn` | `stop` |
255
+ | `max_tokens` | `length` |
256
+ | `tool_use` | `tool_calls` |
257
+ | `refusal` | `content_filter` |
258
+ | `pause_turn` | `stop` (preserve in metadata) |
259
+
260
+ ### Content Mapping
261
+
262
+ #### Text Content
263
+
264
+ ```typescript
265
+ // Holo
266
+ { type: 'text', text: 'Hello' }
267
+
268
+ // Claude (direct)
269
+ { type: 'text', text: 'Hello' }
270
+ ```
271
+
272
+ #### Image Content
273
+
274
+ ```typescript
275
+ // Holo
276
+ { type: 'image', url: 'https://example.com/image.png' }
277
+
278
+ // Claude
279
+ { type: 'image', source: { type: 'url', url: 'https://example.com/image.png' } }
280
+
281
+ // Holo (base64)
282
+ { type: 'image', url: 'data:image/png;base64,iVBORw...' }
283
+
284
+ // Claude (base64)
285
+ { type: 'image', source: { type: 'base64', media_type: 'image/png', data: 'iVBORw...' } }
286
+ ```
287
+
288
+ #### Tool Calls (Extraction Required)
289
+
290
+ ```typescript
291
+ // Claude Response (embedded in content)
292
+ {
293
+ content: [
294
+ { type: 'text', text: 'Let me check that for you.' },
295
+ { type: 'tool_use', id: 'toolu_123', name: 'get_weather', input: { location: 'SF' } }
296
+ ]
297
+ }
298
+
299
+ // Holo Response (extracted)
300
+ {
301
+ messages: [{
302
+ role: 'assistant',
303
+ content: 'Let me check that for you.',
304
+ tool_calls: [{
305
+ id: 'toolu_123',
306
+ type: 'function',
307
+ function: { name: 'get_weather', arguments: { location: 'SF' } }
308
+ }]
309
+ }]
310
+ }
311
+ ```
312
+
313
+ ---
314
+
315
+ ## Streaming
316
+
317
+ ### Event Types
318
+
319
+ Claude provides the most granular streaming events (6 types):
320
+
321
+ | Event Type | Purpose | Holo Mapping |
322
+ |------------|---------|--------------|
323
+ | `message_start` | Initialize message | `type: 'message_start'` |
324
+ | `content_block_start` | Begin content block (text/tool) | Used internally |
325
+ | `content_block_delta` | Incremental content | `type: 'content_delta'` |
326
+ | `content_block_stop` | End content block | Used internally |
327
+ | `message_delta` | Usage/finish updates | `type: 'message_delta'` |
328
+ | `message_stop` | Completion marker | `type: 'message_stop'` |
329
+
330
+ ### Orchestration
331
+
332
+ The `ClaudeStreamTranslator` maintains state to:
333
+ 1. Track content blocks by index
334
+ 2. Accumulate text and tool input deltas
335
+ 3. Extract complete tool calls on block completion
336
+ 4. Preserve raw provider events in `provider_delta`
337
+
338
+ ### Streaming Example
339
+
340
+ ```typescript
341
+ import { HoloStreamChunk } from '@holokai/sdk';
342
+
343
+ const stream = await claudeProvider.streamChat(request);
344
+
345
+ for await (const chunk: HoloStreamChunk of stream) {
346
+ switch (chunk.delta?.type) {
347
+ case 'message_start':
348
+ console.log('Message started:', chunk.id);
349
+ break;
350
+ case 'content_delta':
351
+ process.stdout.write(chunk.delta.delta.content ?? '');
352
+ break;
353
+ case 'message_delta':
354
+ console.log('Usage:', chunk.usage);
355
+ break;
356
+ case 'message_stop':
357
+ console.log('Complete. Reason:', chunk.finish_reason);
358
+ break;
359
+ }
360
+ }
361
+ ```
362
+
363
+ ---
364
+
365
+ ## Claude-Specific Features
366
+
367
+ ### Extended Thinking
368
+
369
+ Enable extended thinking for Claude 3.5 Sonnet+ models:
370
+
371
+ ```typescript
372
+ const request: HoloRequest = {
373
+ model: 'claude-3-5-sonnet-20241022',
374
+ messages: [{ role: 'user', content: 'Solve this complex problem...' }],
375
+ // Provider-specific config (passed through)
376
+ provider_config: {
377
+ thinking: {
378
+ type: 'enabled',
379
+ budget_tokens: 5000
380
+ }
381
+ }
382
+ };
383
+ ```
384
+
385
+ **Note**: Thinking blocks (`content[].type = 'thinking'`) are Claude-specific and not part of the portable Holo format. They're preserved in `provider_delta` for debugging.
386
+
387
+ ### Prompt Caching
388
+
389
+ Reduce costs by caching reusable prompts:
390
+
391
+ ```typescript
392
+ // Provider-specific caching (requires Claude API beta)
393
+ const cachedMessages = [
394
+ {
395
+ role: 'user',
396
+ content: 'Large document content...',
397
+ cache_control: { type: 'ephemeral' } // Cache this message
398
+ }
399
+ ];
400
+ ```
401
+
402
+ **Note**: Cache control is Claude-specific and handled at the provider level, not in Holo format.
403
+
404
+ ### Beta Features
405
+
406
+ Access beta features via plugin configuration:
407
+
408
+ ```json
409
+ {
410
+ "config": {
411
+ "betas": ["prompt-caching-2024-07-31"]
412
+ }
413
+ }
414
+ ```
415
+
416
+ ---
417
+
418
+ ## Type Safety
419
+
420
+ ### SDK Integration
421
+
422
+ This plugin uses strict SDK types exclusively:
423
+
424
+ ```typescript
425
+ import type {
426
+ HoloRequest,
427
+ HoloResponse,
428
+ HoloMessage,
429
+ HoloTool,
430
+ HoloJsonSchema // ✅ Proper JSON Schema types
431
+ } from '@holokai/sdk';
432
+
433
+ // ❌ NO: Record<string, unknown>
434
+ // ✅ YES: HoloJsonSchema
435
+ ```
436
+
437
+ ### Migration from Legacy Types
438
+
439
+ **Before** (Legacy provider):
440
+ ```typescript
441
+ import { HoloTool } from '../../types/holo/requests';
442
+
443
+ interface HoloTool {
444
+ parameters?: Record<string, unknown>; // ❌ Loose typing
445
+ }
446
+ ```
447
+
448
+ **After** (Plugin SDK):
449
+ ```typescript
450
+ import type { HoloTool, HoloJsonSchema } from '@holokai/sdk';
451
+
452
+ interface HoloTool {
453
+ parameters?: HoloJsonSchema; // ✅ Strict JSON Schema Draft 7
454
+ }
455
+ ```
456
+
457
+ ### Type Safety
458
+
459
+ All interfaces use strict TypeScript types from `@holokai/sdk` for compile-time validation.
460
+
461
+ ---
462
+
463
+ ## Configuration Schema
464
+
465
+ The plugin exposes a JSON Schema for configuration validation:
466
+
467
+ ```typescript
468
+ {
469
+ apiKey: string; // Required
470
+ baseUrl?: string; // Optional custom endpoint
471
+ defaultModel?: string; // Fallback model
472
+ allowedModels?: string[]; // Model allowlist
473
+ timeoutMs?: number; // Request timeout (default: 60000)
474
+ maxRetries?: number; // Retry attempts (default: 2)
475
+ enableVision?: boolean; // Vision support (default: true)
476
+ logRequests?: boolean; // Observability (default: false)
477
+ telemetrySampleRate?: number;// Sampling rate (default: 1.0)
478
+ }
479
+ ```
480
+
481
+ See [manifest.ts](./src/manifest.ts) for the complete schema.
482
+
483
+ ---
484
+
485
+ ## Development
486
+
487
+ ### Setup
488
+
489
+ ```bash
490
+ # Install dependencies
491
+ npm install
492
+
493
+ # Build
494
+ npm run build
495
+
496
+ # Type checking
497
+ npm run type-check
498
+
499
+ # Run tests
500
+ npm test
501
+ ```
502
+
503
+ ### Testing
504
+
505
+ ```bash
506
+ # Unit tests
507
+ npm test
508
+
509
+ # Integration tests (requires API key)
510
+ ANTHROPIC_API_KEY=sk-... npm run test:integration
511
+
512
+ # Watch mode
513
+ npm run test:watch
514
+ ```
515
+
516
+ ### Building
517
+
518
+ ```bash
519
+ # Production build
520
+ npm run build
521
+
522
+ # Watch mode
523
+ npm run build:watch
524
+
525
+ # Clean
526
+ npm run clean
527
+ ```
528
+
529
+ ---
530
+
531
+ ## Related Documentation
532
+
533
+ ### SDK Documentation
534
+ - [SDK README](../sdk/README.md) - Plugin development guide and templates
535
+
536
+ ### Claude API Documentation
537
+ - [Official API Reference](https://docs.anthropic.com/claude/reference)
538
+ - [Streaming Guide](https://docs.anthropic.com/claude/reference/streaming)
539
+ - [Tool Use](https://docs.anthropic.com/claude/docs/tool-use)
540
+ - [Vision](https://docs.anthropic.com/claude/docs/vision)
541
+ - [Prompt Caching](https://docs.anthropic.com/claude/docs/prompt-caching)
542
+
543
+ ### Migration Notes
544
+ - This plugin was extracted from the monolithic `src/providers/claude/` codebase
545
+ - Migration to plugin architecture is complete
546
+
547
+ ---
548
+
549
+ ## Contributing
550
+
551
+ ### Adding Features
552
+
553
+ 1. Update types in `@holokai/sdk` first (if needed)
554
+ 2. Implement translator logic
555
+ 3. Write tests (unit + integration)
556
+ 4. Update this README
557
+
558
+ ### Reporting Issues
559
+
560
+ Found a bug or have a feature request?
561
+ - GitHub Issues: https://github.com/holokai/holo-provider-claude/issues
562
+ - Include: Holo version, Claude model, request/response samples
563
+
564
+ ---
565
+
566
+ ## License
567
+
568
+ MIT © Holokai
569
+
570
+ ---
571
+
572
+ ## Changelog
573
+
574
+ ### v0.1.0 (Current)
575
+ - ✅ Initial plugin release
576
+ - ✅ Extracted from monolithic architecture
577
+ - ✅ Migrated to SDK types
578
+ - ✅ Validated against Holo format spec
579
+ - ✅ Complete streaming orchestration
580
+ - ✅ Tool calling with extraction
581
+ - ✅ Vision/multimodal support
582
+ - ✅ Prompt caching support
583
+
584
+ ---
585
+
586
+ **Last Updated**: 2025-12-18
587
+ **Plugin Version**: 0.1.0
588
+ **SDK Version**: ^0.1.0
@@ -0,0 +1,12 @@
1
+ import { BaseAuditor, HoloWorkerRequest, HoloWorkerResponse, ProviderEnvelope } from "@holokai/sdk";
2
+ import { MessageCreateParamsBase } from "@anthropic-ai/sdk/resources/messages";
3
+ import { LlmRequest, LlmResponse } from "@holokai/sdk/core/entities";
4
+ export declare class ClaudeAuditor extends BaseAuditor {
5
+ readonly provider = "claude";
6
+ protected toHoloRequest(workerRequest: HoloWorkerRequest, llmRequest: Omit<LlmRequest, 'id'>): void;
7
+ protected mapProviderPayload(workerRequest: HoloWorkerRequest, llmRequest: Omit<LlmRequest, 'id'>): void;
8
+ protected collectResponseMetrics(workerResponse: HoloWorkerResponse, llmResponse: Omit<LlmResponse, 'id'>): void;
9
+ private extractUserPromptFromMessages;
10
+ protected createProviderEnvelope(payload: MessageCreateParamsBase): Promise<ProviderEnvelope>;
11
+ }
12
+ //# sourceMappingURL=claude.auditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.auditor.d.ts","sourceRoot":"","sources":["../src/claude.auditor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,WAAW,EAAE,iBAAiB,EAAE,kBAAkB,EAAe,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAC/G,OAAO,EAAC,uBAAuB,EAAC,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAC,UAAU,EAAE,WAAW,EAAY,MAAM,4BAA4B,CAAC;AAE9E,qBACa,aAAc,SAAQ,WAAW;IAC1C,QAAQ,CAAC,QAAQ,YAAY;IAE7B,SAAS,CAAC,aAAa,CAAC,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,IAAI;IAiBnG,SAAS,CAAC,kBAAkB,CAAC,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,IAAI;IAiBxG,SAAS,CAAC,sBAAsB,CAC5B,cAAc,EAAE,kBAAkB,EAClC,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GACrC,IAAI;IA+BP,OAAO,CAAC,6BAA6B;cAmBrB,sBAAsB,CAClC,OAAO,EAAE,uBAAuB,GACjC,OAAO,CAAC,gBAAgB,CAAC;CAc/B"}