@llumiverse/drivers 1.0.0-dev.20260202.145450Z → 1.0.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/lib/cjs/adobe/firefly.js +120 -0
- package/lib/cjs/adobe/firefly.js.map +1 -0
- package/lib/cjs/azure/azure_foundry.js +432 -0
- package/lib/cjs/azure/azure_foundry.js.map +1 -0
- package/lib/cjs/bedrock/converse.js +359 -0
- package/lib/cjs/bedrock/converse.js.map +1 -0
- package/lib/cjs/bedrock/index.js +1441 -0
- package/lib/cjs/bedrock/index.js.map +1 -0
- package/lib/cjs/bedrock/nova-image-payload.js +207 -0
- package/lib/cjs/bedrock/nova-image-payload.js.map +1 -0
- package/lib/cjs/bedrock/payloads.js +3 -0
- package/lib/cjs/bedrock/payloads.js.map +1 -0
- package/lib/cjs/bedrock/s3.js +107 -0
- package/lib/cjs/bedrock/s3.js.map +1 -0
- package/lib/cjs/bedrock/twelvelabs.js +87 -0
- package/lib/cjs/bedrock/twelvelabs.js.map +1 -0
- package/lib/cjs/groq/index.js +326 -0
- package/lib/cjs/groq/index.js.map +1 -0
- package/lib/cjs/huggingface_ie.js +201 -0
- package/lib/cjs/huggingface_ie.js.map +1 -0
- package/lib/cjs/index.js +31 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/mistral/index.js +176 -0
- package/lib/cjs/mistral/index.js.map +1 -0
- package/lib/cjs/mistral/types.js +83 -0
- package/lib/cjs/mistral/types.js.map +1 -0
- package/lib/cjs/openai/azure_openai.js +72 -0
- package/lib/cjs/openai/azure_openai.js.map +1 -0
- package/lib/cjs/openai/index.js +1100 -0
- package/lib/cjs/openai/index.js.map +1 -0
- package/lib/cjs/openai/openai.js +21 -0
- package/lib/cjs/openai/openai.js.map +1 -0
- package/lib/cjs/openai/openai_compatible.js +63 -0
- package/lib/cjs/openai/openai_compatible.js.map +1 -0
- package/lib/cjs/openai/openai_format.js +131 -0
- package/lib/cjs/openai/openai_format.js.map +1 -0
- package/lib/cjs/package.json +3 -0
- package/lib/cjs/replicate.js +275 -0
- package/lib/cjs/replicate.js.map +1 -0
- package/lib/cjs/test-driver/TestErrorCompletionStream.js +20 -0
- package/lib/cjs/test-driver/TestErrorCompletionStream.js.map +1 -0
- package/lib/cjs/test-driver/TestValidationErrorCompletionStream.js +24 -0
- package/lib/cjs/test-driver/TestValidationErrorCompletionStream.js.map +1 -0
- package/lib/cjs/test-driver/index.js +109 -0
- package/lib/cjs/test-driver/index.js.map +1 -0
- package/lib/cjs/test-driver/utils.js +30 -0
- package/lib/cjs/test-driver/utils.js.map +1 -0
- package/lib/cjs/togetherai/index.js +126 -0
- package/lib/cjs/togetherai/index.js.map +1 -0
- package/lib/cjs/togetherai/interfaces.js +3 -0
- package/lib/cjs/togetherai/interfaces.js.map +1 -0
- package/lib/cjs/vertexai/debug.js +12 -0
- package/lib/cjs/vertexai/debug.js.map +1 -0
- package/lib/cjs/vertexai/embeddings/embeddings-image.js +27 -0
- package/lib/cjs/vertexai/embeddings/embeddings-image.js.map +1 -0
- package/lib/cjs/vertexai/embeddings/embeddings-text.js +23 -0
- package/lib/cjs/vertexai/embeddings/embeddings-text.js.map +1 -0
- package/lib/cjs/vertexai/index.js +635 -0
- package/lib/cjs/vertexai/index.js.map +1 -0
- package/lib/cjs/vertexai/models/claude.js +842 -0
- package/lib/cjs/vertexai/models/claude.js.map +1 -0
- package/lib/cjs/vertexai/models/gemini.js +1110 -0
- package/lib/cjs/vertexai/models/gemini.js.map +1 -0
- package/lib/cjs/vertexai/models/imagen.js +303 -0
- package/lib/cjs/vertexai/models/imagen.js.map +1 -0
- package/lib/cjs/vertexai/models/llama.js +183 -0
- package/lib/cjs/vertexai/models/llama.js.map +1 -0
- package/lib/cjs/vertexai/models.js +35 -0
- package/lib/cjs/vertexai/models.js.map +1 -0
- package/lib/cjs/watsonx/index.js +161 -0
- package/lib/cjs/watsonx/index.js.map +1 -0
- package/lib/cjs/watsonx/interfaces.js +3 -0
- package/lib/cjs/watsonx/interfaces.js.map +1 -0
- package/lib/cjs/xai/index.js +65 -0
- package/lib/cjs/xai/index.js.map +1 -0
- package/lib/esm/adobe/firefly.js +116 -0
- package/lib/esm/adobe/firefly.js.map +1 -0
- package/lib/esm/azure/azure_foundry.js +426 -0
- package/lib/esm/azure/azure_foundry.js.map +1 -0
- package/lib/esm/bedrock/converse.js +352 -0
- package/lib/esm/bedrock/converse.js.map +1 -0
- package/lib/esm/bedrock/index.js +1434 -0
- package/lib/esm/bedrock/index.js.map +1 -0
- package/lib/esm/bedrock/nova-image-payload.js +203 -0
- package/lib/esm/bedrock/nova-image-payload.js.map +1 -0
- package/lib/esm/bedrock/payloads.js +2 -0
- package/lib/esm/bedrock/payloads.js.map +1 -0
- package/lib/esm/bedrock/s3.js +99 -0
- package/lib/esm/bedrock/s3.js.map +1 -0
- package/lib/esm/bedrock/twelvelabs.js +84 -0
- package/lib/esm/bedrock/twelvelabs.js.map +1 -0
- package/lib/esm/groq/index.js +319 -0
- package/lib/esm/groq/index.js.map +1 -0
- package/lib/esm/huggingface_ie.js +197 -0
- package/lib/esm/huggingface_ie.js.map +1 -0
- package/lib/esm/index.js +15 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/mistral/index.js +172 -0
- package/lib/esm/mistral/index.js.map +1 -0
- package/lib/esm/mistral/types.js +80 -0
- package/lib/esm/mistral/types.js.map +1 -0
- package/lib/esm/openai/azure_openai.js +68 -0
- package/lib/esm/openai/azure_openai.js.map +1 -0
- package/lib/esm/openai/index.js +1093 -0
- package/lib/esm/openai/index.js.map +1 -0
- package/lib/esm/openai/openai.js +14 -0
- package/lib/esm/openai/openai.js.map +1 -0
- package/lib/esm/openai/openai_compatible.js +56 -0
- package/lib/esm/openai/openai_compatible.js.map +1 -0
- package/lib/esm/openai/openai_format.js +127 -0
- package/lib/esm/openai/openai_format.js.map +1 -0
- package/lib/esm/replicate.js +268 -0
- package/lib/esm/replicate.js.map +1 -0
- package/lib/esm/test-driver/TestErrorCompletionStream.js +16 -0
- package/lib/esm/test-driver/TestErrorCompletionStream.js.map +1 -0
- package/lib/esm/test-driver/TestValidationErrorCompletionStream.js +20 -0
- package/lib/esm/test-driver/TestValidationErrorCompletionStream.js.map +1 -0
- package/lib/esm/test-driver/index.js +91 -0
- package/lib/esm/test-driver/index.js.map +1 -0
- package/lib/esm/test-driver/utils.js +25 -0
- package/lib/esm/test-driver/utils.js.map +1 -0
- package/lib/esm/togetherai/index.js +122 -0
- package/lib/esm/togetherai/index.js.map +1 -0
- package/lib/esm/togetherai/interfaces.js +2 -0
- package/lib/esm/togetherai/interfaces.js.map +1 -0
- package/lib/esm/vertexai/debug.js +6 -0
- package/lib/esm/vertexai/debug.js.map +1 -0
- package/lib/esm/vertexai/embeddings/embeddings-image.js +24 -0
- package/lib/esm/vertexai/embeddings/embeddings-image.js.map +1 -0
- package/lib/esm/vertexai/embeddings/embeddings-text.js +20 -0
- package/lib/esm/vertexai/embeddings/embeddings-text.js.map +1 -0
- package/lib/esm/vertexai/index.js +630 -0
- package/lib/esm/vertexai/index.js.map +1 -0
- package/lib/esm/vertexai/models/claude.js +833 -0
- package/lib/esm/vertexai/models/claude.js.map +1 -0
- package/lib/esm/vertexai/models/gemini.js +1104 -0
- package/lib/esm/vertexai/models/gemini.js.map +1 -0
- package/lib/esm/vertexai/models/imagen.js +299 -0
- package/lib/esm/vertexai/models/imagen.js.map +1 -0
- package/lib/esm/vertexai/models/llama.js +179 -0
- package/lib/esm/vertexai/models/llama.js.map +1 -0
- package/lib/esm/vertexai/models.js +32 -0
- package/lib/esm/vertexai/models.js.map +1 -0
- package/lib/esm/watsonx/index.js +157 -0
- package/lib/esm/watsonx/index.js.map +1 -0
- package/lib/esm/watsonx/interfaces.js +2 -0
- package/lib/esm/watsonx/interfaces.js.map +1 -0
- package/lib/esm/xai/index.js +58 -0
- package/lib/esm/xai/index.js.map +1 -0
- package/lib/types/adobe/firefly.d.ts +30 -0
- package/lib/types/adobe/firefly.d.ts.map +1 -0
- package/lib/types/azure/azure_foundry.d.ts +52 -0
- package/lib/types/azure/azure_foundry.d.ts.map +1 -0
- package/lib/types/bedrock/converse.d.ts +8 -0
- package/lib/types/bedrock/converse.d.ts.map +1 -0
- package/lib/types/bedrock/index.d.ts +135 -0
- package/lib/types/bedrock/index.d.ts.map +1 -0
- package/lib/types/bedrock/nova-image-payload.d.ts +74 -0
- package/lib/types/bedrock/nova-image-payload.d.ts.map +1 -0
- package/lib/types/bedrock/payloads.d.ts +12 -0
- package/lib/types/bedrock/payloads.d.ts.map +1 -0
- package/lib/types/bedrock/s3.d.ts +23 -0
- package/lib/types/bedrock/s3.d.ts.map +1 -0
- package/lib/types/bedrock/twelvelabs.d.ts +50 -0
- package/lib/types/bedrock/twelvelabs.d.ts.map +1 -0
- package/lib/types/groq/index.d.ts +27 -0
- package/lib/types/groq/index.d.ts.map +1 -0
- package/lib/types/huggingface_ie.d.ts +35 -0
- package/lib/types/huggingface_ie.d.ts.map +1 -0
- package/lib/types/index.d.ts +15 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/mistral/index.d.ts +25 -0
- package/lib/types/mistral/index.d.ts.map +1 -0
- package/lib/types/mistral/types.d.ts +127 -0
- package/lib/types/mistral/types.d.ts.map +1 -0
- package/lib/types/openai/azure_openai.d.ts +25 -0
- package/lib/types/openai/azure_openai.d.ts.map +1 -0
- package/lib/types/openai/index.d.ts +126 -0
- package/lib/types/openai/index.d.ts.map +1 -0
- package/lib/types/openai/openai.d.ts +15 -0
- package/lib/types/openai/openai.d.ts.map +1 -0
- package/lib/types/openai/openai_compatible.d.ts +31 -0
- package/lib/types/openai/openai_compatible.d.ts.map +1 -0
- package/lib/types/openai/openai_format.d.ts +21 -0
- package/lib/types/openai/openai_format.d.ts.map +1 -0
- package/lib/types/replicate.d.ts +48 -0
- package/lib/types/replicate.d.ts.map +1 -0
- package/lib/types/test-driver/TestErrorCompletionStream.d.ts +9 -0
- package/lib/types/test-driver/TestErrorCompletionStream.d.ts.map +1 -0
- package/lib/types/test-driver/TestValidationErrorCompletionStream.d.ts +9 -0
- package/lib/types/test-driver/TestValidationErrorCompletionStream.d.ts.map +1 -0
- package/lib/types/test-driver/index.d.ts +24 -0
- package/lib/types/test-driver/index.d.ts.map +1 -0
- package/lib/types/test-driver/utils.d.ts +5 -0
- package/lib/types/test-driver/utils.d.ts.map +1 -0
- package/lib/types/togetherai/index.d.ts +23 -0
- package/lib/types/togetherai/index.d.ts.map +1 -0
- package/lib/types/togetherai/interfaces.d.ts +96 -0
- package/lib/types/togetherai/interfaces.d.ts.map +1 -0
- package/lib/types/vertexai/debug.d.ts +2 -0
- package/lib/types/vertexai/debug.d.ts.map +1 -0
- package/lib/types/vertexai/embeddings/embeddings-image.d.ts +11 -0
- package/lib/types/vertexai/embeddings/embeddings-image.d.ts.map +1 -0
- package/lib/types/vertexai/embeddings/embeddings-text.d.ts +10 -0
- package/lib/types/vertexai/embeddings/embeddings-text.d.ts.map +1 -0
- package/lib/types/vertexai/index.d.ts +79 -0
- package/lib/types/vertexai/index.d.ts.map +1 -0
- package/lib/types/vertexai/models/claude.d.ts +103 -0
- package/lib/types/vertexai/models/claude.d.ts.map +1 -0
- package/lib/types/vertexai/models/gemini.d.ts +78 -0
- package/lib/types/vertexai/models/gemini.d.ts.map +1 -0
- package/lib/types/vertexai/models/imagen.d.ts +75 -0
- package/lib/types/vertexai/models/imagen.d.ts.map +1 -0
- package/lib/types/vertexai/models/llama.d.ts +20 -0
- package/lib/types/vertexai/models/llama.d.ts.map +1 -0
- package/lib/types/vertexai/models.d.ts +20 -0
- package/lib/types/vertexai/models.d.ts.map +1 -0
- package/lib/types/watsonx/index.d.ts +27 -0
- package/lib/types/watsonx/index.d.ts.map +1 -0
- package/lib/types/watsonx/interfaces.d.ts +65 -0
- package/lib/types/watsonx/interfaces.d.ts.map +1 -0
- package/lib/types/xai/index.d.ts +18 -0
- package/lib/types/xai/index.d.ts.map +1 -0
- package/package.json +18 -18
- package/src/bedrock/converse.ts +85 -10
- package/src/bedrock/error-handling.test.ts +352 -0
- package/src/bedrock/index.ts +293 -16
- package/src/groq/index.ts +9 -4
- package/src/mistral/index.ts +25 -22
- package/src/mistral/types.ts +0 -5
- package/src/openai/error-handling.test.ts +567 -0
- package/src/openai/index.ts +513 -33
- package/src/openai/openai_compatible.ts +7 -0
- package/src/openai/openai_format.ts +1 -1
- package/src/vertexai/index.ts +61 -13
- package/src/vertexai/models/claude-error-handling.test.ts +432 -0
- package/src/vertexai/models/claude.ts +287 -10
- package/src/vertexai/models/gemini-error-handling.test.ts +353 -0
- package/src/vertexai/models/gemini.ts +329 -52
- package/src/vertexai/models.ts +7 -2
package/src/bedrock/index.ts
CHANGED
|
@@ -10,22 +10,26 @@ import {
|
|
|
10
10
|
BedrockClaudeOptions,
|
|
11
11
|
BedrockGptOssOptions,
|
|
12
12
|
BedrockPalmyraOptions,
|
|
13
|
-
Completion, CompletionChunkObject,
|
|
13
|
+
Completion, CompletionChunkObject,
|
|
14
|
+
CompletionResult,
|
|
15
|
+
DataSource,
|
|
16
|
+
deserializeBinaryFromStorage,
|
|
17
|
+
DriverOptions, EmbeddingsOptions, EmbeddingsResult,
|
|
14
18
|
ExecutionOptions, ExecutionTokenUsage,
|
|
19
|
+
getConversationMeta,
|
|
15
20
|
getMaxTokensLimitBedrock,
|
|
16
21
|
getModelCapabilities,
|
|
22
|
+
incrementConversationTurn,
|
|
23
|
+
LlumiverseError, LlumiverseErrorContext,
|
|
17
24
|
modelModalitiesToArray,
|
|
18
25
|
ModelOptions,
|
|
19
26
|
NovaCanvasOptions,
|
|
20
27
|
PromptSegment,
|
|
21
28
|
StatelessExecutionOptions,
|
|
22
29
|
stripBinaryFromConversation,
|
|
23
|
-
|
|
24
|
-
deserializeBinaryFromStorage,
|
|
25
|
-
getConversationMeta,
|
|
26
|
-
incrementConversationTurn,
|
|
30
|
+
stripHeartbeatsFromConversation,
|
|
27
31
|
TextFallbackOptions, ToolDefinition, ToolUse, TrainingJob, TrainingJobStatus, TrainingOptions,
|
|
28
|
-
|
|
32
|
+
truncateLargeTextInConversation
|
|
29
33
|
} from "@llumiverse/core";
|
|
30
34
|
import { transformAsyncIterator } from "@llumiverse/core/async";
|
|
31
35
|
import { formatNovaPrompt, NovaMessagesPrompt } from "@llumiverse/core/formatters";
|
|
@@ -93,14 +97,49 @@ function maxTokenFallbackClaude(option: StatelessExecutionOptions): number {
|
|
|
93
97
|
if (modelOptions && typeof modelOptions.max_tokens === "number") {
|
|
94
98
|
return modelOptions.max_tokens;
|
|
95
99
|
} else {
|
|
96
|
-
const thinking_budget = modelOptions?.thinking_budget_tokens ?? 0;
|
|
97
100
|
let maxSupportedTokens = getMaxTokensLimitBedrock(option.model) ?? 8192; // Should always return a number for claude, 8192 is to satisfy the TypeScript type checker;
|
|
98
101
|
// Fallback to the default max tokens limit for the model
|
|
99
102
|
if (option.model.includes('claude-3-7-sonnet') && (modelOptions?.thinking_budget_tokens ?? 0) < 48000) {
|
|
100
103
|
maxSupportedTokens = 64000; // Claude 3.7 can go up to 128k with a beta header, but when no max tokens is specified, we default to 64k.
|
|
101
104
|
}
|
|
102
|
-
return
|
|
105
|
+
return maxSupportedTokens;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Parse Claude model version from model string.
|
|
111
|
+
* @param modelString - The model identifier string
|
|
112
|
+
* @returns An object with major and minor version numbers, or null if not parseable
|
|
113
|
+
*/
|
|
114
|
+
function parseClaudeVersion(modelString: string): { major: number; minor: number } | null {
|
|
115
|
+
// Match pattern: claude-[optional variant]-{major}-[optional 1-2 digit minor]
|
|
116
|
+
// The minor version is limited to 1-2 digits to avoid matching dates (YYYYMMDD format)
|
|
117
|
+
const match = modelString.match(/claude-(?:[a-z]+-)?(\d+)(?:-(\d{1,2}))?(?:-|\b)/);
|
|
118
|
+
if (match) {
|
|
119
|
+
return {
|
|
120
|
+
major: parseInt(match[1], 10),
|
|
121
|
+
minor: match[2] ? parseInt(match[2], 10) : 0
|
|
122
|
+
};
|
|
103
123
|
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Check if a Claude model version is greater than or equal to a target version.
|
|
129
|
+
* @returns true if the model version is >= target version, false otherwise
|
|
130
|
+
*/
|
|
131
|
+
function isClaudeVersionGTE(modelString: string, targetMajor: number, targetMinor: number): boolean {
|
|
132
|
+
const version = parseClaudeVersion(modelString);
|
|
133
|
+
if (!version) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
if (version.major > targetMajor) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
if (version.major === targetMajor && version.minor >= targetMinor) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
104
143
|
}
|
|
105
144
|
|
|
106
145
|
export type BedrockPrompt = NovaMessagesPrompt | ConverseRequest | TwelvelabsPegasusRequest;
|
|
@@ -153,6 +192,143 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
153
192
|
return await formatConversePrompt(segments, opts);
|
|
154
193
|
}
|
|
155
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Format AWS Bedrock errors into LlumiverseError with proper status codes and retryability.
|
|
197
|
+
*
|
|
198
|
+
* AWS SDK errors provide:
|
|
199
|
+
* - error.name: The exception type (e.g., "ThrottlingException")
|
|
200
|
+
* - error.$metadata.httpStatusCode: The HTTP status code
|
|
201
|
+
* - error.$metadata.requestId: The AWS request ID for tracking
|
|
202
|
+
* - error.$fault: "client" or "server" indicating error category
|
|
203
|
+
*
|
|
204
|
+
* @param error - The AWS SDK error
|
|
205
|
+
* @param context - Context about where the error occurred
|
|
206
|
+
* @returns A standardized LlumiverseError
|
|
207
|
+
*/
|
|
208
|
+
public formatLlumiverseError(
|
|
209
|
+
error: unknown,
|
|
210
|
+
context: LlumiverseErrorContext
|
|
211
|
+
): LlumiverseError {
|
|
212
|
+
// Check if it's an AWS SDK error with $metadata
|
|
213
|
+
const awsError = error as any;
|
|
214
|
+
const hasMetadata = awsError?.$metadata !== undefined;
|
|
215
|
+
|
|
216
|
+
if (!hasMetadata) {
|
|
217
|
+
// Not an AWS SDK error, use default handling
|
|
218
|
+
return super.formatLlumiverseError(error, context);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Extract AWS-specific fields
|
|
222
|
+
const errorName = awsError.name || 'UnknownError';
|
|
223
|
+
const httpStatusCode = awsError.$metadata?.httpStatusCode;
|
|
224
|
+
const requestId = awsError.$metadata?.requestId;
|
|
225
|
+
const fault = awsError.$fault; // "client" or "server"
|
|
226
|
+
|
|
227
|
+
// Extract error message - handle both Error instances and plain objects
|
|
228
|
+
let message: string;
|
|
229
|
+
if (error instanceof Error) {
|
|
230
|
+
message = error.message;
|
|
231
|
+
} else if (typeof awsError.message === 'string') {
|
|
232
|
+
message = awsError.message;
|
|
233
|
+
} else {
|
|
234
|
+
message = String(error);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Build user-facing message with error name and status code
|
|
238
|
+
let userMessage = message;
|
|
239
|
+
|
|
240
|
+
// Include status code in message if available (for end-user visibility)
|
|
241
|
+
if (httpStatusCode) {
|
|
242
|
+
userMessage = `[${httpStatusCode}] ${userMessage}`;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Prefix with error name if it's meaningful (not just "Error")
|
|
246
|
+
if (errorName && errorName !== 'Error' && errorName !== 'UnknownError') {
|
|
247
|
+
userMessage = `${errorName}: ${userMessage}`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Add request ID if available (useful for AWS support)
|
|
251
|
+
if (requestId) {
|
|
252
|
+
userMessage += ` (Request ID: ${requestId})`;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Determine retryability based on AWS error types
|
|
256
|
+
const retryable = this.isBedrockErrorRetryable(errorName, httpStatusCode, fault);
|
|
257
|
+
|
|
258
|
+
return new LlumiverseError(
|
|
259
|
+
`[${this.provider}] ${userMessage}`,
|
|
260
|
+
retryable,
|
|
261
|
+
context,
|
|
262
|
+
error,
|
|
263
|
+
httpStatusCode, // Only set code if we have numeric status code
|
|
264
|
+
errorName // Preserve AWS error name
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Determine if a Bedrock error is retryable based on error type and status.
|
|
270
|
+
*
|
|
271
|
+
* Retryable errors:
|
|
272
|
+
* - ThrottlingException: Rate limit exceeded, retry with backoff
|
|
273
|
+
* - ServiceUnavailableException: Service temporarily down
|
|
274
|
+
* - InternalServerException: Server-side error
|
|
275
|
+
* - ServiceQuotaExceededException: Quota exhausted, may recover
|
|
276
|
+
* - 5xx status codes: Server errors
|
|
277
|
+
* - 429, 408 status codes: Rate limit, timeout
|
|
278
|
+
*
|
|
279
|
+
* Non-retryable errors:
|
|
280
|
+
* - ValidationException: Invalid request parameters
|
|
281
|
+
* - AccessDeniedException: Authentication/authorization failure
|
|
282
|
+
* - ResourceNotFoundException: Resource doesn't exist
|
|
283
|
+
* - ConflictException: Resource state conflict
|
|
284
|
+
* - ResourceInUseException: Resource locked by another operation
|
|
285
|
+
* - 4xx status codes (except 429, 408): Client errors
|
|
286
|
+
*
|
|
287
|
+
* @param errorName - The AWS error name (e.g., "ThrottlingException")
|
|
288
|
+
* @param httpStatusCode - The HTTP status code if available
|
|
289
|
+
* @param fault - The fault type ("client" or "server")
|
|
290
|
+
* @returns True if retryable, false if not retryable, undefined if unknown
|
|
291
|
+
*/
|
|
292
|
+
private isBedrockErrorRetryable(
|
|
293
|
+
errorName: string,
|
|
294
|
+
httpStatusCode: number | undefined,
|
|
295
|
+
fault: string | undefined
|
|
296
|
+
): boolean | undefined {
|
|
297
|
+
// Check specific AWS error types first
|
|
298
|
+
switch (errorName) {
|
|
299
|
+
// Retryable errors
|
|
300
|
+
case 'ThrottlingException':
|
|
301
|
+
case 'ServiceUnavailableException':
|
|
302
|
+
case 'InternalServerException':
|
|
303
|
+
case 'ServiceQuotaExceededException':
|
|
304
|
+
return true;
|
|
305
|
+
|
|
306
|
+
// Non-retryable errors
|
|
307
|
+
case 'ValidationException':
|
|
308
|
+
case 'AccessDeniedException':
|
|
309
|
+
case 'ResourceNotFoundException':
|
|
310
|
+
case 'ConflictException':
|
|
311
|
+
case 'ResourceInUseException':
|
|
312
|
+
case 'TooManyTagsException':
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// If we have HTTP status code, use it
|
|
317
|
+
if (httpStatusCode !== undefined) {
|
|
318
|
+
if (httpStatusCode === 429 || httpStatusCode === 408) return true; // Rate limit, timeout
|
|
319
|
+
if (httpStatusCode === 529) return true; // Overloaded
|
|
320
|
+
if (httpStatusCode >= 500 && httpStatusCode < 600) return true; // Server errors
|
|
321
|
+
if (httpStatusCode >= 400 && httpStatusCode < 500) return false; // Client errors
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Fall back to fault type
|
|
325
|
+
if (fault === 'server') return true;
|
|
326
|
+
if (fault === 'client') return false;
|
|
327
|
+
|
|
328
|
+
// Unknown error type - let consumer decide retry strategy
|
|
329
|
+
return undefined;
|
|
330
|
+
}
|
|
331
|
+
|
|
156
332
|
getExtractedExecution(result: ConverseResponse, _prompt?: BedrockPrompt, options?: ExecutionOptions): CompletionChunkObject {
|
|
157
333
|
let resultText = "";
|
|
158
334
|
let reasoning = "";
|
|
@@ -163,9 +339,11 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
163
339
|
if (content.text) {
|
|
164
340
|
resultText += content.text;
|
|
165
341
|
} else if (content.reasoningContent) {
|
|
166
|
-
//
|
|
342
|
+
// Extract reasoning content if include_thoughts is true, or if it's a
|
|
343
|
+
// reasoning-only model (e.g. DeepSeek R1) that returns no text blocks
|
|
167
344
|
const claudeOptions = options?.model_options as BedrockClaudeOptions;
|
|
168
|
-
|
|
345
|
+
const isReasoningModel = options?.model?.includes('deepseek') && options?.model?.includes('r1');
|
|
346
|
+
if (claudeOptions?.include_thoughts || isReasoningModel) {
|
|
169
347
|
if (content.reasoningContent.reasoningText) {
|
|
170
348
|
reasoning += content.reasoningContent.reasoningText.text;
|
|
171
349
|
} else if (content.reasoningContent.redactedContent) {
|
|
@@ -210,8 +388,9 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
210
388
|
let stop_reason = "";
|
|
211
389
|
let token_usage: ExecutionTokenUsage | undefined;
|
|
212
390
|
|
|
213
|
-
// Check if we should include thoughts
|
|
214
|
-
const
|
|
391
|
+
// Check if we should include thoughts (always true for reasoning-only models like DeepSeek R1)
|
|
392
|
+
const isReasoningModel = options?.model?.includes('deepseek') && options?.model?.includes('r1');
|
|
393
|
+
const shouldIncludeThoughts = isReasoningModel || (options && (options.model_options as BedrockClaudeOptions)?.include_thoughts);
|
|
215
394
|
|
|
216
395
|
// Handle content block start events (for reasoning blocks)
|
|
217
396
|
if (result.contentBlockStart) {
|
|
@@ -443,6 +622,10 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
443
622
|
};
|
|
444
623
|
let processedConversation = stripBinaryFromConversation(conversation, stripOptions);
|
|
445
624
|
processedConversation = truncateLargeTextInConversation(processedConversation, stripOptions);
|
|
625
|
+
processedConversation = stripHeartbeatsFromConversation(processedConversation, {
|
|
626
|
+
keepForTurns: options.stripHeartbeatsAfterTurns ?? 1,
|
|
627
|
+
currentTurn,
|
|
628
|
+
});
|
|
446
629
|
|
|
447
630
|
return processedConversation as ConverseRequest;
|
|
448
631
|
}
|
|
@@ -467,8 +650,15 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
467
650
|
...payload,
|
|
468
651
|
});
|
|
469
652
|
|
|
653
|
+
// Strip reasoningContent from assistant messages before storing in conversation
|
|
654
|
+
// (DeepSeek R1 returns reasoning blocks but rejects them in subsequent user turns)
|
|
655
|
+
const assistantMsg = res.output?.message ?? { content: [{ text: "" }], role: "assistant" };
|
|
656
|
+
if (assistantMsg.content) {
|
|
657
|
+
assistantMsg.content = assistantMsg.content.filter((c: any) => !c.reasoningContent);
|
|
658
|
+
}
|
|
659
|
+
|
|
470
660
|
conversation = updateConversation(conversation, {
|
|
471
|
-
messages: [
|
|
661
|
+
messages: [assistantMsg],
|
|
472
662
|
modelId: conversePrompt.modelId,
|
|
473
663
|
});
|
|
474
664
|
|
|
@@ -504,6 +694,12 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
504
694
|
// Truncate large text content if configured
|
|
505
695
|
processedConversation = truncateLargeTextInConversation(processedConversation, stripOptions);
|
|
506
696
|
|
|
697
|
+
// Strip old heartbeat status messages
|
|
698
|
+
processedConversation = stripHeartbeatsFromConversation(processedConversation, {
|
|
699
|
+
keepForTurns: options.stripHeartbeatsAfterTurns ?? 1,
|
|
700
|
+
currentTurn,
|
|
701
|
+
});
|
|
702
|
+
|
|
507
703
|
const completion = {
|
|
508
704
|
...this.getExtractedExecution(res, conversePrompt, options),
|
|
509
705
|
original_response: options.include_original_response ? res : undefined,
|
|
@@ -671,6 +867,10 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
671
867
|
};
|
|
672
868
|
}
|
|
673
869
|
}
|
|
870
|
+
// Claude 4.6 and later versions don't support JSON prefill
|
|
871
|
+
if (isClaudeVersionGTE(options.model, 4, 6)) {
|
|
872
|
+
supportsJSONPrefill = false;
|
|
873
|
+
}
|
|
674
874
|
//Needs max_tokens to be set
|
|
675
875
|
if (!model_options.max_tokens) {
|
|
676
876
|
model_options.max_tokens = maxTokenFallbackClaude(options);
|
|
@@ -735,7 +935,9 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
735
935
|
min_tokens: palmyraOptions?.min_tokens,
|
|
736
936
|
}
|
|
737
937
|
} else if (options.model.includes("deepseek")) {
|
|
738
|
-
//DeepSeek models
|
|
938
|
+
// DeepSeek models: no additional options, no stopSequences, only one of temperature/top_p
|
|
939
|
+
model_options.stop_sequence = undefined;
|
|
940
|
+
model_options.top_p = undefined;
|
|
739
941
|
} else if (options.model.includes("gpt-oss")) {
|
|
740
942
|
const gptOssOptions = model_options as ModelOptions as BedrockGptOssOptions;
|
|
741
943
|
additionalField = {
|
|
@@ -769,7 +971,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
769
971
|
const cleanedModelOptions = removeUndefinedValues({
|
|
770
972
|
maxTokens: model_options.max_tokens,
|
|
771
973
|
temperature: model_options.temperature,
|
|
772
|
-
topP: model_options.top_p,
|
|
974
|
+
topP: model_options.temperature != null ? undefined : model_options.top_p,
|
|
773
975
|
stopSequences: model_options.stop_sequence,
|
|
774
976
|
} satisfies InferenceConfiguration);
|
|
775
977
|
|
|
@@ -799,6 +1001,12 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
799
1001
|
request.toolConfig = {
|
|
800
1002
|
tools: tool_defs,
|
|
801
1003
|
}
|
|
1004
|
+
} else if (request.messages && messagesContainToolBlocks(request.messages)) {
|
|
1005
|
+
// Bedrock requires toolConfig when conversation contains toolUse/toolResult blocks.
|
|
1006
|
+
// When no tools are provided (e.g. checkpoint summary calls), convert tool blocks
|
|
1007
|
+
// to text representations so the conversation data is preserved while satisfying
|
|
1008
|
+
// Bedrock's API requirements without making tools callable.
|
|
1009
|
+
request.messages = convertToolBlocksToText(request.messages);
|
|
802
1010
|
}
|
|
803
1011
|
|
|
804
1012
|
return request;
|
|
@@ -1142,7 +1350,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1142
1350
|
const executor = this.getExecutor();
|
|
1143
1351
|
|
|
1144
1352
|
// Prepare the request payload for TwelveLabs Marengo
|
|
1145
|
-
|
|
1353
|
+
const invokeBody: TwelvelabsMarengoRequest = {
|
|
1146
1354
|
inputType: "text"
|
|
1147
1355
|
};
|
|
1148
1356
|
|
|
@@ -1232,6 +1440,75 @@ function getToolDefinition(tool: ToolDefinition): Tool.ToolSpecMember {
|
|
|
1232
1440
|
}
|
|
1233
1441
|
}
|
|
1234
1442
|
|
|
1443
|
+
/**
|
|
1444
|
+
* Checks whether any message contains toolUse or toolResult content blocks.
|
|
1445
|
+
*/
|
|
1446
|
+
export function messagesContainToolBlocks(messages: Message[]): boolean {
|
|
1447
|
+
for (const msg of messages) {
|
|
1448
|
+
if (!msg.content) continue;
|
|
1449
|
+
for (const block of msg.content) {
|
|
1450
|
+
if ((block as ContentBlock.ToolUseMember).toolUse ||
|
|
1451
|
+
(block as ContentBlock.ToolResultMember).toolResult) {
|
|
1452
|
+
return true;
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
return false;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
/**
|
|
1460
|
+
* Converts toolUse and toolResult content blocks to text representations.
|
|
1461
|
+
* This preserves the tool call information in the conversation while removing
|
|
1462
|
+
* the structured tool blocks that require Bedrock's toolConfig to be set.
|
|
1463
|
+
*
|
|
1464
|
+
* Used when no tools are provided (e.g. checkpoint summary calls) but the
|
|
1465
|
+
* conversation history contains tool interactions from prior turns.
|
|
1466
|
+
*/
|
|
1467
|
+
export function convertToolBlocksToText(messages: Message[]): Message[] {
|
|
1468
|
+
return messages.map(msg => {
|
|
1469
|
+
if (!msg.content) return msg;
|
|
1470
|
+
let hasToolBlocks = false;
|
|
1471
|
+
for (const block of msg.content) {
|
|
1472
|
+
if ((block as ContentBlock.ToolUseMember).toolUse ||
|
|
1473
|
+
(block as ContentBlock.ToolResultMember).toolResult) {
|
|
1474
|
+
hasToolBlocks = true;
|
|
1475
|
+
break;
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
if (!hasToolBlocks) return msg;
|
|
1479
|
+
|
|
1480
|
+
const newContent: ContentBlock[] = [];
|
|
1481
|
+
for (const block of msg.content) {
|
|
1482
|
+
const toolUse = (block as ContentBlock.ToolUseMember).toolUse;
|
|
1483
|
+
const toolResult = (block as ContentBlock.ToolResultMember).toolResult;
|
|
1484
|
+
if (toolUse) {
|
|
1485
|
+
const inputStr = toolUse.input ? JSON.stringify(toolUse.input) : '';
|
|
1486
|
+
const truncatedInput = inputStr.length > 500 ? inputStr.substring(0, 500) + '...' : inputStr;
|
|
1487
|
+
newContent.push({
|
|
1488
|
+
text: `[Tool call: ${toolUse.name}(${truncatedInput})]`,
|
|
1489
|
+
} as ContentBlock.TextMember);
|
|
1490
|
+
} else if (toolResult) {
|
|
1491
|
+
const resultTexts: string[] = [];
|
|
1492
|
+
if (toolResult.content) {
|
|
1493
|
+
for (const c of toolResult.content) {
|
|
1494
|
+
if ((c as any).text) {
|
|
1495
|
+
const text = (c as any).text as string;
|
|
1496
|
+
resultTexts.push(text.length > 500 ? text.substring(0, 500) + '...' : text);
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
const resultStr = resultTexts.length > 0 ? resultTexts.join('\n') : 'No text content';
|
|
1501
|
+
newContent.push({
|
|
1502
|
+
text: `[Tool result: ${resultStr}]`,
|
|
1503
|
+
} as ContentBlock.TextMember);
|
|
1504
|
+
} else {
|
|
1505
|
+
newContent.push(block);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
return { ...msg, content: newContent };
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1235
1512
|
/**
|
|
1236
1513
|
* Recursively removes undefined values from an object.
|
|
1237
1514
|
* AWS Bedrock's additionalModelRequestFields must be valid JSON, and undefined is not valid JSON.
|
package/src/groq/index.ts
CHANGED
|
@@ -299,12 +299,17 @@ function convertResponseItemsToGroqMessages(items: ResponseInputItem[]): ChatCom
|
|
|
299
299
|
} else if (part.type === 'input_image') {
|
|
300
300
|
const imgPart = part as OpenAI.Responses.ResponseInputImage;
|
|
301
301
|
if (imgPart.image_url) {
|
|
302
|
+
const image_url: { url: string; detail?: 'auto' | 'low' | 'high' } = {
|
|
303
|
+
url: imgPart.image_url
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
if (imgPart.detail) {
|
|
307
|
+
image_url.detail = imgPart.detail as 'auto' | 'low' | 'high';
|
|
308
|
+
}
|
|
309
|
+
|
|
302
310
|
parts.push({
|
|
303
311
|
type: 'image_url',
|
|
304
|
-
image_url
|
|
305
|
-
url: imgPart.image_url,
|
|
306
|
-
...(imgPart.detail && { detail: imgPart.detail })
|
|
307
|
-
}
|
|
312
|
+
image_url
|
|
308
313
|
});
|
|
309
314
|
}
|
|
310
315
|
}
|
package/src/mistral/index.ts
CHANGED
|
@@ -68,14 +68,17 @@ export class MistralAIDriver extends AbstractDriver<MistralAIDriverOptions, Open
|
|
|
68
68
|
}
|
|
69
69
|
options.model_options = options.model_options as TextFallbackOptions;
|
|
70
70
|
|
|
71
|
+
const requestPayload = _makeChatCompletionRequest({
|
|
72
|
+
model: options.model,
|
|
73
|
+
messages: messages,
|
|
74
|
+
maxTokens: options.model_options?.max_tokens,
|
|
75
|
+
temperature: options.model_options?.temperature,
|
|
76
|
+
responseFormat: this.getResponseFormat(options),
|
|
77
|
+
});
|
|
78
|
+
this.logger.debug({ payload: JSON.stringify(requestPayload) }, "Mistral request payload");
|
|
79
|
+
|
|
71
80
|
const res = await this.client.post('/v1/chat/completions', {
|
|
72
|
-
payload:
|
|
73
|
-
model: options.model,
|
|
74
|
-
messages: messages,
|
|
75
|
-
maxTokens: options.model_options?.max_tokens,
|
|
76
|
-
temperature: options.model_options?.temperature,
|
|
77
|
-
responseFormat: this.getResponseFormat(options),
|
|
78
|
-
})
|
|
81
|
+
payload: requestPayload,
|
|
79
82
|
}) as ChatCompletionResponse;
|
|
80
83
|
|
|
81
84
|
const choice = res.choices[0];
|
|
@@ -99,17 +102,20 @@ export class MistralAIDriver extends AbstractDriver<MistralAIDriverOptions, Open
|
|
|
99
102
|
}
|
|
100
103
|
options.model_options = options.model_options as TextFallbackOptions;
|
|
101
104
|
|
|
105
|
+
const streamPayload = _makeChatCompletionRequest({
|
|
106
|
+
model: options.model,
|
|
107
|
+
messages: messages,
|
|
108
|
+
maxTokens: options.model_options?.max_tokens,
|
|
109
|
+
temperature: options.model_options?.temperature,
|
|
110
|
+
topP: options.model_options?.top_p,
|
|
111
|
+
responseFormat: this.getResponseFormat(options),
|
|
112
|
+
stream: true,
|
|
113
|
+
stopSequences: options.model_options?.stop_sequence,
|
|
114
|
+
});
|
|
115
|
+
this.logger.debug({ payload: JSON.stringify(streamPayload) }, "Mistral stream request payload");
|
|
116
|
+
|
|
102
117
|
const stream = await this.client.post('/v1/chat/completions', {
|
|
103
|
-
payload:
|
|
104
|
-
model: options.model,
|
|
105
|
-
messages: messages,
|
|
106
|
-
maxTokens: options.model_options?.max_tokens,
|
|
107
|
-
temperature: options.model_options?.temperature,
|
|
108
|
-
topP: options.model_options?.top_p,
|
|
109
|
-
responseFormat: this.getResponseFormat(options),
|
|
110
|
-
stream: true,
|
|
111
|
-
stopSequences: options.model_options?.stop_sequence,
|
|
112
|
-
}),
|
|
118
|
+
payload: streamPayload,
|
|
113
119
|
reader: 'sse'
|
|
114
120
|
});
|
|
115
121
|
|
|
@@ -191,22 +197,19 @@ function _makeChatCompletionRequest({
|
|
|
191
197
|
topP,
|
|
192
198
|
randomSeed,
|
|
193
199
|
stream,
|
|
194
|
-
safeMode,
|
|
195
|
-
safePrompt,
|
|
196
200
|
toolChoice,
|
|
197
201
|
responseFormat,
|
|
198
202
|
stopSequences,
|
|
199
203
|
}: CompletionRequestParams) {
|
|
200
204
|
return {
|
|
201
|
-
model
|
|
202
|
-
messages
|
|
205
|
+
model,
|
|
206
|
+
messages,
|
|
203
207
|
tools: tools ?? undefined,
|
|
204
208
|
temperature: temperature ?? undefined,
|
|
205
209
|
max_tokens: maxTokens ?? undefined,
|
|
206
210
|
top_p: topP ?? undefined,
|
|
207
211
|
random_seed: randomSeed ?? undefined,
|
|
208
212
|
stream: stream ?? undefined,
|
|
209
|
-
safe_prompt: (safeMode || safePrompt) ?? undefined,
|
|
210
213
|
tool_choice: toolChoice ?? undefined,
|
|
211
214
|
response_format: responseFormat ?? undefined,
|
|
212
215
|
stop: stopSequences ?? undefined,
|
package/src/mistral/types.ts
CHANGED
|
@@ -132,11 +132,6 @@ export interface CompletionRequestParams {
|
|
|
132
132
|
topP?: number,
|
|
133
133
|
randomSeed?: number,
|
|
134
134
|
stream?: boolean,
|
|
135
|
-
/**
|
|
136
|
-
* @deprecated use safePrompt instead
|
|
137
|
-
*/
|
|
138
|
-
safeMode?: boolean,
|
|
139
|
-
safePrompt?: boolean,
|
|
140
135
|
toolChoice?: ToolChoice,
|
|
141
136
|
responseFormat?: ResponseFormat,
|
|
142
137
|
stopSequences?: string[],
|