ai.matey.backend 0.2.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.
- package/LICENSE +21 -0
- package/dist/cjs/index.js +60 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/providers/ai21.js +331 -0
- package/dist/cjs/providers/ai21.js.map +1 -0
- package/dist/cjs/providers/anthropic.js +664 -0
- package/dist/cjs/providers/anthropic.js.map +1 -0
- package/dist/cjs/providers/anyscale.js +338 -0
- package/dist/cjs/providers/anyscale.js.map +1 -0
- package/dist/cjs/providers/aws-bedrock.js +374 -0
- package/dist/cjs/providers/aws-bedrock.js.map +1 -0
- package/dist/cjs/providers/azure-openai.js +406 -0
- package/dist/cjs/providers/azure-openai.js.map +1 -0
- package/dist/cjs/providers/cerebras.js +356 -0
- package/dist/cjs/providers/cerebras.js.map +1 -0
- package/dist/cjs/providers/cloudflare.js +359 -0
- package/dist/cjs/providers/cloudflare.js.map +1 -0
- package/dist/cjs/providers/cohere.js +368 -0
- package/dist/cjs/providers/cohere.js.map +1 -0
- package/dist/cjs/providers/deepinfra.js +343 -0
- package/dist/cjs/providers/deepinfra.js.map +1 -0
- package/dist/cjs/providers/deepseek.js +104 -0
- package/dist/cjs/providers/deepseek.js.map +1 -0
- package/dist/cjs/providers/fireworks.js +363 -0
- package/dist/cjs/providers/fireworks.js.map +1 -0
- package/dist/cjs/providers/gemini.js +292 -0
- package/dist/cjs/providers/gemini.js.map +1 -0
- package/dist/cjs/providers/groq.js +143 -0
- package/dist/cjs/providers/groq.js.map +1 -0
- package/dist/cjs/providers/huggingface.js +392 -0
- package/dist/cjs/providers/huggingface.js.map +1 -0
- package/dist/cjs/providers/lmstudio.js +144 -0
- package/dist/cjs/providers/lmstudio.js.map +1 -0
- package/dist/cjs/providers/mistral.js +288 -0
- package/dist/cjs/providers/mistral.js.map +1 -0
- package/dist/cjs/providers/nvidia.js +167 -0
- package/dist/cjs/providers/nvidia.js.map +1 -0
- package/dist/cjs/providers/ollama.js +257 -0
- package/dist/cjs/providers/ollama.js.map +1 -0
- package/dist/cjs/providers/openai.js +640 -0
- package/dist/cjs/providers/openai.js.map +1 -0
- package/dist/cjs/providers/openrouter.js +379 -0
- package/dist/cjs/providers/openrouter.js.map +1 -0
- package/dist/cjs/providers/perplexity.js +372 -0
- package/dist/cjs/providers/perplexity.js.map +1 -0
- package/dist/cjs/providers/replicate.js +340 -0
- package/dist/cjs/providers/replicate.js.map +1 -0
- package/dist/cjs/providers/together-ai.js +341 -0
- package/dist/cjs/providers/together-ai.js.map +1 -0
- package/dist/cjs/providers/xai.js +339 -0
- package/dist/cjs/providers/xai.js.map +1 -0
- package/dist/cjs/shared.js +279 -0
- package/dist/cjs/shared.js.map +1 -0
- package/dist/esm/index.js +44 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/providers/ai21.js +327 -0
- package/dist/esm/providers/ai21.js.map +1 -0
- package/dist/esm/providers/anthropic.js +660 -0
- package/dist/esm/providers/anthropic.js.map +1 -0
- package/dist/esm/providers/anyscale.js +334 -0
- package/dist/esm/providers/anyscale.js.map +1 -0
- package/dist/esm/providers/aws-bedrock.js +370 -0
- package/dist/esm/providers/aws-bedrock.js.map +1 -0
- package/dist/esm/providers/azure-openai.js +402 -0
- package/dist/esm/providers/azure-openai.js.map +1 -0
- package/dist/esm/providers/cerebras.js +352 -0
- package/dist/esm/providers/cerebras.js.map +1 -0
- package/dist/esm/providers/cloudflare.js +355 -0
- package/dist/esm/providers/cloudflare.js.map +1 -0
- package/dist/esm/providers/cohere.js +364 -0
- package/dist/esm/providers/cohere.js.map +1 -0
- package/dist/esm/providers/deepinfra.js +339 -0
- package/dist/esm/providers/deepinfra.js.map +1 -0
- package/dist/esm/providers/deepseek.js +99 -0
- package/dist/esm/providers/deepseek.js.map +1 -0
- package/dist/esm/providers/fireworks.js +359 -0
- package/dist/esm/providers/fireworks.js.map +1 -0
- package/dist/esm/providers/gemini.js +288 -0
- package/dist/esm/providers/gemini.js.map +1 -0
- package/dist/esm/providers/groq.js +138 -0
- package/dist/esm/providers/groq.js.map +1 -0
- package/dist/esm/providers/huggingface.js +387 -0
- package/dist/esm/providers/huggingface.js.map +1 -0
- package/dist/esm/providers/lmstudio.js +139 -0
- package/dist/esm/providers/lmstudio.js.map +1 -0
- package/dist/esm/providers/mistral.js +284 -0
- package/dist/esm/providers/mistral.js.map +1 -0
- package/dist/esm/providers/nvidia.js +162 -0
- package/dist/esm/providers/nvidia.js.map +1 -0
- package/dist/esm/providers/ollama.js +253 -0
- package/dist/esm/providers/ollama.js.map +1 -0
- package/dist/esm/providers/openai.js +636 -0
- package/dist/esm/providers/openai.js.map +1 -0
- package/dist/esm/providers/openrouter.js +375 -0
- package/dist/esm/providers/openrouter.js.map +1 -0
- package/dist/esm/providers/perplexity.js +368 -0
- package/dist/esm/providers/perplexity.js.map +1 -0
- package/dist/esm/providers/replicate.js +336 -0
- package/dist/esm/providers/replicate.js.map +1 -0
- package/dist/esm/providers/together-ai.js +337 -0
- package/dist/esm/providers/together-ai.js.map +1 -0
- package/dist/esm/providers/xai.js +335 -0
- package/dist/esm/providers/xai.js.map +1 -0
- package/dist/esm/shared.js +272 -0
- package/dist/esm/shared.js.map +1 -0
- package/dist/types/index.d.ts +38 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/providers/ai21.d.ts +106 -0
- package/dist/types/providers/ai21.d.ts.map +1 -0
- package/dist/types/providers/anthropic.d.ts +194 -0
- package/dist/types/providers/anthropic.d.ts.map +1 -0
- package/dist/types/providers/anyscale.d.ts +109 -0
- package/dist/types/providers/anyscale.d.ts.map +1 -0
- package/dist/types/providers/aws-bedrock.d.ts +152 -0
- package/dist/types/providers/aws-bedrock.d.ts.map +1 -0
- package/dist/types/providers/azure-openai.d.ts +142 -0
- package/dist/types/providers/azure-openai.d.ts.map +1 -0
- package/dist/types/providers/cerebras.d.ts +130 -0
- package/dist/types/providers/cerebras.d.ts.map +1 -0
- package/dist/types/providers/cloudflare.d.ts +125 -0
- package/dist/types/providers/cloudflare.d.ts.map +1 -0
- package/dist/types/providers/cohere.d.ts +114 -0
- package/dist/types/providers/cohere.d.ts.map +1 -0
- package/dist/types/providers/deepinfra.d.ts +118 -0
- package/dist/types/providers/deepinfra.d.ts.map +1 -0
- package/dist/types/providers/deepseek.d.ts +68 -0
- package/dist/types/providers/deepseek.d.ts.map +1 -0
- package/dist/types/providers/fireworks.d.ts +127 -0
- package/dist/types/providers/fireworks.d.ts.map +1 -0
- package/dist/types/providers/gemini.d.ts +71 -0
- package/dist/types/providers/gemini.d.ts.map +1 -0
- package/dist/types/providers/groq.d.ts +83 -0
- package/dist/types/providers/groq.d.ts.map +1 -0
- package/dist/types/providers/huggingface.d.ts +154 -0
- package/dist/types/providers/huggingface.d.ts.map +1 -0
- package/dist/types/providers/lmstudio.d.ts +88 -0
- package/dist/types/providers/lmstudio.d.ts.map +1 -0
- package/dist/types/providers/mistral.d.ts +65 -0
- package/dist/types/providers/mistral.d.ts.map +1 -0
- package/dist/types/providers/nvidia.d.ts +100 -0
- package/dist/types/providers/nvidia.d.ts.map +1 -0
- package/dist/types/providers/ollama.d.ts +59 -0
- package/dist/types/providers/ollama.d.ts.map +1 -0
- package/dist/types/providers/openai.d.ts +205 -0
- package/dist/types/providers/openai.d.ts.map +1 -0
- package/dist/types/providers/openrouter.d.ts +135 -0
- package/dist/types/providers/openrouter.d.ts.map +1 -0
- package/dist/types/providers/perplexity.d.ts +116 -0
- package/dist/types/providers/perplexity.d.ts.map +1 -0
- package/dist/types/providers/replicate.d.ts +91 -0
- package/dist/types/providers/replicate.d.ts.map +1 -0
- package/dist/types/providers/together-ai.d.ts +118 -0
- package/dist/types/providers/together-ai.d.ts.map +1 -0
- package/dist/types/providers/xai.d.ts +119 -0
- package/dist/types/providers/xai.d.ts.map +1 -0
- package/dist/types/shared.d.ts +116 -0
- package/dist/types/shared.d.ts.map +1 -0
- package/package.json +327 -0
- package/readme.md +86 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fireworks AI Backend Adapter
|
|
4
|
+
*
|
|
5
|
+
* Adapts Universal IR to Fireworks AI Chat Completions API.
|
|
6
|
+
* Fireworks AI is OpenAI-compatible with 100+ models and fastest APIs.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.FireworksAIBackendAdapter = void 0;
|
|
12
|
+
const ai_matey_errors_1 = require("ai.matey.errors");
|
|
13
|
+
const ai_matey_utils_1 = require("ai.matey.utils");
|
|
14
|
+
const ai_matey_utils_2 = require("ai.matey.utils");
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Fireworks AI Backend Adapter
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Backend adapter for Fireworks AI Chat Completions API.
|
|
20
|
+
*
|
|
21
|
+
* Features:
|
|
22
|
+
* - 100+ open-source models
|
|
23
|
+
* - Fastest inference APIs
|
|
24
|
+
* - OpenAI-compatible with topK support
|
|
25
|
+
* - Vision model support
|
|
26
|
+
* - Function calling support
|
|
27
|
+
* - Reasoning models with reasoning_effort parameter
|
|
28
|
+
* - Pricing from $0.10 per 1M tokens
|
|
29
|
+
*/
|
|
30
|
+
class FireworksAIBackendAdapter {
|
|
31
|
+
metadata;
|
|
32
|
+
config;
|
|
33
|
+
baseURL;
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this.config = config;
|
|
36
|
+
this.baseURL = config.baseURL || 'https://api.fireworks.ai/inference/v1';
|
|
37
|
+
this.metadata = {
|
|
38
|
+
name: 'fireworks-ai-backend',
|
|
39
|
+
version: '1.0.0',
|
|
40
|
+
provider: 'Fireworks AI',
|
|
41
|
+
capabilities: {
|
|
42
|
+
streaming: true,
|
|
43
|
+
multiModal: true, // Vision models available
|
|
44
|
+
tools: true, // Function calling
|
|
45
|
+
maxContextTokens: 128000,
|
|
46
|
+
systemMessageStrategy: 'in-messages',
|
|
47
|
+
supportsMultipleSystemMessages: true,
|
|
48
|
+
supportsTemperature: true,
|
|
49
|
+
supportsTopP: true,
|
|
50
|
+
supportsTopK: true, // Fireworks AI supports topK
|
|
51
|
+
supportsSeed: false,
|
|
52
|
+
supportsFrequencyPenalty: true,
|
|
53
|
+
supportsPresencePenalty: true,
|
|
54
|
+
maxStopSequences: 4,
|
|
55
|
+
},
|
|
56
|
+
config: {
|
|
57
|
+
baseURL: this.baseURL,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Convert IR to Fireworks AI format.
|
|
63
|
+
*/
|
|
64
|
+
fromIR(request) {
|
|
65
|
+
const { messages } = (0, ai_matey_utils_1.normalizeSystemMessages)(request.messages, this.metadata.capabilities.systemMessageStrategy, this.metadata.capabilities.supportsMultipleSystemMessages);
|
|
66
|
+
const fireworksMessages = messages.map((msg) => ({
|
|
67
|
+
role: msg.role,
|
|
68
|
+
content: typeof msg.content === 'string'
|
|
69
|
+
? msg.content
|
|
70
|
+
: msg.content.map((block) => {
|
|
71
|
+
if (block.type === 'text') {
|
|
72
|
+
return { type: 'text', text: block.text };
|
|
73
|
+
}
|
|
74
|
+
else if (block.type === 'image') {
|
|
75
|
+
return {
|
|
76
|
+
type: 'image_url',
|
|
77
|
+
image_url: {
|
|
78
|
+
url: block.source.type === 'url'
|
|
79
|
+
? block.source.url
|
|
80
|
+
: `data:${block.source.mediaType};base64,${block.source.data}`,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return { type: 'text', text: JSON.stringify(block) };
|
|
85
|
+
}),
|
|
86
|
+
}));
|
|
87
|
+
const fireworksRequest = {
|
|
88
|
+
model: request.parameters?.model ||
|
|
89
|
+
this.config.defaultModel ||
|
|
90
|
+
'accounts/fireworks/models/llama-v3p1-8b-instruct',
|
|
91
|
+
messages: fireworksMessages,
|
|
92
|
+
temperature: request.parameters?.temperature,
|
|
93
|
+
max_tokens: request.parameters?.maxTokens,
|
|
94
|
+
top_p: request.parameters?.topP,
|
|
95
|
+
top_k: request.parameters?.topK, // Pass through topK
|
|
96
|
+
frequency_penalty: request.parameters?.frequencyPenalty,
|
|
97
|
+
presence_penalty: request.parameters?.presencePenalty,
|
|
98
|
+
stop: request.parameters?.stopSequences ? [...request.parameters.stopSequences] : undefined,
|
|
99
|
+
stream: request.stream || false,
|
|
100
|
+
};
|
|
101
|
+
// Add reasoning_effort for reasoning models (if specified in custom parameters)
|
|
102
|
+
if (request.parameters?.custom?.reasoning_effort) {
|
|
103
|
+
fireworksRequest.reasoning_effort = request.parameters.custom.reasoning_effort;
|
|
104
|
+
}
|
|
105
|
+
return fireworksRequest;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Convert Fireworks AI response to IR.
|
|
109
|
+
*/
|
|
110
|
+
toIR(response, originalRequest, latencyMs) {
|
|
111
|
+
const choice = response.choices[0];
|
|
112
|
+
if (!choice) {
|
|
113
|
+
throw new ai_matey_errors_1.ProviderError({
|
|
114
|
+
code: ai_matey_errors_1.ErrorCode.PROVIDER_ERROR,
|
|
115
|
+
message: 'No choices returned in response',
|
|
116
|
+
isRetryable: false,
|
|
117
|
+
provenance: { backend: this.metadata.name },
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
const message = {
|
|
121
|
+
role: choice.message.role === 'assistant' ? 'assistant' : 'user',
|
|
122
|
+
content: typeof choice.message.content === 'string'
|
|
123
|
+
? choice.message.content
|
|
124
|
+
: choice.message.content.map((c) => (c.type === 'text' ? c.text : '')).join(''),
|
|
125
|
+
};
|
|
126
|
+
const finishReasonMap = {
|
|
127
|
+
stop: 'stop',
|
|
128
|
+
length: 'length',
|
|
129
|
+
tool_calls: 'tool_calls',
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
message,
|
|
133
|
+
finishReason: finishReasonMap[choice.finish_reason || 'stop'] || 'stop',
|
|
134
|
+
usage: {
|
|
135
|
+
// Usage always present in Fireworks AI
|
|
136
|
+
promptTokens: response.usage.prompt_tokens,
|
|
137
|
+
completionTokens: response.usage.completion_tokens,
|
|
138
|
+
totalTokens: response.usage.total_tokens,
|
|
139
|
+
},
|
|
140
|
+
metadata: {
|
|
141
|
+
...originalRequest.metadata,
|
|
142
|
+
providerResponseId: response.id,
|
|
143
|
+
provenance: {
|
|
144
|
+
...originalRequest.metadata.provenance,
|
|
145
|
+
backend: this.metadata.name,
|
|
146
|
+
},
|
|
147
|
+
custom: {
|
|
148
|
+
...originalRequest.metadata.custom,
|
|
149
|
+
latencyMs,
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
raw: response,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Execute non-streaming request.
|
|
157
|
+
*/
|
|
158
|
+
async execute(request, signal) {
|
|
159
|
+
try {
|
|
160
|
+
const fireworksRequest = this.fromIR(request);
|
|
161
|
+
fireworksRequest.stream = false;
|
|
162
|
+
const startTime = Date.now();
|
|
163
|
+
const response = await fetch(`${this.baseURL}/chat/completions`, {
|
|
164
|
+
method: 'POST',
|
|
165
|
+
headers: this.getHeaders(),
|
|
166
|
+
body: JSON.stringify(fireworksRequest),
|
|
167
|
+
signal,
|
|
168
|
+
});
|
|
169
|
+
if (!response.ok) {
|
|
170
|
+
throw (0, ai_matey_errors_1.createErrorFromHttpResponse)(response.status, response.statusText, await response.text(), { backend: this.metadata.name });
|
|
171
|
+
}
|
|
172
|
+
const data = (await response.json());
|
|
173
|
+
return this.toIR(data, request, Date.now() - startTime);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
if (error instanceof ai_matey_errors_1.NetworkError || error instanceof ai_matey_errors_1.ProviderError) {
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
throw new ai_matey_errors_1.ProviderError({
|
|
180
|
+
code: ai_matey_errors_1.ErrorCode.PROVIDER_ERROR,
|
|
181
|
+
message: `Fireworks AI request failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
182
|
+
isRetryable: true,
|
|
183
|
+
provenance: { backend: this.metadata.name },
|
|
184
|
+
cause: error instanceof Error ? error : undefined,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Execute streaming request.
|
|
190
|
+
*/
|
|
191
|
+
async *executeStream(request, signal) {
|
|
192
|
+
try {
|
|
193
|
+
const fireworksRequest = this.fromIR(request);
|
|
194
|
+
fireworksRequest.stream = true;
|
|
195
|
+
const streamingConfig = (0, ai_matey_utils_2.mergeStreamingConfig)(this.config.streaming);
|
|
196
|
+
const effectiveMode = (0, ai_matey_utils_2.getEffectiveStreamMode)(request.streamMode, undefined, streamingConfig);
|
|
197
|
+
const includeBoth = streamingConfig.includeBoth || effectiveMode === 'accumulated';
|
|
198
|
+
const response = await fetch(`${this.baseURL}/chat/completions`, {
|
|
199
|
+
method: 'POST',
|
|
200
|
+
headers: this.getHeaders(),
|
|
201
|
+
body: JSON.stringify(fireworksRequest),
|
|
202
|
+
signal,
|
|
203
|
+
});
|
|
204
|
+
if (!response.ok) {
|
|
205
|
+
throw (0, ai_matey_errors_1.createErrorFromHttpResponse)(response.status, response.statusText, await response.text(), { backend: this.metadata.name });
|
|
206
|
+
}
|
|
207
|
+
if (!response.body) {
|
|
208
|
+
throw new ai_matey_errors_1.StreamError({
|
|
209
|
+
code: ai_matey_errors_1.ErrorCode.STREAM_ERROR,
|
|
210
|
+
message: 'No response body',
|
|
211
|
+
provenance: { backend: this.metadata.name },
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
let sequence = 0;
|
|
215
|
+
let contentBuffer = '';
|
|
216
|
+
let usage;
|
|
217
|
+
yield {
|
|
218
|
+
type: 'start',
|
|
219
|
+
sequence: sequence++,
|
|
220
|
+
metadata: {
|
|
221
|
+
...request.metadata,
|
|
222
|
+
provenance: {
|
|
223
|
+
...request.metadata.provenance,
|
|
224
|
+
backend: this.metadata.name,
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
const reader = response.body.getReader();
|
|
229
|
+
const decoder = new TextDecoder();
|
|
230
|
+
let buffer = '';
|
|
231
|
+
try {
|
|
232
|
+
while (true) {
|
|
233
|
+
const { done, value } = await reader.read();
|
|
234
|
+
if (done) {
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
buffer += decoder.decode(value, { stream: true });
|
|
238
|
+
const lines = buffer.split('\n');
|
|
239
|
+
buffer = lines.pop() || '';
|
|
240
|
+
for (const line of lines) {
|
|
241
|
+
if (!line.trim() || !line.startsWith('data: ')) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
const data = line.slice(6).trim();
|
|
245
|
+
if (data === '[DONE]') {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
try {
|
|
249
|
+
const chunk = JSON.parse(data);
|
|
250
|
+
const delta = chunk.choices[0]?.delta?.content;
|
|
251
|
+
// Capture usage stats from streaming chunks
|
|
252
|
+
if (chunk.usage) {
|
|
253
|
+
usage = {
|
|
254
|
+
promptTokens: chunk.usage.prompt_tokens,
|
|
255
|
+
completionTokens: chunk.usage.completion_tokens,
|
|
256
|
+
totalTokens: chunk.usage.total_tokens,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
if (delta) {
|
|
260
|
+
contentBuffer += delta;
|
|
261
|
+
const contentChunk = {
|
|
262
|
+
type: 'content',
|
|
263
|
+
sequence: sequence++,
|
|
264
|
+
delta: delta,
|
|
265
|
+
role: 'assistant',
|
|
266
|
+
};
|
|
267
|
+
if (includeBoth) {
|
|
268
|
+
contentChunk.accumulated = contentBuffer;
|
|
269
|
+
}
|
|
270
|
+
yield contentChunk;
|
|
271
|
+
}
|
|
272
|
+
if (chunk.choices[0]?.finish_reason) {
|
|
273
|
+
const finishReasonMap = {
|
|
274
|
+
stop: 'stop',
|
|
275
|
+
length: 'length',
|
|
276
|
+
};
|
|
277
|
+
const doneChunk = {
|
|
278
|
+
type: 'done',
|
|
279
|
+
sequence: sequence++,
|
|
280
|
+
finishReason: finishReasonMap[chunk.choices[0].finish_reason] || 'stop',
|
|
281
|
+
message: { role: 'assistant', content: contentBuffer },
|
|
282
|
+
};
|
|
283
|
+
// Include usage stats in done chunk
|
|
284
|
+
if (usage) {
|
|
285
|
+
doneChunk.usage = usage;
|
|
286
|
+
}
|
|
287
|
+
yield doneChunk;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch (parseError) {
|
|
291
|
+
console.warn('Failed to parse SSE chunk:', data, parseError);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
reader.releaseLock();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
yield {
|
|
302
|
+
type: 'error',
|
|
303
|
+
sequence: 0,
|
|
304
|
+
error: {
|
|
305
|
+
code: error instanceof Error ? error.name : 'UNKNOWN_ERROR',
|
|
306
|
+
message: error instanceof Error ? error.message : String(error),
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Get HTTP headers.
|
|
313
|
+
*/
|
|
314
|
+
getHeaders() {
|
|
315
|
+
const headers = {
|
|
316
|
+
'Content-Type': 'application/json',
|
|
317
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
318
|
+
};
|
|
319
|
+
return { ...headers, ...this.config.headers };
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Health check.
|
|
323
|
+
*/
|
|
324
|
+
async healthCheck() {
|
|
325
|
+
try {
|
|
326
|
+
const response = await fetch(`${this.baseURL}/models`, {
|
|
327
|
+
method: 'GET',
|
|
328
|
+
headers: this.getHeaders(),
|
|
329
|
+
signal: AbortSignal.timeout(5000),
|
|
330
|
+
});
|
|
331
|
+
return response.ok;
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Estimate cost.
|
|
339
|
+
*/
|
|
340
|
+
estimateCost(request) {
|
|
341
|
+
const pricing = {
|
|
342
|
+
'accounts/fireworks/models/llama-v3p1-8b-instruct': { input: 0.2, output: 0.2 },
|
|
343
|
+
'accounts/fireworks/models/llama-v3p1-70b-instruct': { input: 0.9, output: 0.9 },
|
|
344
|
+
'accounts/fireworks/models/qwen2p5-72b-instruct': { input: 0.9, output: 0.9 },
|
|
345
|
+
'accounts/fireworks/models/deepseek-v3': { input: 0.9, output: 2.0 },
|
|
346
|
+
};
|
|
347
|
+
const model = request.parameters?.model || this.config.defaultModel || '';
|
|
348
|
+
const modelPricing = pricing[model];
|
|
349
|
+
if (!modelPricing) {
|
|
350
|
+
return Promise.resolve(null);
|
|
351
|
+
}
|
|
352
|
+
const inputTokens = request.messages.reduce((sum, msg) => {
|
|
353
|
+
const content = typeof msg.content === 'string' ? msg.content : '';
|
|
354
|
+
return sum + Math.ceil(content.length / 4);
|
|
355
|
+
}, 0);
|
|
356
|
+
const outputTokens = request.parameters?.maxTokens || 1024;
|
|
357
|
+
const inputCost = (inputTokens / 1_000_000) * modelPricing.input;
|
|
358
|
+
const outputCost = (outputTokens / 1_000_000) * modelPricing.output;
|
|
359
|
+
return Promise.resolve(inputCost + outputCost);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
exports.FireworksAIBackendAdapter = FireworksAIBackendAdapter;
|
|
363
|
+
//# sourceMappingURL=fireworks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fireworks.js","sourceRoot":"","sources":["../../../src/providers/fireworks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Google Gemini Backend Adapter
|
|
4
|
+
*
|
|
5
|
+
* Adapts Universal IR to Google Gemini API.
|
|
6
|
+
* Handles Gemini's systemInstruction field and content array format.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.GeminiBackendAdapter = void 0;
|
|
12
|
+
const ai_matey_errors_1 = require("ai.matey.errors");
|
|
13
|
+
const ai_matey_utils_1 = require("ai.matey.utils");
|
|
14
|
+
const ai_matey_utils_2 = require("ai.matey.utils");
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Gemini Backend Adapter
|
|
17
|
+
// ============================================================================
|
|
18
|
+
class GeminiBackendAdapter {
|
|
19
|
+
metadata;
|
|
20
|
+
config;
|
|
21
|
+
baseURL;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.config = config;
|
|
24
|
+
this.baseURL = config.baseURL || 'https://generativelanguage.googleapis.com/v1beta';
|
|
25
|
+
// Note: Gemini is already browser-compatible by default (API key in URL query parameter)
|
|
26
|
+
// The browserMode flag has no effect for this adapter
|
|
27
|
+
this.metadata = {
|
|
28
|
+
name: 'gemini-backend',
|
|
29
|
+
version: '1.0.0',
|
|
30
|
+
provider: 'Google Gemini',
|
|
31
|
+
capabilities: {
|
|
32
|
+
streaming: true,
|
|
33
|
+
multiModal: true,
|
|
34
|
+
tools: true,
|
|
35
|
+
maxContextTokens: 2000000,
|
|
36
|
+
systemMessageStrategy: 'separate-parameter',
|
|
37
|
+
supportsMultipleSystemMessages: false,
|
|
38
|
+
supportsTemperature: true,
|
|
39
|
+
supportsTopP: true,
|
|
40
|
+
supportsTopK: true,
|
|
41
|
+
supportsSeed: false,
|
|
42
|
+
supportsFrequencyPenalty: false,
|
|
43
|
+
supportsPresencePenalty: false,
|
|
44
|
+
maxStopSequences: 5,
|
|
45
|
+
},
|
|
46
|
+
config: { baseURL: this.baseURL },
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async execute(request, signal) {
|
|
50
|
+
try {
|
|
51
|
+
const geminiRequest = this.fromIR(request);
|
|
52
|
+
const model = request.parameters?.model || 'gemini-pro';
|
|
53
|
+
const endpoint = `${this.baseURL}/models/${model}:generateContent?key=${this.config.apiKey}`;
|
|
54
|
+
const startTime = Date.now();
|
|
55
|
+
const response = await fetch(endpoint, {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers: { 'Content-Type': 'application/json', ...this.config.headers },
|
|
58
|
+
body: JSON.stringify(geminiRequest),
|
|
59
|
+
signal,
|
|
60
|
+
});
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
const errorBody = await response.text();
|
|
63
|
+
throw (0, ai_matey_errors_1.createErrorFromHttpResponse)(response.status, response.statusText, errorBody, {
|
|
64
|
+
backend: this.metadata.name,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const data = (await response.json());
|
|
68
|
+
return this.toIR(data, request, Date.now() - startTime);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (error instanceof ai_matey_errors_1.NetworkError || error instanceof ai_matey_errors_1.ProviderError) {
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
throw new ai_matey_errors_1.ProviderError({
|
|
75
|
+
code: ai_matey_errors_1.ErrorCode.PROVIDER_ERROR,
|
|
76
|
+
message: `Gemini request failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
77
|
+
isRetryable: true,
|
|
78
|
+
provenance: { backend: this.metadata.name },
|
|
79
|
+
cause: error instanceof Error ? error : undefined,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async *executeStream(request, signal) {
|
|
84
|
+
try {
|
|
85
|
+
const geminiRequest = this.fromIR(request);
|
|
86
|
+
const model = request.parameters?.model || 'gemini-pro';
|
|
87
|
+
const endpoint = `${this.baseURL}/models/${model}:streamGenerateContent?key=${this.config.apiKey}`;
|
|
88
|
+
// Get effective streaming configuration
|
|
89
|
+
const streamingConfig = (0, ai_matey_utils_2.mergeStreamingConfig)(this.config.streaming);
|
|
90
|
+
const effectiveMode = (0, ai_matey_utils_2.getEffectiveStreamMode)(request.streamMode, undefined, streamingConfig);
|
|
91
|
+
const includeBoth = streamingConfig.includeBoth || effectiveMode === 'accumulated';
|
|
92
|
+
const response = await fetch(endpoint, {
|
|
93
|
+
method: 'POST',
|
|
94
|
+
headers: { 'Content-Type': 'application/json', ...this.config.headers },
|
|
95
|
+
body: JSON.stringify(geminiRequest),
|
|
96
|
+
signal,
|
|
97
|
+
});
|
|
98
|
+
if (!response.ok) {
|
|
99
|
+
const errorBody = await response.text();
|
|
100
|
+
throw (0, ai_matey_errors_1.createErrorFromHttpResponse)(response.status, response.statusText, errorBody, {
|
|
101
|
+
backend: this.metadata.name,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (!response.body) {
|
|
105
|
+
throw new ai_matey_errors_1.StreamError({
|
|
106
|
+
code: ai_matey_errors_1.ErrorCode.STREAM_ERROR,
|
|
107
|
+
message: 'No response body',
|
|
108
|
+
provenance: { backend: this.metadata.name },
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
let sequence = 0;
|
|
112
|
+
yield {
|
|
113
|
+
type: 'start',
|
|
114
|
+
sequence: sequence++,
|
|
115
|
+
metadata: {
|
|
116
|
+
...request.metadata,
|
|
117
|
+
provenance: { ...request.metadata.provenance, backend: this.metadata.name },
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
const reader = response.body.getReader();
|
|
121
|
+
const decoder = new TextDecoder();
|
|
122
|
+
let buffer = '';
|
|
123
|
+
let contentBuffer = '';
|
|
124
|
+
try {
|
|
125
|
+
while (true) {
|
|
126
|
+
const { done, value } = await reader.read();
|
|
127
|
+
if (done) {
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
buffer += decoder.decode(value, { stream: true });
|
|
131
|
+
const lines = buffer.split('\n');
|
|
132
|
+
buffer = lines.pop() || '';
|
|
133
|
+
for (const line of lines) {
|
|
134
|
+
if (!line.trim() || !line.startsWith('data: ')) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const data = line.slice(6).trim();
|
|
138
|
+
try {
|
|
139
|
+
const chunk = JSON.parse(data);
|
|
140
|
+
const candidate = chunk.candidates?.[0];
|
|
141
|
+
if (!candidate) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const content = candidate.content?.parts?.[0];
|
|
145
|
+
if (content && 'text' in content) {
|
|
146
|
+
contentBuffer += content.text;
|
|
147
|
+
// Build content chunk with optional accumulated field
|
|
148
|
+
const contentChunk = {
|
|
149
|
+
type: 'content',
|
|
150
|
+
sequence: sequence++,
|
|
151
|
+
delta: content.text,
|
|
152
|
+
role: 'assistant',
|
|
153
|
+
};
|
|
154
|
+
// Add accumulated field if configured
|
|
155
|
+
if (includeBoth) {
|
|
156
|
+
contentChunk.accumulated = contentBuffer;
|
|
157
|
+
}
|
|
158
|
+
yield contentChunk;
|
|
159
|
+
}
|
|
160
|
+
if (candidate.finishReason) {
|
|
161
|
+
const message = { role: 'assistant', content: contentBuffer };
|
|
162
|
+
yield {
|
|
163
|
+
type: 'done',
|
|
164
|
+
sequence: sequence++,
|
|
165
|
+
finishReason: this.mapFinishReason(candidate.finishReason),
|
|
166
|
+
usage: chunk.usageMetadata
|
|
167
|
+
? {
|
|
168
|
+
promptTokens: chunk.usageMetadata.promptTokenCount,
|
|
169
|
+
completionTokens: chunk.usageMetadata.candidatesTokenCount,
|
|
170
|
+
totalTokens: chunk.usageMetadata.totalTokenCount,
|
|
171
|
+
}
|
|
172
|
+
: undefined,
|
|
173
|
+
message,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch (parseError) {
|
|
178
|
+
console.warn('Failed to parse Gemini SSE chunk:', data, parseError);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
reader.releaseLock();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
yield {
|
|
189
|
+
type: 'error',
|
|
190
|
+
sequence: 0,
|
|
191
|
+
error: {
|
|
192
|
+
code: error instanceof Error ? error.name : 'UNKNOWN_ERROR',
|
|
193
|
+
message: error instanceof Error ? error.message : String(error),
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async healthCheck() {
|
|
199
|
+
try {
|
|
200
|
+
const response = await fetch(`${this.baseURL}/models?key=${this.config.apiKey}`, {
|
|
201
|
+
method: 'GET',
|
|
202
|
+
signal: AbortSignal.timeout(5000),
|
|
203
|
+
});
|
|
204
|
+
return response.ok;
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
estimateCost(_request) {
|
|
211
|
+
return Promise.resolve(null); // Cost estimation not implemented for Gemini
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Convert IR request to Gemini format.
|
|
215
|
+
*
|
|
216
|
+
* Public method for testing and debugging - see what will be sent to Gemini.
|
|
217
|
+
*/
|
|
218
|
+
fromIR(request) {
|
|
219
|
+
const { messages, systemParameter } = (0, ai_matey_utils_1.normalizeSystemMessages)(request.messages, this.metadata.capabilities.systemMessageStrategy, this.metadata.capabilities.supportsMultipleSystemMessages);
|
|
220
|
+
const contents = messages.map((msg) => ({
|
|
221
|
+
role: msg.role === 'assistant' ? 'model' : 'user',
|
|
222
|
+
parts: typeof msg.content === 'string'
|
|
223
|
+
? [{ text: msg.content }]
|
|
224
|
+
: msg.content.map((c) => c.type === 'text' ? { text: c.text } : { text: JSON.stringify(c) }),
|
|
225
|
+
}));
|
|
226
|
+
const systemInstruction = systemParameter ? { parts: [{ text: systemParameter }] } : undefined;
|
|
227
|
+
return {
|
|
228
|
+
contents,
|
|
229
|
+
systemInstruction,
|
|
230
|
+
generationConfig: {
|
|
231
|
+
temperature: request.parameters?.temperature
|
|
232
|
+
? request.parameters.temperature / 2
|
|
233
|
+
: undefined,
|
|
234
|
+
topP: request.parameters?.topP,
|
|
235
|
+
topK: request.parameters?.topK,
|
|
236
|
+
maxOutputTokens: request.parameters?.maxTokens,
|
|
237
|
+
stopSequences: request.parameters?.stopSequences
|
|
238
|
+
? [...request.parameters.stopSequences]
|
|
239
|
+
: undefined,
|
|
240
|
+
},
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Convert Gemini response to IR format.
|
|
245
|
+
*
|
|
246
|
+
* Public method for testing and debugging - parse Gemini responses manually.
|
|
247
|
+
*/
|
|
248
|
+
toIR(response, originalRequest, latencyMs) {
|
|
249
|
+
const candidate = response.candidates[0];
|
|
250
|
+
if (!candidate) {
|
|
251
|
+
throw new ai_matey_errors_1.AdapterConversionError({
|
|
252
|
+
code: ai_matey_errors_1.ErrorCode.ADAPTER_CONVERSION_ERROR,
|
|
253
|
+
message: 'No candidates in Gemini response',
|
|
254
|
+
provenance: { backend: this.metadata.name },
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
const content = candidate.content.parts.map((p) => ('text' in p ? p.text : '')).join('');
|
|
258
|
+
const message = { role: 'assistant', content };
|
|
259
|
+
return {
|
|
260
|
+
message,
|
|
261
|
+
finishReason: this.mapFinishReason(candidate.finishReason),
|
|
262
|
+
usage: response.usageMetadata
|
|
263
|
+
? {
|
|
264
|
+
promptTokens: response.usageMetadata.promptTokenCount,
|
|
265
|
+
completionTokens: response.usageMetadata.candidatesTokenCount,
|
|
266
|
+
totalTokens: response.usageMetadata.totalTokenCount,
|
|
267
|
+
}
|
|
268
|
+
: undefined,
|
|
269
|
+
metadata: {
|
|
270
|
+
...originalRequest.metadata,
|
|
271
|
+
providerResponseId: undefined, // Gemini does not provide a response ID
|
|
272
|
+
provenance: { ...originalRequest.metadata.provenance, backend: this.metadata.name },
|
|
273
|
+
custom: { ...originalRequest.metadata.custom, latencyMs },
|
|
274
|
+
},
|
|
275
|
+
raw: response,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
mapFinishReason(reason) {
|
|
279
|
+
switch (reason) {
|
|
280
|
+
case 'STOP':
|
|
281
|
+
return 'stop';
|
|
282
|
+
case 'MAX_TOKENS':
|
|
283
|
+
return 'length';
|
|
284
|
+
case 'SAFETY':
|
|
285
|
+
return 'content_filter';
|
|
286
|
+
default:
|
|
287
|
+
return 'stop';
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
exports.GeminiBackendAdapter = GeminiBackendAdapter;
|
|
292
|
+
//# sourceMappingURL=gemini.js.map
|