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,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replicate Backend Adapter
|
|
3
|
+
*
|
|
4
|
+
* Adapts Universal IR to Replicate Predictions API.
|
|
5
|
+
* Replicate has per-model API variations and async prediction workflow.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { NetworkError, ProviderError, StreamError, ErrorCode, createErrorFromHttpResponse, } from 'ai.matey.errors';
|
|
10
|
+
import { normalizeSystemMessages } from 'ai.matey.utils';
|
|
11
|
+
import { getEffectiveStreamMode, mergeStreamingConfig } from 'ai.matey.utils';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Replicate Backend Adapter
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Backend adapter for Replicate Predictions API.
|
|
17
|
+
*
|
|
18
|
+
* Features:
|
|
19
|
+
* - Async prediction workflow
|
|
20
|
+
* - Per-model API variations
|
|
21
|
+
* - Limited streaming support
|
|
22
|
+
* - Text-only (vision varies by model)
|
|
23
|
+
* - No function calling
|
|
24
|
+
* - Variable pricing per model
|
|
25
|
+
*
|
|
26
|
+
* Note: This adapter uses a simplified synchronous approach by polling.
|
|
27
|
+
* For production, consider using webhooks or proper async patterns.
|
|
28
|
+
*/
|
|
29
|
+
export class ReplicateBackendAdapter {
|
|
30
|
+
metadata;
|
|
31
|
+
config;
|
|
32
|
+
baseURL;
|
|
33
|
+
maxPollAttempts = 60; // Max 60 attempts (60 seconds)
|
|
34
|
+
pollInterval = 1000; // Poll every 1 second
|
|
35
|
+
constructor(config) {
|
|
36
|
+
this.config = config;
|
|
37
|
+
this.baseURL = config.baseURL || 'https://api.replicate.com/v1';
|
|
38
|
+
this.metadata = {
|
|
39
|
+
name: 'replicate-backend',
|
|
40
|
+
version: '1.0.0',
|
|
41
|
+
provider: 'Replicate',
|
|
42
|
+
capabilities: {
|
|
43
|
+
streaming: true, // Limited streaming support
|
|
44
|
+
multiModal: false, // Varies by model
|
|
45
|
+
tools: false, // No function calling
|
|
46
|
+
maxContextTokens: 4096, // Varies by model
|
|
47
|
+
systemMessageStrategy: 'separate-parameter', // Uses system_prompt
|
|
48
|
+
supportsMultipleSystemMessages: false,
|
|
49
|
+
supportsTemperature: true,
|
|
50
|
+
supportsTopP: true,
|
|
51
|
+
supportsTopK: true,
|
|
52
|
+
supportsSeed: false,
|
|
53
|
+
supportsFrequencyPenalty: false,
|
|
54
|
+
supportsPresencePenalty: false,
|
|
55
|
+
maxStopSequences: 0,
|
|
56
|
+
},
|
|
57
|
+
config: {
|
|
58
|
+
baseURL: this.baseURL,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Convert IR to Replicate format.
|
|
64
|
+
*/
|
|
65
|
+
fromIR(request) {
|
|
66
|
+
const { messages, systemParameter } = normalizeSystemMessages(request.messages, this.metadata.capabilities.systemMessageStrategy, this.metadata.capabilities.supportsMultipleSystemMessages);
|
|
67
|
+
// Build prompt from conversation history
|
|
68
|
+
const prompt = messages
|
|
69
|
+
.map((msg) => {
|
|
70
|
+
const content = typeof msg.content === 'string'
|
|
71
|
+
? msg.content
|
|
72
|
+
: msg.content.map((block) => (block.type === 'text' ? block.text : '')).join('');
|
|
73
|
+
return `${msg.role === 'user' ? 'User' : 'Assistant'}: ${content}`;
|
|
74
|
+
})
|
|
75
|
+
.join('\n\n');
|
|
76
|
+
const input = {
|
|
77
|
+
prompt,
|
|
78
|
+
temperature: request.parameters?.temperature,
|
|
79
|
+
max_tokens: request.parameters?.maxTokens,
|
|
80
|
+
top_p: request.parameters?.topP,
|
|
81
|
+
top_k: request.parameters?.topK,
|
|
82
|
+
};
|
|
83
|
+
// Add system prompt
|
|
84
|
+
if (systemParameter) {
|
|
85
|
+
input.system_prompt =
|
|
86
|
+
typeof systemParameter === 'string'
|
|
87
|
+
? systemParameter
|
|
88
|
+
: systemParameter
|
|
89
|
+
.map((msg) => (msg.type === 'text' ? msg.text : ''))
|
|
90
|
+
.join('');
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
version: request.parameters?.model || this.config.defaultModel || 'meta/llama-2-70b-chat:latest',
|
|
94
|
+
input,
|
|
95
|
+
stream: request.stream || false,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Convert Replicate prediction to IR.
|
|
100
|
+
*/
|
|
101
|
+
toIR(prediction, originalRequest, latencyMs) {
|
|
102
|
+
let content = '';
|
|
103
|
+
if (typeof prediction.output === 'string') {
|
|
104
|
+
content = prediction.output;
|
|
105
|
+
}
|
|
106
|
+
else if (Array.isArray(prediction.output)) {
|
|
107
|
+
content = prediction.output.join('');
|
|
108
|
+
}
|
|
109
|
+
const message = {
|
|
110
|
+
role: 'assistant',
|
|
111
|
+
content,
|
|
112
|
+
};
|
|
113
|
+
const finishReasonMap = {
|
|
114
|
+
succeeded: 'stop',
|
|
115
|
+
failed: 'stop',
|
|
116
|
+
canceled: 'stop',
|
|
117
|
+
};
|
|
118
|
+
return {
|
|
119
|
+
message,
|
|
120
|
+
finishReason: finishReasonMap[prediction.status] || 'stop',
|
|
121
|
+
usage: undefined, // Replicate doesn't provide token counts
|
|
122
|
+
metadata: {
|
|
123
|
+
...originalRequest.metadata,
|
|
124
|
+
providerResponseId: prediction.id,
|
|
125
|
+
provenance: {
|
|
126
|
+
...originalRequest.metadata.provenance,
|
|
127
|
+
backend: this.metadata.name,
|
|
128
|
+
},
|
|
129
|
+
custom: {
|
|
130
|
+
...originalRequest.metadata.custom,
|
|
131
|
+
latencyMs: prediction.metrics?.predict_time
|
|
132
|
+
? prediction.metrics.predict_time * 1000
|
|
133
|
+
: latencyMs,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
raw: prediction,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Execute non-streaming request.
|
|
141
|
+
* Uses polling to wait for async prediction.
|
|
142
|
+
*/
|
|
143
|
+
async execute(request, signal) {
|
|
144
|
+
try {
|
|
145
|
+
const replicateRequest = this.fromIR(request);
|
|
146
|
+
const startTime = Date.now();
|
|
147
|
+
// Create prediction
|
|
148
|
+
const createResponse = await fetch(`${this.baseURL}/predictions`, {
|
|
149
|
+
method: 'POST',
|
|
150
|
+
headers: this.getHeaders(),
|
|
151
|
+
body: JSON.stringify(replicateRequest),
|
|
152
|
+
signal,
|
|
153
|
+
});
|
|
154
|
+
if (!createResponse.ok) {
|
|
155
|
+
throw createErrorFromHttpResponse(createResponse.status, createResponse.statusText, await createResponse.text(), { backend: this.metadata.name });
|
|
156
|
+
}
|
|
157
|
+
let prediction = (await createResponse.json());
|
|
158
|
+
// Poll for completion
|
|
159
|
+
let attempts = 0;
|
|
160
|
+
while (prediction.status !== 'succeeded' &&
|
|
161
|
+
prediction.status !== 'failed' &&
|
|
162
|
+
prediction.status !== 'canceled' &&
|
|
163
|
+
attempts < this.maxPollAttempts) {
|
|
164
|
+
await new Promise((resolve) => setTimeout(resolve, this.pollInterval));
|
|
165
|
+
const pollResponse = await fetch(prediction.urls.get, {
|
|
166
|
+
method: 'GET',
|
|
167
|
+
headers: this.getHeaders(),
|
|
168
|
+
signal,
|
|
169
|
+
});
|
|
170
|
+
if (!pollResponse.ok) {
|
|
171
|
+
throw createErrorFromHttpResponse(pollResponse.status, pollResponse.statusText, await pollResponse.text(), { backend: this.metadata.name });
|
|
172
|
+
}
|
|
173
|
+
prediction = (await pollResponse.json());
|
|
174
|
+
attempts++;
|
|
175
|
+
}
|
|
176
|
+
if (prediction.status === 'failed') {
|
|
177
|
+
throw new ProviderError({
|
|
178
|
+
code: ErrorCode.PROVIDER_ERROR,
|
|
179
|
+
message: `Replicate prediction failed: ${prediction.error || 'Unknown error'}`,
|
|
180
|
+
isRetryable: false,
|
|
181
|
+
provenance: { backend: this.metadata.name },
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
if (attempts >= this.maxPollAttempts) {
|
|
185
|
+
throw new ProviderError({
|
|
186
|
+
code: ErrorCode.PROVIDER_ERROR,
|
|
187
|
+
message: 'Replicate prediction timed out',
|
|
188
|
+
isRetryable: true,
|
|
189
|
+
provenance: { backend: this.metadata.name },
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return this.toIR(prediction, request, Date.now() - startTime);
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
if (error instanceof NetworkError || error instanceof ProviderError) {
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
throw new ProviderError({
|
|
199
|
+
code: ErrorCode.PROVIDER_ERROR,
|
|
200
|
+
message: `Replicate request failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
201
|
+
isRetryable: true,
|
|
202
|
+
provenance: { backend: this.metadata.name },
|
|
203
|
+
cause: error instanceof Error ? error : undefined,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Execute streaming request.
|
|
209
|
+
* Replicate streaming is limited and varies by model.
|
|
210
|
+
*/
|
|
211
|
+
async *executeStream(request, signal) {
|
|
212
|
+
try {
|
|
213
|
+
const replicateRequest = this.fromIR(request);
|
|
214
|
+
replicateRequest.stream = true;
|
|
215
|
+
const streamingConfig = mergeStreamingConfig(this.config.streaming);
|
|
216
|
+
const effectiveMode = getEffectiveStreamMode(request.streamMode, undefined, streamingConfig);
|
|
217
|
+
const includeBoth = streamingConfig.includeBoth || effectiveMode === 'accumulated';
|
|
218
|
+
const response = await fetch(`${this.baseURL}/predictions`, {
|
|
219
|
+
method: 'POST',
|
|
220
|
+
headers: {
|
|
221
|
+
...this.getHeaders(),
|
|
222
|
+
Prefer: 'wait', // Request streaming
|
|
223
|
+
},
|
|
224
|
+
body: JSON.stringify(replicateRequest),
|
|
225
|
+
signal,
|
|
226
|
+
});
|
|
227
|
+
if (!response.ok) {
|
|
228
|
+
throw createErrorFromHttpResponse(response.status, response.statusText, await response.text(), { backend: this.metadata.name });
|
|
229
|
+
}
|
|
230
|
+
if (!response.body) {
|
|
231
|
+
throw new StreamError({
|
|
232
|
+
code: ErrorCode.STREAM_ERROR,
|
|
233
|
+
message: 'No response body',
|
|
234
|
+
provenance: { backend: this.metadata.name },
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
let sequence = 0;
|
|
238
|
+
let contentBuffer = '';
|
|
239
|
+
yield {
|
|
240
|
+
type: 'start',
|
|
241
|
+
sequence: sequence++,
|
|
242
|
+
metadata: {
|
|
243
|
+
...request.metadata,
|
|
244
|
+
provenance: {
|
|
245
|
+
...request.metadata.provenance,
|
|
246
|
+
backend: this.metadata.name,
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
const reader = response.body.getReader();
|
|
251
|
+
const decoder = new TextDecoder();
|
|
252
|
+
let buffer = '';
|
|
253
|
+
try {
|
|
254
|
+
while (true) {
|
|
255
|
+
const { done, value } = await reader.read();
|
|
256
|
+
if (done) {
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
buffer += decoder.decode(value, { stream: true });
|
|
260
|
+
// Replicate streams raw output text
|
|
261
|
+
if (buffer) {
|
|
262
|
+
const delta = buffer;
|
|
263
|
+
buffer = '';
|
|
264
|
+
contentBuffer += delta;
|
|
265
|
+
const contentChunk = {
|
|
266
|
+
type: 'content',
|
|
267
|
+
sequence: sequence++,
|
|
268
|
+
delta: delta,
|
|
269
|
+
role: 'assistant',
|
|
270
|
+
};
|
|
271
|
+
if (includeBoth) {
|
|
272
|
+
contentChunk.accumulated = contentBuffer;
|
|
273
|
+
}
|
|
274
|
+
yield contentChunk;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Stream ended
|
|
278
|
+
yield {
|
|
279
|
+
type: 'done',
|
|
280
|
+
sequence: sequence++,
|
|
281
|
+
finishReason: 'stop',
|
|
282
|
+
message: { role: 'assistant', content: contentBuffer },
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
finally {
|
|
286
|
+
reader.releaseLock();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
yield {
|
|
291
|
+
type: 'error',
|
|
292
|
+
sequence: 0,
|
|
293
|
+
error: {
|
|
294
|
+
code: error instanceof Error ? error.name : 'UNKNOWN_ERROR',
|
|
295
|
+
message: error instanceof Error ? error.message : String(error),
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Get HTTP headers.
|
|
302
|
+
*/
|
|
303
|
+
getHeaders() {
|
|
304
|
+
const headers = {
|
|
305
|
+
'Content-Type': 'application/json',
|
|
306
|
+
Authorization: `Token ${this.config.apiKey}`,
|
|
307
|
+
};
|
|
308
|
+
return { ...headers, ...this.config.headers };
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Health check.
|
|
312
|
+
*/
|
|
313
|
+
async healthCheck() {
|
|
314
|
+
try {
|
|
315
|
+
const response = await fetch(`${this.baseURL}/models`, {
|
|
316
|
+
method: 'GET',
|
|
317
|
+
headers: this.getHeaders(),
|
|
318
|
+
signal: AbortSignal.timeout(5000),
|
|
319
|
+
});
|
|
320
|
+
return response.ok;
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Estimate cost.
|
|
328
|
+
* Replicate pricing varies significantly per model.
|
|
329
|
+
*/
|
|
330
|
+
estimateCost(_request) {
|
|
331
|
+
// Replicate pricing is complex and per-second, not per-token
|
|
332
|
+
// Returning null as cost estimation is not reliable
|
|
333
|
+
return Promise.resolve(null);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
//# sourceMappingURL=replicate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replicate.js","sourceRoot":"","sources":["../../../src/providers/replicate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Together AI Backend Adapter
|
|
3
|
+
*
|
|
4
|
+
* Adapts Universal IR to Together AI Chat Completions API.
|
|
5
|
+
* Together AI is OpenAI-compatible with 200+ open-source models.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { NetworkError, ProviderError, StreamError, ErrorCode, createErrorFromHttpResponse, } from 'ai.matey.errors';
|
|
10
|
+
import { normalizeSystemMessages } from 'ai.matey.utils';
|
|
11
|
+
import { getEffectiveStreamMode, mergeStreamingConfig } from 'ai.matey.utils';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Together AI Backend Adapter
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Backend adapter for Together AI Chat Completions API.
|
|
17
|
+
*
|
|
18
|
+
* Features:
|
|
19
|
+
* - 200+ open-source models
|
|
20
|
+
* - OpenAI-compatible API
|
|
21
|
+
* - Vision model support
|
|
22
|
+
* - Function calling support
|
|
23
|
+
* - Budget pricing starting at $0.06 per 1M tokens
|
|
24
|
+
*/
|
|
25
|
+
export class TogetherAIBackendAdapter {
|
|
26
|
+
metadata;
|
|
27
|
+
config;
|
|
28
|
+
baseURL;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.config = config;
|
|
31
|
+
this.baseURL = config.baseURL || 'https://api.together.xyz/v1';
|
|
32
|
+
this.metadata = {
|
|
33
|
+
name: 'together-ai-backend',
|
|
34
|
+
version: '1.0.0',
|
|
35
|
+
provider: 'Together AI',
|
|
36
|
+
capabilities: {
|
|
37
|
+
streaming: true,
|
|
38
|
+
multiModal: true, // Vision models available
|
|
39
|
+
tools: true, // Function calling
|
|
40
|
+
maxContextTokens: 128000,
|
|
41
|
+
systemMessageStrategy: 'in-messages',
|
|
42
|
+
supportsMultipleSystemMessages: true,
|
|
43
|
+
supportsTemperature: true,
|
|
44
|
+
supportsTopP: true,
|
|
45
|
+
supportsTopK: false,
|
|
46
|
+
supportsSeed: false,
|
|
47
|
+
supportsFrequencyPenalty: true,
|
|
48
|
+
supportsPresencePenalty: true,
|
|
49
|
+
maxStopSequences: 4,
|
|
50
|
+
},
|
|
51
|
+
config: {
|
|
52
|
+
baseURL: this.baseURL,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Convert IR to Together AI format.
|
|
58
|
+
*/
|
|
59
|
+
fromIR(request) {
|
|
60
|
+
const { messages } = normalizeSystemMessages(request.messages, this.metadata.capabilities.systemMessageStrategy, this.metadata.capabilities.supportsMultipleSystemMessages);
|
|
61
|
+
const togetherMessages = messages.map((msg) => ({
|
|
62
|
+
role: msg.role,
|
|
63
|
+
content: typeof msg.content === 'string'
|
|
64
|
+
? msg.content
|
|
65
|
+
: msg.content.map((block) => {
|
|
66
|
+
if (block.type === 'text') {
|
|
67
|
+
return { type: 'text', text: block.text };
|
|
68
|
+
}
|
|
69
|
+
else if (block.type === 'image') {
|
|
70
|
+
return {
|
|
71
|
+
type: 'image_url',
|
|
72
|
+
image_url: {
|
|
73
|
+
url: block.source.type === 'url'
|
|
74
|
+
? block.source.url
|
|
75
|
+
: `data:${block.source.mediaType};base64,${block.source.data}`,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return { type: 'text', text: JSON.stringify(block) };
|
|
80
|
+
}),
|
|
81
|
+
}));
|
|
82
|
+
return {
|
|
83
|
+
model: request.parameters?.model ||
|
|
84
|
+
this.config.defaultModel ||
|
|
85
|
+
'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo',
|
|
86
|
+
messages: togetherMessages,
|
|
87
|
+
temperature: request.parameters?.temperature,
|
|
88
|
+
max_tokens: request.parameters?.maxTokens,
|
|
89
|
+
top_p: request.parameters?.topP,
|
|
90
|
+
frequency_penalty: request.parameters?.frequencyPenalty,
|
|
91
|
+
presence_penalty: request.parameters?.presencePenalty,
|
|
92
|
+
stop: request.parameters?.stopSequences ? [...request.parameters.stopSequences] : undefined,
|
|
93
|
+
stream: request.stream || false,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Convert Together AI response to IR.
|
|
98
|
+
*/
|
|
99
|
+
toIR(response, originalRequest, latencyMs) {
|
|
100
|
+
const choice = response.choices[0];
|
|
101
|
+
if (!choice) {
|
|
102
|
+
throw new ProviderError({
|
|
103
|
+
code: ErrorCode.PROVIDER_ERROR,
|
|
104
|
+
message: 'No choices returned in response',
|
|
105
|
+
isRetryable: false,
|
|
106
|
+
provenance: { backend: this.metadata.name },
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
const message = {
|
|
110
|
+
role: choice.message.role === 'assistant' ? 'assistant' : 'user',
|
|
111
|
+
content: typeof choice.message.content === 'string'
|
|
112
|
+
? choice.message.content
|
|
113
|
+
: choice.message.content.map((c) => (c.type === 'text' ? c.text : '')).join(''),
|
|
114
|
+
};
|
|
115
|
+
const finishReasonMap = {
|
|
116
|
+
stop: 'stop',
|
|
117
|
+
length: 'length',
|
|
118
|
+
tool_calls: 'tool_calls',
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
message,
|
|
122
|
+
finishReason: finishReasonMap[choice.finish_reason || 'stop'] || 'stop',
|
|
123
|
+
usage: response.usage
|
|
124
|
+
? {
|
|
125
|
+
promptTokens: response.usage.prompt_tokens,
|
|
126
|
+
completionTokens: response.usage.completion_tokens,
|
|
127
|
+
totalTokens: response.usage.total_tokens,
|
|
128
|
+
}
|
|
129
|
+
: undefined,
|
|
130
|
+
metadata: {
|
|
131
|
+
...originalRequest.metadata,
|
|
132
|
+
providerResponseId: response.id,
|
|
133
|
+
provenance: {
|
|
134
|
+
...originalRequest.metadata.provenance,
|
|
135
|
+
backend: this.metadata.name,
|
|
136
|
+
},
|
|
137
|
+
custom: {
|
|
138
|
+
...originalRequest.metadata.custom,
|
|
139
|
+
latencyMs,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
raw: response,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Execute non-streaming request.
|
|
147
|
+
*/
|
|
148
|
+
async execute(request, signal) {
|
|
149
|
+
try {
|
|
150
|
+
const togetherRequest = this.fromIR(request);
|
|
151
|
+
togetherRequest.stream = false;
|
|
152
|
+
const startTime = Date.now();
|
|
153
|
+
const response = await fetch(`${this.baseURL}/chat/completions`, {
|
|
154
|
+
method: 'POST',
|
|
155
|
+
headers: this.getHeaders(),
|
|
156
|
+
body: JSON.stringify(togetherRequest),
|
|
157
|
+
signal,
|
|
158
|
+
});
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
throw createErrorFromHttpResponse(response.status, response.statusText, await response.text(), { backend: this.metadata.name });
|
|
161
|
+
}
|
|
162
|
+
const data = (await response.json());
|
|
163
|
+
return this.toIR(data, request, Date.now() - startTime);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
if (error instanceof NetworkError || error instanceof ProviderError) {
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
throw new ProviderError({
|
|
170
|
+
code: ErrorCode.PROVIDER_ERROR,
|
|
171
|
+
message: `Together AI request failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
172
|
+
isRetryable: true,
|
|
173
|
+
provenance: { backend: this.metadata.name },
|
|
174
|
+
cause: error instanceof Error ? error : undefined,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Execute streaming request.
|
|
180
|
+
*/
|
|
181
|
+
async *executeStream(request, signal) {
|
|
182
|
+
try {
|
|
183
|
+
const togetherRequest = this.fromIR(request);
|
|
184
|
+
togetherRequest.stream = true;
|
|
185
|
+
const streamingConfig = mergeStreamingConfig(this.config.streaming);
|
|
186
|
+
const effectiveMode = getEffectiveStreamMode(request.streamMode, undefined, streamingConfig);
|
|
187
|
+
const includeBoth = streamingConfig.includeBoth || effectiveMode === 'accumulated';
|
|
188
|
+
const response = await fetch(`${this.baseURL}/chat/completions`, {
|
|
189
|
+
method: 'POST',
|
|
190
|
+
headers: this.getHeaders(),
|
|
191
|
+
body: JSON.stringify(togetherRequest),
|
|
192
|
+
signal,
|
|
193
|
+
});
|
|
194
|
+
if (!response.ok) {
|
|
195
|
+
throw createErrorFromHttpResponse(response.status, response.statusText, await response.text(), { backend: this.metadata.name });
|
|
196
|
+
}
|
|
197
|
+
if (!response.body) {
|
|
198
|
+
throw new StreamError({
|
|
199
|
+
code: ErrorCode.STREAM_ERROR,
|
|
200
|
+
message: 'No response body',
|
|
201
|
+
provenance: { backend: this.metadata.name },
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
let sequence = 0;
|
|
205
|
+
let contentBuffer = '';
|
|
206
|
+
yield {
|
|
207
|
+
type: 'start',
|
|
208
|
+
sequence: sequence++,
|
|
209
|
+
metadata: {
|
|
210
|
+
...request.metadata,
|
|
211
|
+
provenance: {
|
|
212
|
+
...request.metadata.provenance,
|
|
213
|
+
backend: this.metadata.name,
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
const reader = response.body.getReader();
|
|
218
|
+
const decoder = new TextDecoder();
|
|
219
|
+
let buffer = '';
|
|
220
|
+
try {
|
|
221
|
+
while (true) {
|
|
222
|
+
const { done, value } = await reader.read();
|
|
223
|
+
if (done) {
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
buffer += decoder.decode(value, { stream: true });
|
|
227
|
+
const lines = buffer.split('\n');
|
|
228
|
+
buffer = lines.pop() || '';
|
|
229
|
+
for (const line of lines) {
|
|
230
|
+
if (!line.trim() || !line.startsWith('data: ')) {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const data = line.slice(6).trim();
|
|
234
|
+
if (data === '[DONE]') {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
const chunk = JSON.parse(data);
|
|
239
|
+
const delta = chunk.choices[0]?.delta?.content;
|
|
240
|
+
if (delta) {
|
|
241
|
+
contentBuffer += delta;
|
|
242
|
+
const contentChunk = {
|
|
243
|
+
type: 'content',
|
|
244
|
+
sequence: sequence++,
|
|
245
|
+
delta: delta,
|
|
246
|
+
role: 'assistant',
|
|
247
|
+
};
|
|
248
|
+
if (includeBoth) {
|
|
249
|
+
contentChunk.accumulated = contentBuffer;
|
|
250
|
+
}
|
|
251
|
+
yield contentChunk;
|
|
252
|
+
}
|
|
253
|
+
if (chunk.choices[0]?.finish_reason) {
|
|
254
|
+
const finishReasonMap = {
|
|
255
|
+
stop: 'stop',
|
|
256
|
+
length: 'length',
|
|
257
|
+
};
|
|
258
|
+
yield {
|
|
259
|
+
type: 'done',
|
|
260
|
+
sequence: sequence++,
|
|
261
|
+
finishReason: finishReasonMap[chunk.choices[0].finish_reason] || 'stop',
|
|
262
|
+
message: { role: 'assistant', content: contentBuffer },
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch (parseError) {
|
|
267
|
+
console.warn('Failed to parse SSE chunk:', data, parseError);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
reader.releaseLock();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
yield {
|
|
278
|
+
type: 'error',
|
|
279
|
+
sequence: 0,
|
|
280
|
+
error: {
|
|
281
|
+
code: error instanceof Error ? error.name : 'UNKNOWN_ERROR',
|
|
282
|
+
message: error instanceof Error ? error.message : String(error),
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Get HTTP headers.
|
|
289
|
+
*/
|
|
290
|
+
getHeaders() {
|
|
291
|
+
const headers = {
|
|
292
|
+
'Content-Type': 'application/json',
|
|
293
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
294
|
+
};
|
|
295
|
+
return { ...headers, ...this.config.headers };
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Health check.
|
|
299
|
+
*/
|
|
300
|
+
async healthCheck() {
|
|
301
|
+
try {
|
|
302
|
+
const response = await fetch(`${this.baseURL}/models`, {
|
|
303
|
+
method: 'GET',
|
|
304
|
+
headers: this.getHeaders(),
|
|
305
|
+
signal: AbortSignal.timeout(5000),
|
|
306
|
+
});
|
|
307
|
+
return response.ok;
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Estimate cost.
|
|
315
|
+
*/
|
|
316
|
+
estimateCost(request) {
|
|
317
|
+
const pricing = {
|
|
318
|
+
'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo': { input: 0.1, output: 0.1 },
|
|
319
|
+
'meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo': { input: 0.88, output: 0.88 },
|
|
320
|
+
'meta-llama/Llama-4-Scout-17B-16E-Instruct': { input: 0.2, output: 0.2 },
|
|
321
|
+
};
|
|
322
|
+
const model = request.parameters?.model || this.config.defaultModel || '';
|
|
323
|
+
const modelPricing = pricing[model];
|
|
324
|
+
if (!modelPricing) {
|
|
325
|
+
return Promise.resolve(null);
|
|
326
|
+
}
|
|
327
|
+
const inputTokens = request.messages.reduce((sum, msg) => {
|
|
328
|
+
const content = typeof msg.content === 'string' ? msg.content : '';
|
|
329
|
+
return sum + Math.ceil(content.length / 4);
|
|
330
|
+
}, 0);
|
|
331
|
+
const outputTokens = request.parameters?.maxTokens || 1024;
|
|
332
|
+
const inputCost = (inputTokens / 1_000_000) * modelPricing.input;
|
|
333
|
+
const outputCost = (outputTokens / 1_000_000) * modelPricing.output;
|
|
334
|
+
return Promise.resolve(inputCost + outputCost);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=together-ai.js.map
|