@providerprotocol/ai 0.0.3 → 0.0.4
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @providerprotocol/ai
|
|
2
2
|
|
|
3
|
-
Unified Provider Protocol (UPP-1.
|
|
3
|
+
Unified Provider Protocol (UPP-1.2) implementation for AI inference across multiple providers.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -15,6 +15,8 @@ import { llm } from '@providerprotocol/ai';
|
|
|
15
15
|
import { anthropic } from '@providerprotocol/ai/anthropic';
|
|
16
16
|
import { openai } from '@providerprotocol/ai/openai';
|
|
17
17
|
import { google } from '@providerprotocol/ai/google';
|
|
18
|
+
import { ollama } from '@providerprotocol/ai/ollama';
|
|
19
|
+
import { openrouter } from '@providerprotocol/ai/openrouter';
|
|
18
20
|
|
|
19
21
|
// Simple generation
|
|
20
22
|
const claude = llm({ model: anthropic('claude-sonnet-4-20250514') });
|
|
@@ -61,6 +63,8 @@ console.log(turn.data); // { name: 'John', age: 30 }
|
|
|
61
63
|
| Anthropic | `@providerprotocol/ai/anthropic` |
|
|
62
64
|
| OpenAI | `@providerprotocol/ai/openai` |
|
|
63
65
|
| Google | `@providerprotocol/ai/google` |
|
|
66
|
+
| Ollama | `@providerprotocol/ai/ollama` |
|
|
67
|
+
| OpenRouter | `@providerprotocol/ai/openrouter` |
|
|
64
68
|
|
|
65
69
|
## Configuration
|
|
66
70
|
|
|
@@ -5,8 +5,8 @@ import { b as Provider } from '../provider-CUJWjgNl.js';
|
|
|
5
5
|
* These are passed through to the Anthropic Messages API
|
|
6
6
|
*/
|
|
7
7
|
interface AnthropicLLMParams {
|
|
8
|
-
/** Maximum number of tokens to generate (required by Anthropic) */
|
|
9
|
-
max_tokens
|
|
8
|
+
/** Maximum number of tokens to generate (required by Anthropic API) */
|
|
9
|
+
max_tokens?: number;
|
|
10
10
|
/** Temperature for randomness (0.0 - 1.0) */
|
|
11
11
|
temperature?: number;
|
|
12
12
|
/** Top-p (nucleus) sampling */
|
package/dist/anthropic/index.js
CHANGED
|
@@ -20,12 +20,14 @@ import {
|
|
|
20
20
|
|
|
21
21
|
// src/providers/anthropic/transform.ts
|
|
22
22
|
function transformRequest(request, modelId) {
|
|
23
|
-
const params = request.params ?? {
|
|
23
|
+
const params = request.params ?? {};
|
|
24
24
|
const anthropicRequest = {
|
|
25
25
|
model: modelId,
|
|
26
|
-
max_tokens: params.max_tokens ?? 4096,
|
|
27
26
|
messages: request.messages.map(transformMessage)
|
|
28
27
|
};
|
|
28
|
+
if (params.max_tokens !== void 0) {
|
|
29
|
+
anthropicRequest.max_tokens = params.max_tokens;
|
|
30
|
+
}
|
|
29
31
|
if (request.system) {
|
|
30
32
|
anthropicRequest.system = request.system;
|
|
31
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/anthropic/transform.ts","../../src/providers/anthropic/llm.ts","../../src/providers/anthropic/index.ts"],"sourcesContent":["import type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { ContentBlock, TextBlock, ImageBlock } from '../../types/content.ts';\nimport {\n AssistantMessage,\n UserMessage,\n ToolResultMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport type {\n AnthropicLLMParams,\n AnthropicRequest,\n AnthropicMessage,\n AnthropicContent,\n AnthropicTool,\n AnthropicResponse,\n AnthropicStreamEvent,\n AnthropicContentBlockDeltaEvent,\n} from './types.ts';\n\n/**\n * Transform UPP request to Anthropic format\n */\nexport function transformRequest<TParams extends AnthropicLLMParams>(\n request: LLMRequest<TParams>,\n modelId: string\n): AnthropicRequest {\n const params = (request.params ?? { max_tokens: 4096 }) as AnthropicLLMParams;\n\n const anthropicRequest: AnthropicRequest = {\n model: modelId,\n max_tokens: params.max_tokens ?? 4096,\n messages: request.messages.map(transformMessage),\n };\n\n // System prompt (top-level in Anthropic)\n if (request.system) {\n anthropicRequest.system = request.system;\n }\n\n // Model parameters\n if (params.temperature !== undefined) {\n anthropicRequest.temperature = params.temperature;\n }\n if (params.top_p !== undefined) {\n anthropicRequest.top_p = params.top_p;\n }\n if (params.top_k !== undefined) {\n anthropicRequest.top_k = params.top_k;\n }\n if (params.stop_sequences) {\n anthropicRequest.stop_sequences = params.stop_sequences;\n }\n if (params.metadata) {\n anthropicRequest.metadata = params.metadata;\n }\n if (params.thinking) {\n anthropicRequest.thinking = params.thinking;\n }\n if (params.service_tier !== undefined) {\n anthropicRequest.service_tier = params.service_tier;\n }\n\n // Tools\n if (request.tools && request.tools.length > 0) {\n anthropicRequest.tools = request.tools.map(transformTool);\n anthropicRequest.tool_choice = { type: 'auto' };\n }\n\n // Structured output via tool-based approach\n // Anthropic doesn't have native structured output, so we use a tool to enforce the schema\n if (request.structure) {\n const structuredTool: AnthropicTool = {\n name: 'json_response',\n description: 'Return the response in the specified JSON format. You MUST use this tool to provide your response.',\n input_schema: {\n type: 'object',\n properties: request.structure.properties,\n required: request.structure.required,\n },\n };\n\n // Add the structured output tool (may coexist with user tools)\n anthropicRequest.tools = [...(anthropicRequest.tools ?? []), structuredTool];\n // Force the model to use the json_response tool\n anthropicRequest.tool_choice = { type: 'tool', name: 'json_response' };\n }\n\n return anthropicRequest;\n}\n\n/**\n * Filter to only valid content blocks with a type property\n */\nfunction filterValidContent<T extends { type?: string }>(content: T[]): T[] {\n return content.filter((c) => c && typeof c.type === 'string');\n}\n\n/**\n * Transform a UPP Message to Anthropic format\n */\nfunction transformMessage(message: Message): AnthropicMessage {\n if (isUserMessage(message)) {\n const validContent = filterValidContent(message.content);\n return {\n role: 'user',\n content: validContent.map(transformContentBlock),\n };\n }\n\n if (isAssistantMessage(message)) {\n const validContent = filterValidContent(message.content);\n const content: AnthropicContent[] = validContent.map(transformContentBlock);\n\n // Add tool calls as tool_use content blocks\n if (message.toolCalls) {\n for (const call of message.toolCalls) {\n content.push({\n type: 'tool_use',\n id: call.toolCallId,\n name: call.toolName,\n input: call.arguments,\n });\n }\n }\n\n return {\n role: 'assistant',\n content,\n };\n }\n\n if (isToolResultMessage(message)) {\n // Tool results are sent as user messages with tool_result content\n return {\n role: 'user',\n content: message.results.map((result) => ({\n type: 'tool_result' as const,\n tool_use_id: result.toolCallId,\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n is_error: result.isError,\n })),\n };\n }\n\n throw new Error(`Unknown message type: ${message.type}`);\n}\n\n/**\n * Transform a content block to Anthropic format\n */\nfunction transformContentBlock(block: ContentBlock): AnthropicContent {\n switch (block.type) {\n case 'text':\n return { type: 'text', text: block.text };\n\n case 'image': {\n const imageBlock = block as ImageBlock;\n if (imageBlock.source.type === 'base64') {\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: imageBlock.mimeType,\n data: imageBlock.source.data,\n },\n };\n }\n if (imageBlock.source.type === 'url') {\n return {\n type: 'image',\n source: {\n type: 'url',\n url: imageBlock.source.url,\n },\n };\n }\n if (imageBlock.source.type === 'bytes') {\n // Convert bytes to base64\n const base64 = btoa(\n Array.from(imageBlock.source.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: imageBlock.mimeType,\n data: base64,\n },\n };\n }\n throw new Error(`Unknown image source type`);\n }\n\n default:\n throw new Error(`Unsupported content type: ${block.type}`);\n }\n}\n\n/**\n * Transform a UPP Tool to Anthropic format\n */\nfunction transformTool(tool: Tool): AnthropicTool {\n return {\n name: tool.name,\n description: tool.description,\n input_schema: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n },\n };\n}\n\n/**\n * Transform Anthropic response to UPP LLMResponse\n */\nexport function transformResponse(data: AnthropicResponse): LLMResponse {\n // Extract text content\n const textContent: TextBlock[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n for (const block of data.content) {\n if (block.type === 'text') {\n textContent.push({ type: 'text', text: block.text });\n } else if (block.type === 'tool_use') {\n // Check if this is the json_response tool (structured output)\n if (block.name === 'json_response') {\n // Extract structured data from tool arguments\n structuredData = block.input;\n }\n toolCalls.push({\n toolCallId: block.id,\n toolName: block.name,\n arguments: block.input,\n });\n }\n // Skip thinking blocks for now\n }\n\n const message = new AssistantMessage(\n textContent,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: data.id,\n metadata: {\n anthropic: {\n stop_reason: data.stop_reason,\n stop_sequence: data.stop_sequence,\n model: data.model,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: data.usage.input_tokens,\n outputTokens: data.usage.output_tokens,\n totalTokens: data.usage.input_tokens + data.usage.output_tokens,\n };\n\n return {\n message,\n usage,\n stopReason: data.stop_reason ?? 'end_turn',\n data: structuredData,\n };\n}\n\n/**\n * State for accumulating streaming response\n */\nexport interface StreamState {\n messageId: string;\n model: string;\n content: Array<{ type: string; text?: string; id?: string; name?: string; input?: string }>;\n stopReason: string | null;\n inputTokens: number;\n outputTokens: number;\n}\n\n/**\n * Create initial stream state\n */\nexport function createStreamState(): StreamState {\n return {\n messageId: '',\n model: '',\n content: [],\n stopReason: null,\n inputTokens: 0,\n outputTokens: 0,\n };\n}\n\n/**\n * Transform Anthropic stream event to UPP StreamEvent\n * Returns null for events that don't produce UPP events\n */\nexport function transformStreamEvent(\n event: AnthropicStreamEvent,\n state: StreamState\n): StreamEvent | null {\n switch (event.type) {\n case 'message_start':\n state.messageId = event.message.id;\n state.model = event.message.model;\n state.inputTokens = event.message.usage.input_tokens;\n return { type: 'message_start', index: 0, delta: {} };\n\n case 'content_block_start':\n // Initialize content block\n if (event.content_block.type === 'text') {\n state.content[event.index] = { type: 'text', text: '' };\n } else if (event.content_block.type === 'tool_use') {\n state.content[event.index] = {\n type: 'tool_use',\n id: event.content_block.id,\n name: event.content_block.name,\n input: '',\n };\n }\n return { type: 'content_block_start', index: event.index, delta: {} };\n\n case 'content_block_delta': {\n const delta = event.delta;\n if (delta.type === 'text_delta') {\n if (state.content[event.index]) {\n state.content[event.index]!.text =\n (state.content[event.index]!.text ?? '') + delta.text;\n }\n return {\n type: 'text_delta',\n index: event.index,\n delta: { text: delta.text },\n };\n }\n if (delta.type === 'input_json_delta') {\n if (state.content[event.index]) {\n state.content[event.index]!.input =\n (state.content[event.index]!.input ?? '') + delta.partial_json;\n }\n return {\n type: 'tool_call_delta',\n index: event.index,\n delta: {\n argumentsJson: delta.partial_json,\n toolCallId: state.content[event.index]?.id,\n toolName: state.content[event.index]?.name,\n },\n };\n }\n if (delta.type === 'thinking_delta') {\n return {\n type: 'reasoning_delta',\n index: event.index,\n delta: { text: delta.thinking },\n };\n }\n return null;\n }\n\n case 'content_block_stop':\n return { type: 'content_block_stop', index: event.index, delta: {} };\n\n case 'message_delta':\n state.stopReason = event.delta.stop_reason;\n state.outputTokens = event.usage.output_tokens;\n return null;\n\n case 'message_stop':\n return { type: 'message_stop', index: 0, delta: {} };\n\n case 'ping':\n case 'error':\n return null;\n\n default:\n return null;\n }\n}\n\n/**\n * Build LLMResponse from accumulated stream state\n */\nexport function buildResponseFromState(state: StreamState): LLMResponse {\n const textContent: TextBlock[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n for (const block of state.content) {\n if (block.type === 'text' && block.text) {\n textContent.push({ type: 'text', text: block.text });\n } else if (block.type === 'tool_use' && block.id && block.name) {\n let args: Record<string, unknown> = {};\n if (block.input) {\n try {\n args = JSON.parse(block.input);\n } catch {\n // Invalid JSON - use empty object\n }\n }\n // Check if this is the json_response tool (structured output)\n if (block.name === 'json_response') {\n structuredData = args;\n }\n toolCalls.push({\n toolCallId: block.id,\n toolName: block.name,\n arguments: args,\n });\n }\n }\n\n const message = new AssistantMessage(\n textContent,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: state.messageId,\n metadata: {\n anthropic: {\n stop_reason: state.stopReason,\n model: state.model,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.inputTokens + state.outputTokens,\n };\n\n return {\n message,\n usage,\n stopReason: state.stopReason ?? 'end_turn',\n data: structuredData,\n };\n}\n","import type { LLMHandler, BoundLLMModel, LLMRequest, LLMResponse, LLMStreamResult, LLMCapabilities } from '../../types/llm.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { parseSSEStream } from '../../http/sse.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport type { AnthropicLLMParams, AnthropicResponse, AnthropicStreamEvent } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamEvent,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\nconst ANTHROPIC_API_URL = 'https://api.anthropic.com/v1/messages';\nconst ANTHROPIC_VERSION = '2023-06-01';\n\n/**\n * Anthropic API capabilities\n */\nconst ANTHROPIC_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Create Anthropic LLM handler\n */\nexport function createLLMHandler(): LLMHandler<AnthropicLLMParams> {\n // Provider reference injected by createProvider() after construction\n let providerRef: LLMProvider<AnthropicLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<AnthropicLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<AnthropicLLMParams> {\n // Use the injected provider reference (set by createProvider)\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n 'INVALID_REQUEST',\n 'anthropic',\n 'llm'\n );\n }\n\n const model: BoundLLMModel<AnthropicLLMParams> = {\n modelId,\n capabilities: ANTHROPIC_CAPABILITIES,\n\n get provider(): LLMProvider<AnthropicLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<AnthropicLLMParams>): Promise<LLMResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'ANTHROPIC_API_KEY',\n 'anthropic',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? ANTHROPIC_API_URL;\n const body = transformRequest(request, modelId);\n\n const response = await doFetch(\n baseUrl,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': request.config.apiVersion ?? ANTHROPIC_VERSION,\n },\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'anthropic',\n 'llm'\n );\n\n const data = (await response.json()) as AnthropicResponse;\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<AnthropicLLMParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n const apiKey = await resolveApiKey(\n request.config,\n 'ANTHROPIC_API_KEY',\n 'anthropic',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? ANTHROPIC_API_URL;\n const body = transformRequest(request, modelId);\n body.stream = true;\n\n const response = await doStreamFetch(\n baseUrl,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': request.config.apiVersion ?? ANTHROPIC_VERSION,\n },\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'anthropic',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'anthropic', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n 'PROVIDER_ERROR',\n 'anthropic',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n for await (const data of parseSSEStream(response.body)) {\n // Check for Anthropic error event\n if (typeof data === 'object' && data !== null && 'type' in data) {\n const event = data as AnthropicStreamEvent;\n\n if (event.type === 'error') {\n const error = new UPPError(\n event.error.message,\n 'PROVIDER_ERROR',\n 'anthropic',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n const uppEvent = transformStreamEvent(event, state);\n if (uppEvent) {\n yield uppEvent;\n }\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n responseReject(error as Error);\n throw error;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","import { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\n\n/**\n * Anthropic provider\n * Supports LLM modality with Claude models\n */\nexport const anthropic = createProvider({\n name: 'anthropic',\n version: '1.0.0',\n modalities: {\n llm: createLLMHandler(),\n },\n});\n\n// Re-export types\nexport type { AnthropicLLMParams } from './types.ts';\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/providers/anthropic/transform.ts","../../src/providers/anthropic/llm.ts","../../src/providers/anthropic/index.ts"],"sourcesContent":["import type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { ContentBlock, TextBlock, ImageBlock } from '../../types/content.ts';\nimport {\n AssistantMessage,\n UserMessage,\n ToolResultMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport type {\n AnthropicLLMParams,\n AnthropicRequest,\n AnthropicMessage,\n AnthropicContent,\n AnthropicTool,\n AnthropicResponse,\n AnthropicStreamEvent,\n AnthropicContentBlockDeltaEvent,\n} from './types.ts';\n\n/**\n * Transform UPP request to Anthropic format\n */\nexport function transformRequest<TParams extends AnthropicLLMParams>(\n request: LLMRequest<TParams>,\n modelId: string\n): AnthropicRequest {\n const params = (request.params ?? {}) as AnthropicLLMParams;\n\n const anthropicRequest: AnthropicRequest = {\n model: modelId,\n messages: request.messages.map(transformMessage),\n };\n\n // Only include max_tokens if provided - let Anthropic API enforce its requirement\n if (params.max_tokens !== undefined) {\n anthropicRequest.max_tokens = params.max_tokens;\n }\n\n // System prompt (top-level in Anthropic)\n if (request.system) {\n anthropicRequest.system = request.system;\n }\n\n // Model parameters\n if (params.temperature !== undefined) {\n anthropicRequest.temperature = params.temperature;\n }\n if (params.top_p !== undefined) {\n anthropicRequest.top_p = params.top_p;\n }\n if (params.top_k !== undefined) {\n anthropicRequest.top_k = params.top_k;\n }\n if (params.stop_sequences) {\n anthropicRequest.stop_sequences = params.stop_sequences;\n }\n if (params.metadata) {\n anthropicRequest.metadata = params.metadata;\n }\n if (params.thinking) {\n anthropicRequest.thinking = params.thinking;\n }\n if (params.service_tier !== undefined) {\n anthropicRequest.service_tier = params.service_tier;\n }\n\n // Tools\n if (request.tools && request.tools.length > 0) {\n anthropicRequest.tools = request.tools.map(transformTool);\n anthropicRequest.tool_choice = { type: 'auto' };\n }\n\n // Structured output via tool-based approach\n // Anthropic doesn't have native structured output, so we use a tool to enforce the schema\n if (request.structure) {\n const structuredTool: AnthropicTool = {\n name: 'json_response',\n description: 'Return the response in the specified JSON format. You MUST use this tool to provide your response.',\n input_schema: {\n type: 'object',\n properties: request.structure.properties,\n required: request.structure.required,\n },\n };\n\n // Add the structured output tool (may coexist with user tools)\n anthropicRequest.tools = [...(anthropicRequest.tools ?? []), structuredTool];\n // Force the model to use the json_response tool\n anthropicRequest.tool_choice = { type: 'tool', name: 'json_response' };\n }\n\n return anthropicRequest;\n}\n\n/**\n * Filter to only valid content blocks with a type property\n */\nfunction filterValidContent<T extends { type?: string }>(content: T[]): T[] {\n return content.filter((c) => c && typeof c.type === 'string');\n}\n\n/**\n * Transform a UPP Message to Anthropic format\n */\nfunction transformMessage(message: Message): AnthropicMessage {\n if (isUserMessage(message)) {\n const validContent = filterValidContent(message.content);\n return {\n role: 'user',\n content: validContent.map(transformContentBlock),\n };\n }\n\n if (isAssistantMessage(message)) {\n const validContent = filterValidContent(message.content);\n const content: AnthropicContent[] = validContent.map(transformContentBlock);\n\n // Add tool calls as tool_use content blocks\n if (message.toolCalls) {\n for (const call of message.toolCalls) {\n content.push({\n type: 'tool_use',\n id: call.toolCallId,\n name: call.toolName,\n input: call.arguments,\n });\n }\n }\n\n return {\n role: 'assistant',\n content,\n };\n }\n\n if (isToolResultMessage(message)) {\n // Tool results are sent as user messages with tool_result content\n return {\n role: 'user',\n content: message.results.map((result) => ({\n type: 'tool_result' as const,\n tool_use_id: result.toolCallId,\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n is_error: result.isError,\n })),\n };\n }\n\n throw new Error(`Unknown message type: ${message.type}`);\n}\n\n/**\n * Transform a content block to Anthropic format\n */\nfunction transformContentBlock(block: ContentBlock): AnthropicContent {\n switch (block.type) {\n case 'text':\n return { type: 'text', text: block.text };\n\n case 'image': {\n const imageBlock = block as ImageBlock;\n if (imageBlock.source.type === 'base64') {\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: imageBlock.mimeType,\n data: imageBlock.source.data,\n },\n };\n }\n if (imageBlock.source.type === 'url') {\n return {\n type: 'image',\n source: {\n type: 'url',\n url: imageBlock.source.url,\n },\n };\n }\n if (imageBlock.source.type === 'bytes') {\n // Convert bytes to base64\n const base64 = btoa(\n Array.from(imageBlock.source.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: imageBlock.mimeType,\n data: base64,\n },\n };\n }\n throw new Error(`Unknown image source type`);\n }\n\n default:\n throw new Error(`Unsupported content type: ${block.type}`);\n }\n}\n\n/**\n * Transform a UPP Tool to Anthropic format\n */\nfunction transformTool(tool: Tool): AnthropicTool {\n return {\n name: tool.name,\n description: tool.description,\n input_schema: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n },\n };\n}\n\n/**\n * Transform Anthropic response to UPP LLMResponse\n */\nexport function transformResponse(data: AnthropicResponse): LLMResponse {\n // Extract text content\n const textContent: TextBlock[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n for (const block of data.content) {\n if (block.type === 'text') {\n textContent.push({ type: 'text', text: block.text });\n } else if (block.type === 'tool_use') {\n // Check if this is the json_response tool (structured output)\n if (block.name === 'json_response') {\n // Extract structured data from tool arguments\n structuredData = block.input;\n }\n toolCalls.push({\n toolCallId: block.id,\n toolName: block.name,\n arguments: block.input,\n });\n }\n // Skip thinking blocks for now\n }\n\n const message = new AssistantMessage(\n textContent,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: data.id,\n metadata: {\n anthropic: {\n stop_reason: data.stop_reason,\n stop_sequence: data.stop_sequence,\n model: data.model,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: data.usage.input_tokens,\n outputTokens: data.usage.output_tokens,\n totalTokens: data.usage.input_tokens + data.usage.output_tokens,\n };\n\n return {\n message,\n usage,\n stopReason: data.stop_reason ?? 'end_turn',\n data: structuredData,\n };\n}\n\n/**\n * State for accumulating streaming response\n */\nexport interface StreamState {\n messageId: string;\n model: string;\n content: Array<{ type: string; text?: string; id?: string; name?: string; input?: string }>;\n stopReason: string | null;\n inputTokens: number;\n outputTokens: number;\n}\n\n/**\n * Create initial stream state\n */\nexport function createStreamState(): StreamState {\n return {\n messageId: '',\n model: '',\n content: [],\n stopReason: null,\n inputTokens: 0,\n outputTokens: 0,\n };\n}\n\n/**\n * Transform Anthropic stream event to UPP StreamEvent\n * Returns null for events that don't produce UPP events\n */\nexport function transformStreamEvent(\n event: AnthropicStreamEvent,\n state: StreamState\n): StreamEvent | null {\n switch (event.type) {\n case 'message_start':\n state.messageId = event.message.id;\n state.model = event.message.model;\n state.inputTokens = event.message.usage.input_tokens;\n return { type: 'message_start', index: 0, delta: {} };\n\n case 'content_block_start':\n // Initialize content block\n if (event.content_block.type === 'text') {\n state.content[event.index] = { type: 'text', text: '' };\n } else if (event.content_block.type === 'tool_use') {\n state.content[event.index] = {\n type: 'tool_use',\n id: event.content_block.id,\n name: event.content_block.name,\n input: '',\n };\n }\n return { type: 'content_block_start', index: event.index, delta: {} };\n\n case 'content_block_delta': {\n const delta = event.delta;\n if (delta.type === 'text_delta') {\n if (state.content[event.index]) {\n state.content[event.index]!.text =\n (state.content[event.index]!.text ?? '') + delta.text;\n }\n return {\n type: 'text_delta',\n index: event.index,\n delta: { text: delta.text },\n };\n }\n if (delta.type === 'input_json_delta') {\n if (state.content[event.index]) {\n state.content[event.index]!.input =\n (state.content[event.index]!.input ?? '') + delta.partial_json;\n }\n return {\n type: 'tool_call_delta',\n index: event.index,\n delta: {\n argumentsJson: delta.partial_json,\n toolCallId: state.content[event.index]?.id,\n toolName: state.content[event.index]?.name,\n },\n };\n }\n if (delta.type === 'thinking_delta') {\n return {\n type: 'reasoning_delta',\n index: event.index,\n delta: { text: delta.thinking },\n };\n }\n return null;\n }\n\n case 'content_block_stop':\n return { type: 'content_block_stop', index: event.index, delta: {} };\n\n case 'message_delta':\n state.stopReason = event.delta.stop_reason;\n state.outputTokens = event.usage.output_tokens;\n return null;\n\n case 'message_stop':\n return { type: 'message_stop', index: 0, delta: {} };\n\n case 'ping':\n case 'error':\n return null;\n\n default:\n return null;\n }\n}\n\n/**\n * Build LLMResponse from accumulated stream state\n */\nexport function buildResponseFromState(state: StreamState): LLMResponse {\n const textContent: TextBlock[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n\n for (const block of state.content) {\n if (block.type === 'text' && block.text) {\n textContent.push({ type: 'text', text: block.text });\n } else if (block.type === 'tool_use' && block.id && block.name) {\n let args: Record<string, unknown> = {};\n if (block.input) {\n try {\n args = JSON.parse(block.input);\n } catch {\n // Invalid JSON - use empty object\n }\n }\n // Check if this is the json_response tool (structured output)\n if (block.name === 'json_response') {\n structuredData = args;\n }\n toolCalls.push({\n toolCallId: block.id,\n toolName: block.name,\n arguments: args,\n });\n }\n }\n\n const message = new AssistantMessage(\n textContent,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: state.messageId,\n metadata: {\n anthropic: {\n stop_reason: state.stopReason,\n model: state.model,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.inputTokens + state.outputTokens,\n };\n\n return {\n message,\n usage,\n stopReason: state.stopReason ?? 'end_turn',\n data: structuredData,\n };\n}\n","import type { LLMHandler, BoundLLMModel, LLMRequest, LLMResponse, LLMStreamResult, LLMCapabilities } from '../../types/llm.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { parseSSEStream } from '../../http/sse.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport type { AnthropicLLMParams, AnthropicResponse, AnthropicStreamEvent } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamEvent,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\nconst ANTHROPIC_API_URL = 'https://api.anthropic.com/v1/messages';\nconst ANTHROPIC_VERSION = '2023-06-01';\n\n/**\n * Anthropic API capabilities\n */\nconst ANTHROPIC_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Create Anthropic LLM handler\n */\nexport function createLLMHandler(): LLMHandler<AnthropicLLMParams> {\n // Provider reference injected by createProvider() after construction\n let providerRef: LLMProvider<AnthropicLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<AnthropicLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<AnthropicLLMParams> {\n // Use the injected provider reference (set by createProvider)\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n 'INVALID_REQUEST',\n 'anthropic',\n 'llm'\n );\n }\n\n const model: BoundLLMModel<AnthropicLLMParams> = {\n modelId,\n capabilities: ANTHROPIC_CAPABILITIES,\n\n get provider(): LLMProvider<AnthropicLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<AnthropicLLMParams>): Promise<LLMResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'ANTHROPIC_API_KEY',\n 'anthropic',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? ANTHROPIC_API_URL;\n const body = transformRequest(request, modelId);\n\n const response = await doFetch(\n baseUrl,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': request.config.apiVersion ?? ANTHROPIC_VERSION,\n },\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'anthropic',\n 'llm'\n );\n\n const data = (await response.json()) as AnthropicResponse;\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<AnthropicLLMParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n const apiKey = await resolveApiKey(\n request.config,\n 'ANTHROPIC_API_KEY',\n 'anthropic',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? ANTHROPIC_API_URL;\n const body = transformRequest(request, modelId);\n body.stream = true;\n\n const response = await doStreamFetch(\n baseUrl,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': request.config.apiVersion ?? ANTHROPIC_VERSION,\n },\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'anthropic',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'anthropic', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n 'PROVIDER_ERROR',\n 'anthropic',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n for await (const data of parseSSEStream(response.body)) {\n // Check for Anthropic error event\n if (typeof data === 'object' && data !== null && 'type' in data) {\n const event = data as AnthropicStreamEvent;\n\n if (event.type === 'error') {\n const error = new UPPError(\n event.error.message,\n 'PROVIDER_ERROR',\n 'anthropic',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n const uppEvent = transformStreamEvent(event, state);\n if (uppEvent) {\n yield uppEvent;\n }\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n responseReject(error as Error);\n throw error;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","import { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\n\n/**\n * Anthropic provider\n * Supports LLM modality with Claude models\n */\nexport const anthropic = createProvider({\n name: 'anthropic',\n version: '1.0.0',\n modalities: {\n llm: createLLMHandler(),\n },\n});\n\n// Re-export types\nexport type { AnthropicLLMParams } from './types.ts';\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@providerprotocol/ai",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "UPP
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"description": "UPP: Unified Provider Protocol for AI inference",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Provider Protocol"
|
|
@@ -30,14 +30,18 @@ export function transformRequest<TParams extends AnthropicLLMParams>(
|
|
|
30
30
|
request: LLMRequest<TParams>,
|
|
31
31
|
modelId: string
|
|
32
32
|
): AnthropicRequest {
|
|
33
|
-
const params = (request.params ?? {
|
|
33
|
+
const params = (request.params ?? {}) as AnthropicLLMParams;
|
|
34
34
|
|
|
35
35
|
const anthropicRequest: AnthropicRequest = {
|
|
36
36
|
model: modelId,
|
|
37
|
-
max_tokens: params.max_tokens ?? 4096,
|
|
38
37
|
messages: request.messages.map(transformMessage),
|
|
39
38
|
};
|
|
40
39
|
|
|
40
|
+
// Only include max_tokens if provided - let Anthropic API enforce its requirement
|
|
41
|
+
if (params.max_tokens !== undefined) {
|
|
42
|
+
anthropicRequest.max_tokens = params.max_tokens;
|
|
43
|
+
}
|
|
44
|
+
|
|
41
45
|
// System prompt (top-level in Anthropic)
|
|
42
46
|
if (request.system) {
|
|
43
47
|
anthropicRequest.system = request.system;
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* These are passed through to the Anthropic Messages API
|
|
4
4
|
*/
|
|
5
5
|
export interface AnthropicLLMParams {
|
|
6
|
-
/** Maximum number of tokens to generate (required by Anthropic) */
|
|
7
|
-
max_tokens
|
|
6
|
+
/** Maximum number of tokens to generate (required by Anthropic API) */
|
|
7
|
+
max_tokens?: number;
|
|
8
8
|
|
|
9
9
|
/** Temperature for randomness (0.0 - 1.0) */
|
|
10
10
|
temperature?: number;
|
|
@@ -42,7 +42,7 @@ export interface AnthropicLLMParams {
|
|
|
42
42
|
*/
|
|
43
43
|
export interface AnthropicRequest {
|
|
44
44
|
model: string;
|
|
45
|
-
max_tokens
|
|
45
|
+
max_tokens?: number;
|
|
46
46
|
messages: AnthropicMessage[];
|
|
47
47
|
system?: string;
|
|
48
48
|
temperature?: number;
|