@llumiverse/drivers 1.3.0 → 1.4.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/{types/adobe → adobe}/firefly.d.ts +2 -1
- package/lib/adobe/firefly.d.ts.map +1 -0
- package/lib/adobe/firefly.js +120 -0
- package/lib/adobe/firefly.js.map +1 -0
- package/lib/{types/anthropic → anthropic}/index.d.ts +4 -2
- package/lib/anthropic/index.d.ts.map +1 -0
- package/lib/{esm/anthropic → anthropic}/index.js +19 -8
- package/lib/anthropic/index.js.map +1 -0
- package/lib/{types/azure → azure}/azure_foundry.d.ts +9 -7
- package/lib/azure/azure_foundry.d.ts.map +1 -0
- package/lib/{esm/azure → azure}/azure_foundry.js +138 -124
- package/lib/azure/azure_foundry.js.map +1 -0
- package/lib/{types/bedrock → bedrock}/converse.d.ts +2 -2
- package/lib/bedrock/converse.d.ts.map +1 -0
- package/lib/{esm/bedrock → bedrock}/converse.js +86 -79
- package/lib/bedrock/converse.js.map +1 -0
- package/lib/bedrock/embeddings.d.ts +4 -0
- package/lib/bedrock/embeddings.d.ts.map +1 -0
- package/lib/bedrock/embeddings.js +359 -0
- package/lib/bedrock/embeddings.js.map +1 -0
- package/lib/{types/bedrock → bedrock}/index.d.ts +33 -9
- package/lib/bedrock/index.d.ts.map +1 -0
- package/lib/{esm/bedrock → bedrock}/index.js +599 -324
- package/lib/bedrock/index.js.map +1 -0
- package/lib/{types/bedrock → bedrock}/nova-image-payload.d.ts +5 -5
- package/lib/bedrock/nova-image-payload.d.ts.map +1 -0
- package/lib/{esm/bedrock → bedrock}/nova-image-payload.js +31 -36
- package/lib/bedrock/nova-image-payload.js.map +1 -0
- package/lib/{types/bedrock → bedrock}/payloads.d.ts +1 -1
- package/lib/bedrock/payloads.d.ts.map +1 -0
- package/lib/{cjs/bedrock → bedrock}/payloads.js.map +1 -1
- package/lib/{types/bedrock → bedrock}/s3.d.ts +3 -2
- package/lib/bedrock/s3.d.ts.map +1 -0
- package/lib/{esm/bedrock → bedrock}/s3.js +27 -23
- package/lib/bedrock/s3.js.map +1 -0
- package/lib/{types/bedrock → bedrock}/twelvelabs.d.ts +8 -9
- package/lib/bedrock/twelvelabs.d.ts.map +1 -0
- package/lib/{esm/bedrock → bedrock}/twelvelabs.js +17 -21
- package/lib/bedrock/twelvelabs.js.map +1 -0
- package/lib/{types/groq → groq}/index.d.ts +6 -4
- package/lib/groq/index.d.ts.map +1 -0
- package/lib/{esm/groq → groq}/index.js +72 -39
- package/lib/groq/index.js.map +1 -0
- package/lib/{types/huggingface_ie.d.ts → huggingface_ie.d.ts} +4 -3
- package/lib/huggingface_ie.d.ts.map +1 -0
- package/lib/{esm/huggingface_ie.js → huggingface_ie.js} +32 -31
- package/lib/huggingface_ie.js.map +1 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +16 -0
- package/lib/index.js.map +1 -0
- package/lib/{types/mistral → mistral}/index.d.ts +6 -5
- package/lib/mistral/index.d.ts.map +1 -0
- package/lib/{esm/mistral → mistral}/index.js +66 -38
- package/lib/mistral/index.js.map +1 -0
- package/lib/{types/mistral → mistral}/types.d.ts +1 -0
- package/lib/mistral/types.d.ts.map +1 -0
- package/lib/mistral/types.js.map +1 -0
- package/lib/{types/openai → openai}/azure_openai.d.ts +5 -4
- package/lib/openai/azure_openai.d.ts.map +1 -0
- package/lib/{esm/openai → openai}/azure_openai.js +17 -14
- package/lib/openai/azure_openai.js.map +1 -0
- package/lib/openai/drivers.d.ts +4 -0
- package/lib/openai/drivers.d.ts.map +1 -0
- package/lib/openai/drivers.js +9 -0
- package/lib/openai/drivers.js.map +1 -0
- package/lib/{types/openai → openai}/index.d.ts +16 -5
- package/lib/openai/index.d.ts.map +1 -0
- package/lib/{esm/openai → openai}/index.js +242 -141
- package/lib/openai/index.js.map +1 -0
- package/lib/{types/openai → openai}/openai.d.ts +3 -3
- package/lib/openai/openai.d.ts.map +1 -0
- package/lib/openai/openai.js +15 -0
- package/lib/openai/openai.js.map +1 -0
- package/lib/{types/openai → openai}/openai_compatible.d.ts +3 -3
- package/lib/openai/openai_compatible.d.ts.map +1 -0
- package/lib/{esm/openai → openai}/openai_compatible.js +14 -11
- package/lib/openai/openai_compatible.js.map +1 -0
- package/lib/{types/openai → openai}/openai_format.d.ts +3 -2
- package/lib/openai/openai_format.d.ts.map +1 -0
- package/lib/{esm/openai → openai}/openai_format.js +66 -24
- package/lib/openai/openai_format.js.map +1 -0
- package/lib/{types/replicate.d.ts → replicate.d.ts} +3 -2
- package/lib/replicate.d.ts.map +1 -0
- package/lib/{esm/replicate.js → replicate.js} +59 -49
- package/lib/replicate.js.map +1 -0
- package/lib/{types/shared → shared}/claude-messages.d.ts +25 -1
- package/lib/shared/claude-messages.d.ts.map +1 -0
- package/lib/{esm/shared → shared}/claude-messages.js +212 -59
- package/lib/shared/claude-messages.js.map +1 -0
- package/lib/{types/shared → shared}/claude-thinking.d.ts +1 -1
- package/lib/shared/claude-thinking.d.ts.map +1 -0
- package/lib/{esm/shared → shared}/claude-thinking.js +5 -7
- package/lib/shared/claude-thinking.js.map +1 -0
- package/lib/shared/debug-prompt.d.ts +5 -0
- package/lib/shared/debug-prompt.d.ts.map +1 -0
- package/lib/shared/debug-prompt.js +25 -0
- package/lib/shared/debug-prompt.js.map +1 -0
- package/lib/{types/test-driver → test-driver}/TestErrorCompletionStream.d.ts +1 -1
- package/lib/test-driver/TestErrorCompletionStream.d.ts.map +1 -0
- package/lib/test-driver/TestErrorCompletionStream.js +16 -0
- package/lib/test-driver/TestErrorCompletionStream.js.map +1 -0
- package/lib/{types/test-driver → test-driver}/TestValidationErrorCompletionStream.d.ts +1 -1
- package/lib/test-driver/TestValidationErrorCompletionStream.d.ts.map +1 -0
- package/lib/{esm/test-driver → test-driver}/TestValidationErrorCompletionStream.js +4 -4
- package/lib/test-driver/TestValidationErrorCompletionStream.js.map +1 -0
- package/lib/{types/test-driver → test-driver}/index.d.ts +3 -3
- package/lib/test-driver/index.d.ts.map +1 -0
- package/lib/{esm/test-driver → test-driver}/index.js +20 -20
- package/lib/test-driver/index.js.map +1 -0
- package/lib/{types/test-driver → test-driver}/utils.d.ts +1 -1
- package/lib/test-driver/utils.d.ts.map +1 -0
- package/lib/{esm/test-driver → test-driver}/utils.js +4 -4
- package/lib/test-driver/utils.js.map +1 -0
- package/lib/togetherai/index.d.ts +15 -0
- package/lib/togetherai/index.d.ts.map +1 -0
- package/lib/togetherai/index.js +54 -0
- package/lib/togetherai/index.js.map +1 -0
- package/lib/{types/togetherai → togetherai}/interfaces.d.ts +1 -1
- package/lib/togetherai/interfaces.d.ts.map +1 -0
- package/lib/{cjs/watsonx → togetherai}/interfaces.js.map +1 -1
- package/lib/vertexai/debug.d.ts +2 -0
- package/lib/vertexai/debug.d.ts.map +1 -0
- package/lib/{esm/vertexai → vertexai}/debug.js +1 -1
- package/lib/vertexai/debug.js.map +1 -0
- package/lib/vertexai/embeddings/embed-legacy-multimodal.d.ts +9 -0
- package/lib/vertexai/embeddings/embed-legacy-multimodal.d.ts.map +1 -0
- package/lib/vertexai/embeddings/embed-legacy-multimodal.js +141 -0
- package/lib/vertexai/embeddings/embed-legacy-multimodal.js.map +1 -0
- package/lib/vertexai/embeddings/embed.d.ts +13 -0
- package/lib/vertexai/embeddings/embed.d.ts.map +1 -0
- package/lib/vertexai/embeddings/embed.js +162 -0
- package/lib/vertexai/embeddings/embed.js.map +1 -0
- package/lib/vertexai/embeddings/source-utils.d.ts +9 -0
- package/lib/vertexai/embeddings/source-utils.d.ts.map +1 -0
- package/lib/vertexai/embeddings/source-utils.js +18 -0
- package/lib/vertexai/embeddings/source-utils.js.map +1 -0
- package/lib/{types/vertexai → vertexai}/index.d.ts +31 -19
- package/lib/vertexai/index.d.ts.map +1 -0
- package/lib/{esm/vertexai → vertexai}/index.js +221 -159
- package/lib/vertexai/index.js.map +1 -0
- package/lib/{types/vertexai → vertexai}/models/claude.d.ts +4 -4
- package/lib/vertexai/models/claude.d.ts.map +1 -0
- package/lib/{esm/vertexai → vertexai}/models/claude.js +17 -20
- package/lib/vertexai/models/claude.js.map +1 -0
- package/lib/{types/vertexai → vertexai}/models/gemini.d.ts +28 -4
- package/lib/vertexai/models/gemini.d.ts.map +1 -0
- package/lib/{esm/vertexai → vertexai}/models/gemini.js +238 -116
- package/lib/vertexai/models/gemini.js.map +1 -0
- package/lib/{types/vertexai → vertexai}/models/imagen.d.ts +12 -11
- package/lib/vertexai/models/imagen.d.ts.map +1 -0
- package/lib/{esm/vertexai → vertexai}/models/imagen.js +74 -47
- package/lib/vertexai/models/imagen.js.map +1 -0
- package/lib/{types/vertexai → vertexai}/models/llama.d.ts +4 -4
- package/lib/vertexai/models/llama.d.ts.map +1 -0
- package/lib/{esm/vertexai → vertexai}/models/llama.js +37 -33
- package/lib/vertexai/models/llama.js.map +1 -0
- package/lib/vertexai/models.d.ts +21 -0
- package/lib/vertexai/models.d.ts.map +1 -0
- package/lib/{esm/vertexai → vertexai}/models.js +12 -9
- package/lib/vertexai/models.js.map +1 -0
- package/lib/{types/watsonx → watsonx}/index.d.ts +4 -3
- package/lib/watsonx/index.d.ts.map +1 -0
- package/lib/{esm/watsonx → watsonx}/index.js +69 -41
- package/lib/watsonx/index.js.map +1 -0
- package/lib/watsonx/interfaces.d.ts.map +1 -0
- package/lib/{esm/watsonx → watsonx}/interfaces.js.map +1 -1
- package/lib/{types/xai → xai}/index.d.ts +4 -4
- package/lib/xai/index.d.ts.map +1 -0
- package/lib/{esm/xai → xai}/index.js +22 -18
- package/lib/xai/index.js.map +1 -0
- package/package.json +87 -36
- package/src/adobe/firefly.ts +60 -43
- package/src/anthropic/index.ts +37 -20
- package/src/azure/azure_foundry.ts +210 -165
- package/src/bedrock/converse.ts +124 -101
- package/src/bedrock/embeddings.test.ts +508 -0
- package/src/bedrock/embeddings.ts +517 -0
- package/src/bedrock/error-handling.test.ts +62 -14
- package/src/bedrock/index.ts +832 -466
- package/src/bedrock/nova-image-payload.ts +98 -91
- package/src/bedrock/payloads.ts +9 -9
- package/src/bedrock/s3.test.ts +39 -0
- package/src/bedrock/s3.ts +57 -38
- package/src/bedrock/streaming-tool-use.test.ts +86 -69
- package/src/bedrock/twelvelabs.ts +35 -32
- package/src/groq/index.ts +143 -60
- package/src/http-timeout-wiring.test.ts +263 -0
- package/src/huggingface_ie.ts +45 -61
- package/src/index.ts +15 -16
- package/src/mistral/index.ts +97 -48
- package/src/mistral/types.ts +13 -12
- package/src/openai/azure_openai.ts +35 -27
- package/src/openai/drivers.ts +9 -0
- package/src/openai/error-handling.test.ts +308 -113
- package/src/openai/index.ts +378 -248
- package/src/openai/openai.ts +6 -13
- package/src/openai/openai_compatible.ts +35 -25
- package/src/openai/openai_format.ts +90 -40
- package/src/replicate.ts +108 -86
- package/src/shared/claude-messages.test.ts +37 -0
- package/src/shared/claude-messages.ts +303 -97
- package/src/shared/claude-thinking.ts +6 -12
- package/src/shared/debug-prompt.ts +28 -0
- package/src/test-driver/TestErrorCompletionStream.ts +9 -10
- package/src/test-driver/TestValidationErrorCompletionStream.ts +9 -10
- package/src/test-driver/index.ts +43 -27
- package/src/test-driver/utils.ts +8 -8
- package/src/togetherai/index.test.ts +32 -0
- package/src/togetherai/index.ts +64 -128
- package/src/togetherai/interfaces.ts +5 -5
- package/src/vertexai/debug.ts +3 -3
- package/src/vertexai/embeddings/embed-legacy-multimodal.ts +211 -0
- package/src/vertexai/embeddings/embed.ts +206 -0
- package/src/vertexai/embeddings/embeddings.test.ts +497 -0
- package/src/vertexai/embeddings/source-utils.test.ts +54 -0
- package/src/vertexai/embeddings/source-utils.ts +29 -0
- package/src/vertexai/index.ts +331 -244
- package/src/vertexai/models/claude-error-handling.test.ts +83 -36
- package/src/vertexai/models/claude-streaming-spacing.test.ts +82 -75
- package/src/vertexai/models/claude.ts +55 -40
- package/src/vertexai/models/gemini-conversation-mutation.test.ts +65 -23
- package/src/vertexai/models/gemini-error-handling.test.ts +126 -10
- package/src/vertexai/models/gemini-orphaned-tool-result.test.ts +118 -0
- package/src/vertexai/models/gemini.ts +349 -172
- package/src/vertexai/models/imagen.ts +164 -100
- package/src/vertexai/models/llama.ts +70 -48
- package/src/vertexai/models.ts +36 -16
- package/src/watsonx/index.ts +101 -65
- package/src/watsonx/interfaces.ts +10 -15
- package/src/xai/index.ts +30 -30
- package/lib/cjs/adobe/firefly.js +0 -120
- package/lib/cjs/adobe/firefly.js.map +0 -1
- package/lib/cjs/anthropic/index.js +0 -64
- package/lib/cjs/anthropic/index.js.map +0 -1
- package/lib/cjs/azure/azure_foundry.js +0 -432
- package/lib/cjs/azure/azure_foundry.js.map +0 -1
- package/lib/cjs/bedrock/converse.js +0 -359
- package/lib/cjs/bedrock/converse.js.map +0 -1
- package/lib/cjs/bedrock/index.js +0 -1508
- package/lib/cjs/bedrock/index.js.map +0 -1
- package/lib/cjs/bedrock/nova-image-payload.js +0 -207
- package/lib/cjs/bedrock/nova-image-payload.js.map +0 -1
- package/lib/cjs/bedrock/payloads.js +0 -3
- package/lib/cjs/bedrock/s3.js +0 -107
- package/lib/cjs/bedrock/s3.js.map +0 -1
- package/lib/cjs/bedrock/twelvelabs.js +0 -87
- package/lib/cjs/bedrock/twelvelabs.js.map +0 -1
- package/lib/cjs/groq/index.js +0 -328
- package/lib/cjs/groq/index.js.map +0 -1
- package/lib/cjs/huggingface_ie.js +0 -201
- package/lib/cjs/huggingface_ie.js.map +0 -1
- package/lib/cjs/index.js +0 -32
- package/lib/cjs/index.js.map +0 -1
- package/lib/cjs/mistral/index.js +0 -176
- package/lib/cjs/mistral/index.js.map +0 -1
- package/lib/cjs/mistral/types.js +0 -83
- package/lib/cjs/mistral/types.js.map +0 -1
- package/lib/cjs/openai/azure_openai.js +0 -72
- package/lib/cjs/openai/azure_openai.js.map +0 -1
- package/lib/cjs/openai/index.js +0 -1135
- package/lib/cjs/openai/index.js.map +0 -1
- package/lib/cjs/openai/openai.js +0 -21
- package/lib/cjs/openai/openai.js.map +0 -1
- package/lib/cjs/openai/openai_compatible.js +0 -63
- package/lib/cjs/openai/openai_compatible.js.map +0 -1
- package/lib/cjs/openai/openai_format.js +0 -131
- package/lib/cjs/openai/openai_format.js.map +0 -1
- package/lib/cjs/package.json +0 -3
- package/lib/cjs/replicate.js +0 -275
- package/lib/cjs/replicate.js.map +0 -1
- package/lib/cjs/shared/claude-messages.js +0 -737
- package/lib/cjs/shared/claude-messages.js.map +0 -1
- package/lib/cjs/shared/claude-thinking.js +0 -60
- package/lib/cjs/shared/claude-thinking.js.map +0 -1
- package/lib/cjs/test-driver/TestErrorCompletionStream.js +0 -20
- package/lib/cjs/test-driver/TestErrorCompletionStream.js.map +0 -1
- package/lib/cjs/test-driver/TestValidationErrorCompletionStream.js +0 -24
- package/lib/cjs/test-driver/TestValidationErrorCompletionStream.js.map +0 -1
- package/lib/cjs/test-driver/index.js +0 -109
- package/lib/cjs/test-driver/index.js.map +0 -1
- package/lib/cjs/test-driver/utils.js +0 -30
- package/lib/cjs/test-driver/utils.js.map +0 -1
- package/lib/cjs/togetherai/index.js +0 -126
- package/lib/cjs/togetherai/index.js.map +0 -1
- package/lib/cjs/togetherai/interfaces.js +0 -3
- package/lib/cjs/togetherai/interfaces.js.map +0 -1
- package/lib/cjs/vertexai/debug.js +0 -12
- package/lib/cjs/vertexai/debug.js.map +0 -1
- package/lib/cjs/vertexai/embeddings/embeddings-image.js +0 -27
- package/lib/cjs/vertexai/embeddings/embeddings-image.js.map +0 -1
- package/lib/cjs/vertexai/embeddings/embeddings-text.js +0 -23
- package/lib/cjs/vertexai/embeddings/embeddings-text.js.map +0 -1
- package/lib/cjs/vertexai/index.js +0 -644
- package/lib/cjs/vertexai/index.js.map +0 -1
- package/lib/cjs/vertexai/models/claude.js +0 -72
- package/lib/cjs/vertexai/models/claude.js.map +0 -1
- package/lib/cjs/vertexai/models/gemini.js +0 -864
- package/lib/cjs/vertexai/models/gemini.js.map +0 -1
- package/lib/cjs/vertexai/models/imagen.js +0 -303
- package/lib/cjs/vertexai/models/imagen.js.map +0 -1
- package/lib/cjs/vertexai/models/llama.js +0 -183
- package/lib/cjs/vertexai/models/llama.js.map +0 -1
- package/lib/cjs/vertexai/models.js +0 -35
- package/lib/cjs/vertexai/models.js.map +0 -1
- package/lib/cjs/watsonx/index.js +0 -161
- package/lib/cjs/watsonx/index.js.map +0 -1
- package/lib/cjs/watsonx/interfaces.js +0 -3
- package/lib/cjs/xai/index.js +0 -65
- package/lib/cjs/xai/index.js.map +0 -1
- package/lib/esm/adobe/firefly.js +0 -116
- package/lib/esm/adobe/firefly.js.map +0 -1
- package/lib/esm/anthropic/index.js.map +0 -1
- package/lib/esm/azure/azure_foundry.js.map +0 -1
- package/lib/esm/bedrock/converse.js.map +0 -1
- package/lib/esm/bedrock/index.js.map +0 -1
- package/lib/esm/bedrock/nova-image-payload.js.map +0 -1
- package/lib/esm/bedrock/payloads.js.map +0 -1
- package/lib/esm/bedrock/s3.js.map +0 -1
- package/lib/esm/bedrock/twelvelabs.js.map +0 -1
- package/lib/esm/groq/index.js.map +0 -1
- package/lib/esm/huggingface_ie.js.map +0 -1
- package/lib/esm/index.js +0 -16
- package/lib/esm/index.js.map +0 -1
- package/lib/esm/mistral/index.js.map +0 -1
- package/lib/esm/mistral/types.js.map +0 -1
- package/lib/esm/openai/azure_openai.js.map +0 -1
- package/lib/esm/openai/index.js.map +0 -1
- package/lib/esm/openai/openai.js +0 -14
- package/lib/esm/openai/openai.js.map +0 -1
- package/lib/esm/openai/openai_compatible.js.map +0 -1
- package/lib/esm/openai/openai_format.js.map +0 -1
- package/lib/esm/replicate.js.map +0 -1
- package/lib/esm/shared/claude-messages.js.map +0 -1
- package/lib/esm/shared/claude-thinking.js.map +0 -1
- package/lib/esm/test-driver/TestErrorCompletionStream.js +0 -16
- package/lib/esm/test-driver/TestErrorCompletionStream.js.map +0 -1
- package/lib/esm/test-driver/TestValidationErrorCompletionStream.js.map +0 -1
- package/lib/esm/test-driver/index.js.map +0 -1
- package/lib/esm/test-driver/utils.js.map +0 -1
- package/lib/esm/togetherai/index.js +0 -122
- package/lib/esm/togetherai/index.js.map +0 -1
- package/lib/esm/togetherai/interfaces.js.map +0 -1
- package/lib/esm/vertexai/debug.js.map +0 -1
- package/lib/esm/vertexai/embeddings/embeddings-image.js +0 -24
- package/lib/esm/vertexai/embeddings/embeddings-image.js.map +0 -1
- package/lib/esm/vertexai/embeddings/embeddings-text.js +0 -20
- package/lib/esm/vertexai/embeddings/embeddings-text.js.map +0 -1
- package/lib/esm/vertexai/index.js.map +0 -1
- package/lib/esm/vertexai/models/claude.js.map +0 -1
- package/lib/esm/vertexai/models/gemini.js.map +0 -1
- package/lib/esm/vertexai/models/imagen.js.map +0 -1
- package/lib/esm/vertexai/models/llama.js.map +0 -1
- package/lib/esm/vertexai/models.js.map +0 -1
- package/lib/esm/watsonx/index.js.map +0 -1
- package/lib/esm/xai/index.js.map +0 -1
- package/lib/types/adobe/firefly.d.ts.map +0 -1
- package/lib/types/anthropic/index.d.ts.map +0 -1
- package/lib/types/azure/azure_foundry.d.ts.map +0 -1
- package/lib/types/bedrock/converse.d.ts.map +0 -1
- package/lib/types/bedrock/index.d.ts.map +0 -1
- package/lib/types/bedrock/nova-image-payload.d.ts.map +0 -1
- package/lib/types/bedrock/payloads.d.ts.map +0 -1
- package/lib/types/bedrock/s3.d.ts.map +0 -1
- package/lib/types/bedrock/twelvelabs.d.ts.map +0 -1
- package/lib/types/groq/index.d.ts.map +0 -1
- package/lib/types/huggingface_ie.d.ts.map +0 -1
- package/lib/types/index.d.ts +0 -16
- package/lib/types/index.d.ts.map +0 -1
- package/lib/types/mistral/index.d.ts.map +0 -1
- package/lib/types/mistral/types.d.ts.map +0 -1
- package/lib/types/openai/azure_openai.d.ts.map +0 -1
- package/lib/types/openai/index.d.ts.map +0 -1
- package/lib/types/openai/openai.d.ts.map +0 -1
- package/lib/types/openai/openai_compatible.d.ts.map +0 -1
- package/lib/types/openai/openai_format.d.ts.map +0 -1
- package/lib/types/replicate.d.ts.map +0 -1
- package/lib/types/shared/claude-messages.d.ts.map +0 -1
- package/lib/types/shared/claude-thinking.d.ts.map +0 -1
- package/lib/types/test-driver/TestErrorCompletionStream.d.ts.map +0 -1
- package/lib/types/test-driver/TestValidationErrorCompletionStream.d.ts.map +0 -1
- package/lib/types/test-driver/index.d.ts.map +0 -1
- package/lib/types/test-driver/utils.d.ts.map +0 -1
- package/lib/types/togetherai/index.d.ts +0 -23
- package/lib/types/togetherai/index.d.ts.map +0 -1
- package/lib/types/togetherai/interfaces.d.ts.map +0 -1
- package/lib/types/vertexai/debug.d.ts +0 -2
- package/lib/types/vertexai/debug.d.ts.map +0 -1
- package/lib/types/vertexai/embeddings/embeddings-image.d.ts +0 -11
- package/lib/types/vertexai/embeddings/embeddings-image.d.ts.map +0 -1
- package/lib/types/vertexai/embeddings/embeddings-text.d.ts +0 -10
- package/lib/types/vertexai/embeddings/embeddings-text.d.ts.map +0 -1
- package/lib/types/vertexai/index.d.ts.map +0 -1
- package/lib/types/vertexai/models/claude.d.ts.map +0 -1
- package/lib/types/vertexai/models/gemini.d.ts.map +0 -1
- package/lib/types/vertexai/models/imagen.d.ts.map +0 -1
- package/lib/types/vertexai/models/llama.d.ts.map +0 -1
- package/lib/types/vertexai/models.d.ts +0 -20
- package/lib/types/vertexai/models.d.ts.map +0 -1
- package/lib/types/watsonx/index.d.ts.map +0 -1
- package/lib/types/watsonx/interfaces.d.ts.map +0 -1
- package/lib/types/xai/index.d.ts.map +0 -1
- package/src/vertexai/embeddings/embeddings-image.ts +0 -52
- package/src/vertexai/embeddings/embeddings-text.ts +0 -54
- /package/lib/{esm/bedrock → bedrock}/payloads.js +0 -0
- /package/lib/{esm/mistral → mistral}/types.js +0 -0
- /package/lib/{esm/togetherai → togetherai}/interfaces.js +0 -0
- /package/lib/{types/watsonx → watsonx}/interfaces.d.ts +0 -0
- /package/lib/{esm/watsonx → watsonx}/interfaces.js +0 -0
package/src/bedrock/index.ts
CHANGED
|
@@ -1,72 +1,137 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Bedrock,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
Bedrock,
|
|
3
|
+
CreateModelCustomizationJobCommand,
|
|
4
|
+
type FoundationModelSummary,
|
|
5
|
+
GetModelCustomizationJobCommand,
|
|
6
|
+
type GetModelCustomizationJobCommandOutput,
|
|
7
|
+
ModelCustomizationJobStatus,
|
|
8
|
+
ModelModality,
|
|
9
|
+
StopModelCustomizationJobCommand,
|
|
10
|
+
} from '@aws-sdk/client-bedrock';
|
|
8
11
|
import {
|
|
9
|
-
|
|
12
|
+
BedrockRuntime,
|
|
13
|
+
type ContentBlock,
|
|
14
|
+
type ConverseRequest,
|
|
15
|
+
type ConverseResponse,
|
|
16
|
+
type ConverseStreamOutput,
|
|
17
|
+
type InferenceConfiguration,
|
|
18
|
+
type InvokeModelCommandOutput,
|
|
19
|
+
type Message,
|
|
20
|
+
type Tool,
|
|
21
|
+
type ToolResultContentBlock,
|
|
22
|
+
} from '@aws-sdk/client-bedrock-runtime';
|
|
23
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
|
24
|
+
import type { AwsCredentialIdentity, Provider } from '@aws-sdk/types';
|
|
25
|
+
import {
|
|
26
|
+
type AIModel,
|
|
10
27
|
type BedrockClaudeOptions,
|
|
11
28
|
type BedrockGptOssOptions,
|
|
12
29
|
type BedrockPalmyraOptions,
|
|
13
|
-
type Completion,
|
|
30
|
+
type Completion,
|
|
31
|
+
type CompletionChunkObject,
|
|
14
32
|
type CompletionResult,
|
|
15
33
|
type DataSource,
|
|
16
|
-
deserializeBinaryFromStorage,
|
|
17
34
|
type DriverOptions,
|
|
18
|
-
|
|
19
|
-
type
|
|
35
|
+
deserializeBinaryFromStorage,
|
|
36
|
+
type EmbeddingsOptions,
|
|
37
|
+
type EmbeddingsResult,
|
|
38
|
+
type ExecutionOptions,
|
|
39
|
+
type ExecutionTokenUsage,
|
|
20
40
|
getConversationMeta,
|
|
21
41
|
getMaxTokensLimitBedrock,
|
|
22
42
|
getModelCapabilities,
|
|
43
|
+
type HttpTimeoutOptions,
|
|
23
44
|
incrementConversationTurn,
|
|
24
45
|
isClaudeVersionGTE,
|
|
25
|
-
LlumiverseError,
|
|
26
|
-
|
|
46
|
+
LlumiverseError,
|
|
47
|
+
type LlumiverseErrorContext,
|
|
27
48
|
type ModelOptions,
|
|
49
|
+
modelModalitiesToArray,
|
|
28
50
|
type NovaCanvasOptions,
|
|
29
51
|
type PromptSegment,
|
|
30
52
|
type StatelessExecutionOptions,
|
|
31
53
|
stripBinaryFromConversation,
|
|
32
54
|
stripHeartbeatsFromConversation,
|
|
33
|
-
type TextFallbackOptions,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
55
|
+
type TextFallbackOptions,
|
|
56
|
+
type ToolDefinition,
|
|
57
|
+
type ToolUse,
|
|
58
|
+
type TrainingJob,
|
|
59
|
+
TrainingJobStatus,
|
|
60
|
+
type TrainingOptions,
|
|
61
|
+
truncateLargeTextInConversation,
|
|
62
|
+
} from '@llumiverse/core';
|
|
63
|
+
import { transformAsyncIterator } from '@llumiverse/core/async';
|
|
64
|
+
import { AbstractDriver } from '@llumiverse/core/driver';
|
|
65
|
+
import { formatNovaPrompt, type NovaMessagesPrompt } from '@llumiverse/core/formatters';
|
|
66
|
+
import { mergeDriverHttpTimeoutOptions, resolveDriverHttpTimeouts } from '@llumiverse/core/http-agent';
|
|
67
|
+
import { LRUCache } from 'mnemonist';
|
|
68
|
+
import { resolveClaudeThinking } from '../shared/claude-thinking.js';
|
|
69
|
+
import { truncateBinaryForDebug, uint8ArrayToBase64ForDebug } from '../shared/debug-prompt.js';
|
|
43
70
|
import {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
} from
|
|
71
|
+
converseConcatMessages,
|
|
72
|
+
converseJSONprefill,
|
|
73
|
+
converseSystemToMessages,
|
|
74
|
+
formatConversePrompt,
|
|
75
|
+
} from './converse.js';
|
|
76
|
+
import { generateBedrockEmbeddings } from './embeddings.js';
|
|
77
|
+
import { formatNovaImageGenerationPayload, NovaImageGenerationTaskType } from './nova-image-payload.js';
|
|
78
|
+
import { forceUploadFile } from './s3.js';
|
|
79
|
+
import { formatTwelvelabsPegasusPrompt, type TwelvelabsPegasusRequest } from './twelvelabs.js';
|
|
49
80
|
|
|
50
81
|
const supportStreamingCache = new LRUCache<string, boolean>(4096);
|
|
51
82
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
83
|
+
type AwsSdkError = {
|
|
84
|
+
name?: string;
|
|
85
|
+
message?: string;
|
|
86
|
+
$metadata?: {
|
|
87
|
+
httpStatusCode?: number;
|
|
88
|
+
requestId?: string;
|
|
89
|
+
};
|
|
90
|
+
$fault?: string;
|
|
91
|
+
};
|
|
92
|
+
type ReasoningBlockStart = {
|
|
93
|
+
reasoningContent?: {
|
|
94
|
+
redactedContent?: Uint8Array;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
type BedrockRuntimeExecutorScope = {
|
|
98
|
+
executor: BedrockRuntime;
|
|
99
|
+
close(): void;
|
|
57
100
|
};
|
|
58
101
|
|
|
102
|
+
enum BedrockModelType {
|
|
103
|
+
FoundationModel = 'foundation-model',
|
|
104
|
+
InferenceProfile = 'inference-profile',
|
|
105
|
+
CustomModel = 'custom-model',
|
|
106
|
+
Unknown = 'unknown',
|
|
107
|
+
}
|
|
108
|
+
|
|
59
109
|
function converseFinishReason(reason: string | undefined) {
|
|
60
110
|
//Possible values:
|
|
61
111
|
//end_turn | tool_use | max_tokens | stop_sequence | guardrail_intervened | content_filtered
|
|
62
112
|
if (!reason) return undefined;
|
|
63
113
|
switch (reason) {
|
|
64
|
-
case 'end_turn':
|
|
65
|
-
|
|
66
|
-
|
|
114
|
+
case 'end_turn':
|
|
115
|
+
return 'stop';
|
|
116
|
+
case 'max_tokens':
|
|
117
|
+
return 'length';
|
|
118
|
+
default:
|
|
119
|
+
return reason;
|
|
67
120
|
}
|
|
68
121
|
}
|
|
69
122
|
|
|
123
|
+
function withBedrockRuntimeScope<T>(iterable: AsyncIterable<T>, scope: BedrockRuntimeExecutorScope): AsyncIterable<T> {
|
|
124
|
+
return {
|
|
125
|
+
async *[Symbol.asyncIterator]() {
|
|
126
|
+
try {
|
|
127
|
+
yield* iterable;
|
|
128
|
+
} finally {
|
|
129
|
+
scope.close();
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
70
135
|
export interface BedrockModelCapabilities {
|
|
71
136
|
name: string;
|
|
72
137
|
canStream: boolean;
|
|
@@ -92,13 +157,12 @@ export interface BedrockDriverOptions extends DriverOptions {
|
|
|
92
157
|
* The credentials to use to access AWS (IAM access key + secret)
|
|
93
158
|
*/
|
|
94
159
|
credentials?: AwsCredentialIdentity | Provider<AwsCredentialIdentity>;
|
|
95
|
-
|
|
96
160
|
}
|
|
97
161
|
|
|
98
162
|
//Used to get a max_token value when not specified in the model options. Claude requires it to be set.
|
|
99
163
|
function maxTokenFallbackClaude(option: StatelessExecutionOptions): number {
|
|
100
164
|
const modelOptions = option.model_options as BedrockClaudeOptions | undefined;
|
|
101
|
-
if (modelOptions && typeof modelOptions.max_tokens ===
|
|
165
|
+
if (modelOptions && typeof modelOptions.max_tokens === 'number') {
|
|
102
166
|
return modelOptions.max_tokens;
|
|
103
167
|
} else {
|
|
104
168
|
let maxSupportedTokens = getMaxTokensLimitBedrock(option.model) ?? 8192; // Should always return a number for claude, 8192 is to satisfy the TypeScript type checker;
|
|
@@ -115,9 +179,173 @@ export type BedrockPrompt = NovaMessagesPrompt | ConverseRequest | TwelvelabsPeg
|
|
|
115
179
|
type BedrockSystemBlock = NonNullable<ConverseRequest['system']>[number];
|
|
116
180
|
type BedrockToolEntry = NonNullable<NonNullable<ConverseRequest['toolConfig']>['tools']>[number];
|
|
117
181
|
|
|
118
|
-
|
|
182
|
+
function formatBedrockBytes(bytes: Uint8Array | string | undefined): string | undefined {
|
|
183
|
+
if (bytes instanceof Uint8Array) {
|
|
184
|
+
return truncateBinaryForDebug(uint8ArrayToBase64ForDebug(bytes));
|
|
185
|
+
}
|
|
186
|
+
if (typeof bytes === 'string') {
|
|
187
|
+
return truncateBinaryForDebug(bytes);
|
|
188
|
+
}
|
|
189
|
+
return bytes;
|
|
190
|
+
}
|
|
119
191
|
|
|
120
|
-
|
|
192
|
+
function formatBedrockBytesForDebug(bytes: Uint8Array | string | undefined): Uint8Array {
|
|
193
|
+
// AWS SDK prompt types require Uint8Array here, but the debug prompt returned to
|
|
194
|
+
// Studio must be JSON-safe. Keep the mismatch contained to this conversion.
|
|
195
|
+
return formatBedrockBytes(bytes) as unknown as Uint8Array;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function formatBedrockContentBlockForDebug(block: ContentBlock): ContentBlock {
|
|
199
|
+
if (block.image?.source?.bytes) {
|
|
200
|
+
return {
|
|
201
|
+
...block,
|
|
202
|
+
image: {
|
|
203
|
+
...block.image,
|
|
204
|
+
source: {
|
|
205
|
+
...block.image.source,
|
|
206
|
+
bytes: formatBedrockBytesForDebug(block.image.source.bytes),
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
if (block.document?.source?.bytes) {
|
|
212
|
+
return {
|
|
213
|
+
...block,
|
|
214
|
+
document: {
|
|
215
|
+
...block.document,
|
|
216
|
+
source: {
|
|
217
|
+
...block.document.source,
|
|
218
|
+
bytes: formatBedrockBytesForDebug(block.document.source.bytes),
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
if (block.video?.source?.bytes) {
|
|
224
|
+
return {
|
|
225
|
+
...block,
|
|
226
|
+
video: {
|
|
227
|
+
...block.video,
|
|
228
|
+
source: {
|
|
229
|
+
...block.video.source,
|
|
230
|
+
bytes: formatBedrockBytesForDebug(block.video.source.bytes),
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
if (block.toolResult?.content) {
|
|
236
|
+
return {
|
|
237
|
+
...block,
|
|
238
|
+
toolResult: {
|
|
239
|
+
...block.toolResult,
|
|
240
|
+
content: block.toolResult.content.map(formatBedrockToolResultContentBlockForDebug),
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return block;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function formatBedrockToolResultContentBlockForDebug(block: ToolResultContentBlock): ToolResultContentBlock {
|
|
248
|
+
if (block.image?.source?.bytes) {
|
|
249
|
+
return {
|
|
250
|
+
...block,
|
|
251
|
+
image: {
|
|
252
|
+
...block.image,
|
|
253
|
+
source: {
|
|
254
|
+
...block.image.source,
|
|
255
|
+
bytes: formatBedrockBytesForDebug(block.image.source.bytes),
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
if (block.document?.source?.bytes) {
|
|
261
|
+
return {
|
|
262
|
+
...block,
|
|
263
|
+
document: {
|
|
264
|
+
...block.document,
|
|
265
|
+
source: {
|
|
266
|
+
...block.document.source,
|
|
267
|
+
bytes: formatBedrockBytesForDebug(block.document.source.bytes),
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
if (block.video?.source?.bytes) {
|
|
273
|
+
return {
|
|
274
|
+
...block,
|
|
275
|
+
video: {
|
|
276
|
+
...block.video,
|
|
277
|
+
source: {
|
|
278
|
+
...block.video.source,
|
|
279
|
+
bytes: formatBedrockBytesForDebug(block.video.source.bytes),
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
return block;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function formatConversePromptForDebug(prompt: ConverseRequest): ConverseRequest {
|
|
288
|
+
return {
|
|
289
|
+
...prompt,
|
|
290
|
+
messages: prompt.messages?.map((message) => ({
|
|
291
|
+
...message,
|
|
292
|
+
content: message.content?.map(formatBedrockContentBlockForDebug),
|
|
293
|
+
})),
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function formatNovaPromptForDebug(prompt: NovaMessagesPrompt): NovaMessagesPrompt {
|
|
298
|
+
return {
|
|
299
|
+
...prompt,
|
|
300
|
+
messages: prompt.messages.map((message) => ({
|
|
301
|
+
...message,
|
|
302
|
+
content: message.content.map((part) => {
|
|
303
|
+
if (!part.image?.source.bytes && !part.video?.source.bytes) {
|
|
304
|
+
return part;
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
...part,
|
|
308
|
+
image: part.image
|
|
309
|
+
? {
|
|
310
|
+
...part.image,
|
|
311
|
+
source: {
|
|
312
|
+
...part.image.source,
|
|
313
|
+
bytes: truncateBinaryForDebug(part.image.source.bytes),
|
|
314
|
+
},
|
|
315
|
+
}
|
|
316
|
+
: undefined,
|
|
317
|
+
video: part.video
|
|
318
|
+
? {
|
|
319
|
+
...part.video,
|
|
320
|
+
source: {
|
|
321
|
+
...part.video.source,
|
|
322
|
+
bytes: part.video.source.bytes
|
|
323
|
+
? truncateBinaryForDebug(part.video.source.bytes)
|
|
324
|
+
: undefined,
|
|
325
|
+
},
|
|
326
|
+
}
|
|
327
|
+
: undefined,
|
|
328
|
+
};
|
|
329
|
+
}),
|
|
330
|
+
})),
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function formatTwelvelabsPromptForDebug(prompt: TwelvelabsPegasusRequest): TwelvelabsPegasusRequest {
|
|
335
|
+
if (!prompt.mediaSource.base64String) {
|
|
336
|
+
return prompt;
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
...prompt,
|
|
340
|
+
mediaSource: {
|
|
341
|
+
...prompt.mediaSource,
|
|
342
|
+
base64String: truncateBinaryForDebug(prompt.mediaSource.base64String),
|
|
343
|
+
},
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockPrompt> {
|
|
348
|
+
static PROVIDER = 'bedrock';
|
|
121
349
|
|
|
122
350
|
provider = BedrockDriver.PROVIDER;
|
|
123
351
|
|
|
@@ -132,21 +360,63 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
132
360
|
}
|
|
133
361
|
}
|
|
134
362
|
|
|
135
|
-
|
|
363
|
+
/**
|
|
364
|
+
* Build a Smithy `requestHandler` config from the driver's
|
|
365
|
+
* `httpTimeout` so AWS SDK calls fail fast on hung upstream Bedrock
|
|
366
|
+
* endpoints instead of using the AWS default (no request timeout).
|
|
367
|
+
* Returns a partial config the SDK merges into its default handler.
|
|
368
|
+
*/
|
|
369
|
+
private getBedrockRequestHandlerConfig(httpTimeout?: HttpTimeoutOptions) {
|
|
370
|
+
const timeouts = resolveDriverHttpTimeouts(
|
|
371
|
+
mergeDriverHttpTimeoutOptions(this.options.httpTimeout, httpTimeout),
|
|
372
|
+
);
|
|
373
|
+
return {
|
|
374
|
+
requestTimeout: timeouts.headersTimeout,
|
|
375
|
+
throwOnRequestTimeout: true,
|
|
376
|
+
connectionTimeout: timeouts.connectTimeout,
|
|
377
|
+
socketTimeout: timeouts.bodyTimeout,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
private createExecutor(httpTimeout?: HttpTimeoutOptions) {
|
|
382
|
+
return new BedrockRuntime({
|
|
383
|
+
region: this.options.region,
|
|
384
|
+
credentials: this.options.credentials,
|
|
385
|
+
requestHandler: this.getBedrockRequestHandlerConfig(httpTimeout),
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
getExecutor(httpTimeout?: HttpTimeoutOptions) {
|
|
390
|
+
if (httpTimeout) {
|
|
391
|
+
return this.createExecutor(httpTimeout);
|
|
392
|
+
}
|
|
136
393
|
if (!this._executor) {
|
|
137
|
-
this._executor =
|
|
138
|
-
region: this.options.region,
|
|
139
|
-
credentials: this.options.credentials,
|
|
140
|
-
});
|
|
394
|
+
this._executor = this.createExecutor();
|
|
141
395
|
}
|
|
142
396
|
return this._executor;
|
|
143
397
|
}
|
|
144
398
|
|
|
399
|
+
private getScopedExecutor(options: Pick<ExecutionOptions, 'httpTimeout'>): BedrockRuntimeExecutorScope {
|
|
400
|
+
if (!options.httpTimeout) {
|
|
401
|
+
return {
|
|
402
|
+
executor: this.getExecutor(),
|
|
403
|
+
close: () => undefined,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const executor = this.getExecutor(options.httpTimeout);
|
|
408
|
+
return {
|
|
409
|
+
executor,
|
|
410
|
+
close: () => executor.destroy(),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
145
414
|
getService(region: string = this.options.region) {
|
|
146
415
|
if (!this._service || this._service_region !== region) {
|
|
147
416
|
this._service = new Bedrock({
|
|
148
417
|
region: region,
|
|
149
418
|
credentials: this.options.credentials,
|
|
419
|
+
requestHandler: this.getBedrockRequestHandlerConfig(),
|
|
150
420
|
});
|
|
151
421
|
this._service_region = region;
|
|
152
422
|
}
|
|
@@ -154,34 +424,41 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
154
424
|
}
|
|
155
425
|
|
|
156
426
|
protected async formatPrompt(segments: PromptSegment[], opts: ExecutionOptions): Promise<BedrockPrompt> {
|
|
157
|
-
if (opts.model.includes(
|
|
427
|
+
if (opts.model.includes('canvas')) {
|
|
158
428
|
return await formatNovaPrompt(segments, opts.result_schema);
|
|
159
429
|
}
|
|
160
|
-
if (opts.model.includes(
|
|
430
|
+
if (opts.model.includes('twelvelabs.pegasus')) {
|
|
161
431
|
return await formatTwelvelabsPegasusPrompt(segments, opts);
|
|
162
432
|
}
|
|
163
433
|
return await formatConversePrompt(segments, opts);
|
|
164
434
|
}
|
|
165
435
|
|
|
436
|
+
public formatDebugPrompt(prompt: BedrockPrompt): BedrockPrompt {
|
|
437
|
+
if ('mediaSource' in prompt) {
|
|
438
|
+
return formatTwelvelabsPromptForDebug(prompt);
|
|
439
|
+
}
|
|
440
|
+
if ('modelId' in prompt) {
|
|
441
|
+
return formatConversePromptForDebug(prompt);
|
|
442
|
+
}
|
|
443
|
+
return formatNovaPromptForDebug(prompt);
|
|
444
|
+
}
|
|
445
|
+
|
|
166
446
|
/**
|
|
167
447
|
* Format AWS Bedrock errors into LlumiverseError with proper status codes and retryability.
|
|
168
|
-
*
|
|
448
|
+
*
|
|
169
449
|
* AWS SDK errors provide:
|
|
170
450
|
* - error.name: The exception type (e.g., "ThrottlingException")
|
|
171
451
|
* - error.$metadata.httpStatusCode: The HTTP status code
|
|
172
452
|
* - error.$metadata.requestId: The AWS request ID for tracking
|
|
173
453
|
* - error.$fault: "client" or "server" indicating error category
|
|
174
|
-
*
|
|
454
|
+
*
|
|
175
455
|
* @param error - The AWS SDK error
|
|
176
456
|
* @param context - Context about where the error occurred
|
|
177
457
|
* @returns A standardized LlumiverseError
|
|
178
458
|
*/
|
|
179
|
-
public formatLlumiverseError(
|
|
180
|
-
error: unknown,
|
|
181
|
-
context: LlumiverseErrorContext
|
|
182
|
-
): LlumiverseError {
|
|
459
|
+
public formatLlumiverseError(error: unknown, context: LlumiverseErrorContext): LlumiverseError {
|
|
183
460
|
// Check if it's an AWS SDK error with $metadata
|
|
184
|
-
const awsError = error as
|
|
461
|
+
const awsError = error as AwsSdkError;
|
|
185
462
|
const hasMetadata = awsError?.$metadata !== undefined;
|
|
186
463
|
|
|
187
464
|
if (!hasMetadata) {
|
|
@@ -232,13 +509,13 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
232
509
|
context,
|
|
233
510
|
error,
|
|
234
511
|
httpStatusCode, // Only set code if we have numeric status code
|
|
235
|
-
errorName
|
|
512
|
+
errorName, // Preserve AWS error name
|
|
236
513
|
);
|
|
237
514
|
}
|
|
238
515
|
|
|
239
516
|
/**
|
|
240
517
|
* Determine if a Bedrock error is retryable based on error type and status.
|
|
241
|
-
*
|
|
518
|
+
*
|
|
242
519
|
* Retryable errors:
|
|
243
520
|
* - ThrottlingException: Rate limit exceeded, retry with backoff
|
|
244
521
|
* - ServiceUnavailableException: Service temporarily down
|
|
@@ -246,7 +523,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
246
523
|
* - ServiceQuotaExceededException: Quota exhausted, may recover
|
|
247
524
|
* - 5xx status codes: Server errors
|
|
248
525
|
* - 429, 408 status codes: Rate limit, timeout
|
|
249
|
-
*
|
|
526
|
+
*
|
|
250
527
|
* Non-retryable errors:
|
|
251
528
|
* - ValidationException: Invalid request parameters
|
|
252
529
|
* - AccessDeniedException: Authentication/authorization failure
|
|
@@ -254,7 +531,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
254
531
|
* - ConflictException: Resource state conflict
|
|
255
532
|
* - ResourceInUseException: Resource locked by another operation
|
|
256
533
|
* - 4xx status codes (except 429, 408): Client errors
|
|
257
|
-
*
|
|
534
|
+
*
|
|
258
535
|
* @param errorName - The AWS error name (e.g., "ThrottlingException")
|
|
259
536
|
* @param httpStatusCode - The HTTP status code if available
|
|
260
537
|
* @param fault - The fault type ("client" or "server")
|
|
@@ -263,7 +540,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
263
540
|
private isBedrockErrorRetryable(
|
|
264
541
|
errorName: string,
|
|
265
542
|
httpStatusCode: number | undefined,
|
|
266
|
-
fault: string | undefined
|
|
543
|
+
fault: string | undefined,
|
|
267
544
|
): boolean | undefined {
|
|
268
545
|
// Check specific AWS error types first
|
|
269
546
|
switch (errorName) {
|
|
@@ -300,9 +577,13 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
300
577
|
return undefined;
|
|
301
578
|
}
|
|
302
579
|
|
|
303
|
-
getExtractedExecution(
|
|
304
|
-
|
|
305
|
-
|
|
580
|
+
getExtractedExecution(
|
|
581
|
+
result: ConverseResponse,
|
|
582
|
+
_prompt?: BedrockPrompt,
|
|
583
|
+
options?: ExecutionOptions,
|
|
584
|
+
): CompletionChunkObject {
|
|
585
|
+
let resultText = '';
|
|
586
|
+
let reasoning = '';
|
|
306
587
|
|
|
307
588
|
if (result.output?.message?.content) {
|
|
308
589
|
for (const content of result.output.message.content) {
|
|
@@ -323,14 +604,14 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
323
604
|
reasoning += `[Redacted thinking: ${redactedData}]`;
|
|
324
605
|
}
|
|
325
606
|
} else {
|
|
326
|
-
this.logger.info(
|
|
607
|
+
this.logger.info('[Bedrock] Not outputting reasoning content as include_thoughts is false');
|
|
327
608
|
}
|
|
328
609
|
} else {
|
|
329
610
|
// Get content block type
|
|
330
611
|
const type = Object.keys(content).find(
|
|
331
|
-
key => key !== '$unknown' && content[key as keyof typeof content] !== undefined
|
|
612
|
+
(key) => key !== '$unknown' && content[key as keyof typeof content] !== undefined,
|
|
332
613
|
);
|
|
333
|
-
this.logger.info({ type },
|
|
614
|
+
this.logger.info({ type }, '[Bedrock] Unsupported content response type:');
|
|
334
615
|
}
|
|
335
616
|
}
|
|
336
617
|
|
|
@@ -341,14 +622,18 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
341
622
|
}
|
|
342
623
|
|
|
343
624
|
const completionResult: CompletionChunkObject = {
|
|
344
|
-
result: reasoning + resultText ? [{ type:
|
|
625
|
+
result: reasoning + resultText ? [{ type: 'text', value: reasoning + resultText }] : [],
|
|
345
626
|
token_usage: {
|
|
346
627
|
// Bedrock's inputTokens already excludes cache-read tokens,
|
|
347
628
|
// so prompt_new is inputTokens directly (no subtraction needed).
|
|
348
629
|
// prompt is the total including cached + cache_write for consistency
|
|
349
630
|
// with the Vertex Claude driver.
|
|
350
631
|
prompt_new: result.usage?.inputTokens,
|
|
351
|
-
prompt: result.usage
|
|
632
|
+
prompt: result.usage
|
|
633
|
+
? (result.usage.inputTokens ?? 0) +
|
|
634
|
+
(result.usage.cacheReadInputTokens ?? 0) +
|
|
635
|
+
(result.usage.cacheWriteInputTokens ?? 0)
|
|
636
|
+
: undefined,
|
|
352
637
|
result: result.usage?.outputTokens,
|
|
353
638
|
total: result.usage?.totalTokens,
|
|
354
639
|
prompt_cached: result.usage?.cacheReadInputTokens ?? undefined,
|
|
@@ -358,32 +643,46 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
358
643
|
};
|
|
359
644
|
|
|
360
645
|
return completionResult;
|
|
361
|
-
}
|
|
646
|
+
}
|
|
362
647
|
|
|
363
|
-
getExtractedStream(
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
648
|
+
getExtractedStream(
|
|
649
|
+
result: ConverseStreamOutput,
|
|
650
|
+
_prompt?: BedrockPrompt,
|
|
651
|
+
options?: ExecutionOptions,
|
|
652
|
+
streamingToolBlocks?: Map<number, { id: string; name: string }>,
|
|
653
|
+
): CompletionChunkObject {
|
|
654
|
+
let output: string = '';
|
|
655
|
+
let reasoning: string = '';
|
|
656
|
+
let stop_reason = '';
|
|
367
657
|
let token_usage: ExecutionTokenUsage | undefined;
|
|
368
|
-
let tool_use: ToolUse[] | undefined;
|
|
658
|
+
let tool_use: ToolUse<unknown>[] | undefined;
|
|
369
659
|
|
|
370
660
|
// Check if we should include thoughts (always true for reasoning-only models like DeepSeek R1)
|
|
371
661
|
const isReasoningModel = options?.model?.includes('deepseek') && options?.model?.includes('r1');
|
|
372
|
-
const shouldIncludeThoughts =
|
|
662
|
+
const shouldIncludeThoughts =
|
|
663
|
+
isReasoningModel || (options && (options.model_options as BedrockClaudeOptions)?.include_thoughts);
|
|
373
664
|
|
|
374
665
|
// Handle content block start events (for reasoning blocks and tool use)
|
|
375
666
|
if (result.contentBlockStart) {
|
|
376
|
-
if (
|
|
667
|
+
if (
|
|
668
|
+
result.contentBlockStart.start &&
|
|
669
|
+
'toolUse' in result.contentBlockStart.start &&
|
|
670
|
+
result.contentBlockStart.start.toolUse
|
|
671
|
+
) {
|
|
377
672
|
// Register new tool call block and emit an initial chunk so the accumulator can track it by id
|
|
378
673
|
const toolUseStart = result.contentBlockStart.start.toolUse;
|
|
379
674
|
const blockIndex = result.contentBlockStart.contentBlockIndex ?? -1;
|
|
380
675
|
const id = toolUseStart.toolUseId ?? '';
|
|
381
676
|
const name = toolUseStart.name ?? '';
|
|
382
677
|
streamingToolBlocks?.set(blockIndex, { id, name });
|
|
383
|
-
tool_use = [{ id, tool_name: name, tool_input: ''
|
|
384
|
-
} else if (
|
|
678
|
+
tool_use = [{ id, tool_name: name, tool_input: '' }];
|
|
679
|
+
} else if (
|
|
680
|
+
result.contentBlockStart.start &&
|
|
681
|
+
'reasoningContent' in result.contentBlockStart.start &&
|
|
682
|
+
shouldIncludeThoughts
|
|
683
|
+
) {
|
|
385
684
|
// Handle redacted content at block start
|
|
386
|
-
const reasoningStart = result.contentBlockStart.start as
|
|
685
|
+
const reasoningStart = result.contentBlockStart.start as ReasoningBlockStart;
|
|
387
686
|
if (reasoningStart.reasoningContent?.redactedContent) {
|
|
388
687
|
const redactedData = new TextDecoder().decode(reasoningStart.reasoningContent.redactedContent);
|
|
389
688
|
reasoning = `[Redacted thinking: ${redactedData}]`;
|
|
@@ -399,7 +698,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
399
698
|
const blockIndex = result.contentBlockDelta.contentBlockIndex ?? -1;
|
|
400
699
|
const toolBlock = streamingToolBlocks?.get(blockIndex);
|
|
401
700
|
if (toolBlock && delta.toolUse.input !== undefined) {
|
|
402
|
-
tool_use = [{ id: toolBlock.id, tool_name: '', tool_input: delta.toolUse.input
|
|
701
|
+
tool_use = [{ id: toolBlock.id, tool_name: '', tool_input: delta.toolUse.input }];
|
|
403
702
|
}
|
|
404
703
|
} else if (delta?.text) {
|
|
405
704
|
output = delta.text;
|
|
@@ -411,16 +710,16 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
411
710
|
reasoning = `[Redacted thinking: ${redactedData}]`;
|
|
412
711
|
} else if (delta.reasoningContent.signature) {
|
|
413
712
|
// Handle signature updates for reasoning content - end of thinking
|
|
414
|
-
reasoning =
|
|
713
|
+
reasoning = '\n\n';
|
|
415
714
|
// Putting logging here so it only triggers once.
|
|
416
|
-
this.logger.info(
|
|
715
|
+
this.logger.info('[Bedrock] Not outputting reasoning content as include_thoughts is false');
|
|
417
716
|
}
|
|
418
717
|
} else if (delta) {
|
|
419
718
|
// Get content block type
|
|
420
719
|
const type = Object.keys(delta).find(
|
|
421
|
-
key => key !== '$unknown' && (delta as
|
|
720
|
+
(key) => key !== '$unknown' && (delta as unknown as Record<string, unknown>)[key] !== undefined,
|
|
422
721
|
);
|
|
423
|
-
this.logger.info({ type },
|
|
722
|
+
this.logger.info({ type }, '[Bedrock] Unsupported content response type:');
|
|
424
723
|
}
|
|
425
724
|
}
|
|
426
725
|
|
|
@@ -436,29 +735,33 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
436
735
|
}
|
|
437
736
|
|
|
438
737
|
if (result.messageStop) {
|
|
439
|
-
stop_reason = result.messageStop.stopReason ??
|
|
738
|
+
stop_reason = result.messageStop.stopReason ?? '';
|
|
440
739
|
}
|
|
441
740
|
|
|
442
741
|
if (result.metadata) {
|
|
443
742
|
token_usage = {
|
|
444
743
|
prompt_new: result.metadata.usage?.inputTokens,
|
|
445
|
-
prompt: result.metadata.usage
|
|
744
|
+
prompt: result.metadata.usage
|
|
745
|
+
? (result.metadata.usage.inputTokens ?? 0) +
|
|
746
|
+
(result.metadata.usage.cacheReadInputTokens ?? 0) +
|
|
747
|
+
(result.metadata.usage.cacheWriteInputTokens ?? 0)
|
|
748
|
+
: undefined,
|
|
446
749
|
result: result.metadata.usage?.outputTokens,
|
|
447
750
|
total: result.metadata.usage?.totalTokens,
|
|
448
751
|
prompt_cached: result.metadata.usage?.cacheReadInputTokens ?? undefined,
|
|
449
752
|
prompt_cache_write: result.metadata.usage?.cacheWriteInputTokens ?? undefined,
|
|
450
|
-
}
|
|
753
|
+
};
|
|
451
754
|
}
|
|
452
755
|
|
|
453
756
|
const completionResult: CompletionChunkObject = {
|
|
454
|
-
result: reasoning + output ? [{ type:
|
|
757
|
+
result: reasoning + output ? [{ type: 'text', value: reasoning + output }] : [],
|
|
455
758
|
token_usage: token_usage,
|
|
456
759
|
finish_reason: converseFinishReason(stop_reason),
|
|
457
760
|
tool_use,
|
|
458
761
|
};
|
|
459
762
|
|
|
460
763
|
return completionResult;
|
|
461
|
-
}
|
|
764
|
+
}
|
|
462
765
|
|
|
463
766
|
extractRegion(modelString: string, defaultRegion: string): string {
|
|
464
767
|
// Match region in full ARN pattern
|
|
@@ -468,7 +771,9 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
468
771
|
}
|
|
469
772
|
|
|
470
773
|
// Match common AWS regions directly in string
|
|
471
|
-
const regionMatch = modelString.match(
|
|
774
|
+
const regionMatch = modelString.match(
|
|
775
|
+
/(?:us|eu|ap|sa|ca|me|af)[-](east|west|central|south|north|southeast|southwest|northeast|northwest)[-][1-9]/,
|
|
776
|
+
);
|
|
472
777
|
if (regionMatch) {
|
|
473
778
|
return regionMatch[0];
|
|
474
779
|
}
|
|
@@ -478,12 +783,12 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
478
783
|
|
|
479
784
|
private async getCanStream(model: string, type: BedrockModelType): Promise<boolean> {
|
|
480
785
|
let canStream: boolean = false;
|
|
481
|
-
let error:
|
|
786
|
+
let error: unknown = null;
|
|
482
787
|
const region = this.extractRegion(model, this.options.region);
|
|
483
788
|
if (type === BedrockModelType.FoundationModel || type === BedrockModelType.Unknown) {
|
|
484
789
|
try {
|
|
485
790
|
const response = await this.getService(region).getFoundationModel({
|
|
486
|
-
modelIdentifier: model
|
|
791
|
+
modelIdentifier: model,
|
|
487
792
|
});
|
|
488
793
|
canStream = response.modelDetails?.responseStreamingSupported ?? false;
|
|
489
794
|
return canStream;
|
|
@@ -494,9 +799,12 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
494
799
|
if (type === BedrockModelType.InferenceProfile || type === BedrockModelType.Unknown) {
|
|
495
800
|
try {
|
|
496
801
|
const response = await this.getService(region).getInferenceProfile({
|
|
497
|
-
inferenceProfileIdentifier: model
|
|
802
|
+
inferenceProfileIdentifier: model,
|
|
498
803
|
});
|
|
499
|
-
canStream = await this.getCanStream(
|
|
804
|
+
canStream = await this.getCanStream(
|
|
805
|
+
response.models?.[0].modelArn ?? '',
|
|
806
|
+
BedrockModelType.FoundationModel,
|
|
807
|
+
);
|
|
500
808
|
return canStream;
|
|
501
809
|
} catch (e) {
|
|
502
810
|
error = e;
|
|
@@ -505,16 +813,16 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
505
813
|
if (type === BedrockModelType.CustomModel || type === BedrockModelType.Unknown) {
|
|
506
814
|
try {
|
|
507
815
|
const response = await this.getService(region).getCustomModel({
|
|
508
|
-
modelIdentifier: model
|
|
816
|
+
modelIdentifier: model,
|
|
509
817
|
});
|
|
510
|
-
canStream = await this.getCanStream(response.baseModelArn ??
|
|
818
|
+
canStream = await this.getCanStream(response.baseModelArn ?? '', BedrockModelType.FoundationModel);
|
|
511
819
|
return canStream;
|
|
512
820
|
} catch (e) {
|
|
513
821
|
error = e;
|
|
514
822
|
}
|
|
515
823
|
}
|
|
516
824
|
if (error) {
|
|
517
|
-
console.warn(
|
|
825
|
+
console.warn(`Error on canStream check for model: ${model} region detected: ${region}`, error);
|
|
518
826
|
}
|
|
519
827
|
return canStream;
|
|
520
828
|
}
|
|
@@ -528,11 +836,11 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
528
836
|
let canStream = supportStreamingCache.get(options.model);
|
|
529
837
|
if (canStream == null) {
|
|
530
838
|
let type = BedrockModelType.Unknown;
|
|
531
|
-
if (options.model.includes(
|
|
839
|
+
if (options.model.includes('foundation-model')) {
|
|
532
840
|
type = BedrockModelType.FoundationModel;
|
|
533
|
-
} else if (options.model.includes(
|
|
841
|
+
} else if (options.model.includes('inference-profile')) {
|
|
534
842
|
type = BedrockModelType.InferenceProfile;
|
|
535
|
-
} else if (options.model.includes(
|
|
843
|
+
} else if (options.model.includes('custom-model')) {
|
|
536
844
|
type = BedrockModelType.CustomModel;
|
|
537
845
|
}
|
|
538
846
|
canStream = await this.getCanStream(options.model, type);
|
|
@@ -549,10 +857,10 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
549
857
|
prompt: BedrockPrompt,
|
|
550
858
|
result: unknown[],
|
|
551
859
|
toolUse: unknown[] | undefined,
|
|
552
|
-
options: ExecutionOptions
|
|
860
|
+
options: ExecutionOptions,
|
|
553
861
|
): ConverseRequest | undefined {
|
|
554
862
|
// Only handle ConverseRequest prompts (not NovaMessagesPrompt or TwelvelabsPegasusRequest)
|
|
555
|
-
if (options.model.includes(
|
|
863
|
+
if (options.model.includes('canvas') || options.model.includes('twelvelabs.pegasus')) {
|
|
556
864
|
return undefined;
|
|
557
865
|
}
|
|
558
866
|
|
|
@@ -561,7 +869,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
561
869
|
|
|
562
870
|
// Convert accumulated results to text content for assistant message
|
|
563
871
|
const textContent = completionResults
|
|
564
|
-
.map(r => {
|
|
872
|
+
.map((r) => {
|
|
565
873
|
switch (r.type) {
|
|
566
874
|
case 'text':
|
|
567
875
|
return r.value;
|
|
@@ -570,8 +878,10 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
570
878
|
case 'image':
|
|
571
879
|
// Skip images in conversation - they're in the result
|
|
572
880
|
return '';
|
|
573
|
-
default:
|
|
574
|
-
|
|
881
|
+
default: {
|
|
882
|
+
const _exhaustive: never = r;
|
|
883
|
+
return String(_exhaustive);
|
|
884
|
+
}
|
|
575
885
|
}
|
|
576
886
|
})
|
|
577
887
|
.join('');
|
|
@@ -583,7 +893,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
583
893
|
let conversation = updateConversation(incomingConversation, conversePrompt);
|
|
584
894
|
|
|
585
895
|
// Build assistant message content
|
|
586
|
-
const messageContent:
|
|
896
|
+
const messageContent: ContentBlock[] = [];
|
|
587
897
|
if (textContent) {
|
|
588
898
|
messageContent.push({ text: textContent });
|
|
589
899
|
}
|
|
@@ -595,17 +905,19 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
595
905
|
toolUseId: tool.id,
|
|
596
906
|
name: tool.tool_name,
|
|
597
907
|
input: tool.tool_input,
|
|
598
|
-
}
|
|
908
|
+
},
|
|
599
909
|
});
|
|
600
910
|
}
|
|
601
911
|
}
|
|
602
912
|
|
|
603
913
|
// Add assistant message
|
|
604
914
|
const assistantMessage: ConverseRequest = {
|
|
605
|
-
messages: [
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
915
|
+
messages: [
|
|
916
|
+
{
|
|
917
|
+
content: messageContent.length > 0 ? messageContent : [{ text: '' }],
|
|
918
|
+
role: 'assistant',
|
|
919
|
+
},
|
|
920
|
+
],
|
|
609
921
|
modelId: conversePrompt.modelId,
|
|
610
922
|
};
|
|
611
923
|
conversation = updateConversation(conversation, assistantMessage);
|
|
@@ -618,7 +930,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
618
930
|
const stripOptions = {
|
|
619
931
|
keepForTurns: options.stripImagesAfterTurns ?? Infinity,
|
|
620
932
|
currentTurn,
|
|
621
|
-
textMaxTokens: options.stripTextMaxTokens
|
|
933
|
+
textMaxTokens: options.stripTextMaxTokens,
|
|
622
934
|
};
|
|
623
935
|
let processedConversation = stripBinaryFromConversation(conversation, stripOptions);
|
|
624
936
|
processedConversation = truncateLargeTextInConversation(processedConversation, stripOptions);
|
|
@@ -632,7 +944,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
632
944
|
|
|
633
945
|
async requestTextCompletion(prompt: BedrockPrompt, options: ExecutionOptions): Promise<Completion> {
|
|
634
946
|
// Handle Twelvelabs Pegasus models
|
|
635
|
-
if (options.model.includes(
|
|
947
|
+
if (options.model.includes('twelvelabs.pegasus')) {
|
|
636
948
|
return this.requestTwelvelabsPegasusCompletion(prompt as TwelvelabsPegasusRequest, options);
|
|
637
949
|
}
|
|
638
950
|
|
|
@@ -644,17 +956,22 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
644
956
|
let conversation = updateConversation(incomingConversation, conversePrompt);
|
|
645
957
|
|
|
646
958
|
const payload = this.preparePayload(conversation, options);
|
|
647
|
-
const
|
|
959
|
+
const executorScope = this.getScopedExecutor(options);
|
|
648
960
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
961
|
+
let res: ConverseResponse;
|
|
962
|
+
try {
|
|
963
|
+
res = await executorScope.executor.converse({
|
|
964
|
+
...payload,
|
|
965
|
+
});
|
|
966
|
+
} finally {
|
|
967
|
+
executorScope.close();
|
|
968
|
+
}
|
|
652
969
|
|
|
653
970
|
// Strip reasoningContent from assistant messages before storing in conversation
|
|
654
971
|
// (DeepSeek R1 returns reasoning blocks but rejects them in subsequent user turns)
|
|
655
|
-
const assistantMsg = res.output?.message ?? { content: [{ text:
|
|
972
|
+
const assistantMsg = res.output?.message ?? { content: [{ text: '' }], role: 'assistant' };
|
|
656
973
|
if (assistantMsg.content) {
|
|
657
|
-
assistantMsg.content = assistantMsg.content.filter((c
|
|
974
|
+
assistantMsg.content = assistantMsg.content.filter((c) => !('reasoningContent' in c));
|
|
658
975
|
}
|
|
659
976
|
|
|
660
977
|
conversation = updateConversation(conversation, {
|
|
@@ -665,15 +982,15 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
665
982
|
// Increment turn counter for deferred stripping
|
|
666
983
|
conversation = incrementConversationTurn(conversation) as ConverseRequest;
|
|
667
984
|
|
|
668
|
-
let tool_use: ToolUse[] | undefined
|
|
985
|
+
let tool_use: ToolUse<unknown>[] | undefined;
|
|
669
986
|
//Get tool requests, we check tool use regardless of finish reason, as you can hit length and still get a valid response.
|
|
670
|
-
tool_use = res.output?.message?.content?.reduce((tools: ToolUse[], c) => {
|
|
987
|
+
tool_use = res.output?.message?.content?.reduce((tools: ToolUse<unknown>[], c) => {
|
|
671
988
|
if (c.toolUse) {
|
|
672
989
|
tools.push({
|
|
673
|
-
tool_name: c.toolUse.name ??
|
|
674
|
-
tool_input: c.toolUse.input
|
|
675
|
-
id: c.toolUse.toolUseId ??
|
|
676
|
-
} satisfies ToolUse);
|
|
990
|
+
tool_name: c.toolUse.name ?? '',
|
|
991
|
+
tool_input: c.toolUse.input,
|
|
992
|
+
id: c.toolUse.toolUseId ?? '',
|
|
993
|
+
} satisfies ToolUse<unknown>);
|
|
677
994
|
}
|
|
678
995
|
return tools;
|
|
679
996
|
}, []);
|
|
@@ -687,7 +1004,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
687
1004
|
const stripOptions = {
|
|
688
1005
|
keepForTurns: options.stripImagesAfterTurns ?? Infinity,
|
|
689
1006
|
currentTurn,
|
|
690
|
-
textMaxTokens: options.stripTextMaxTokens
|
|
1007
|
+
textMaxTokens: options.stripTextMaxTokens,
|
|
691
1008
|
};
|
|
692
1009
|
let processedConversation = stripBinaryFromConversation(conversation, stripOptions);
|
|
693
1010
|
|
|
@@ -710,15 +1027,23 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
710
1027
|
return completion;
|
|
711
1028
|
}
|
|
712
1029
|
|
|
713
|
-
private async requestTwelvelabsPegasusCompletion(
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
1030
|
+
private async requestTwelvelabsPegasusCompletion(
|
|
1031
|
+
prompt: TwelvelabsPegasusRequest,
|
|
1032
|
+
options: ExecutionOptions,
|
|
1033
|
+
): Promise<Completion> {
|
|
1034
|
+
const executorScope = this.getScopedExecutor(options);
|
|
1035
|
+
|
|
1036
|
+
let res: InvokeModelCommandOutput;
|
|
1037
|
+
try {
|
|
1038
|
+
res = await executorScope.executor.invokeModel({
|
|
1039
|
+
modelId: options.model,
|
|
1040
|
+
contentType: 'application/json',
|
|
1041
|
+
accept: 'application/json',
|
|
1042
|
+
body: JSON.stringify(prompt),
|
|
1043
|
+
});
|
|
1044
|
+
} finally {
|
|
1045
|
+
executorScope.close();
|
|
1046
|
+
}
|
|
722
1047
|
|
|
723
1048
|
const decoder = new TextDecoder();
|
|
724
1049
|
const body = decoder.decode(res.body);
|
|
@@ -727,81 +1052,96 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
727
1052
|
// Extract the response according to TwelveLabs Pegasus format
|
|
728
1053
|
let finishReason: string | undefined;
|
|
729
1054
|
switch (result.finishReason) {
|
|
730
|
-
case
|
|
731
|
-
finishReason =
|
|
1055
|
+
case 'stop':
|
|
1056
|
+
finishReason = 'stop';
|
|
732
1057
|
break;
|
|
733
|
-
case
|
|
734
|
-
finishReason =
|
|
1058
|
+
case 'length':
|
|
1059
|
+
finishReason = 'length';
|
|
735
1060
|
break;
|
|
736
1061
|
default:
|
|
737
1062
|
finishReason = result.finishReason;
|
|
738
1063
|
}
|
|
739
1064
|
|
|
740
1065
|
return {
|
|
741
|
-
result: result.message ? [{ type:
|
|
1066
|
+
result: result.message ? [{ type: 'text' as const, value: result.message }] : [],
|
|
742
1067
|
finish_reason: finishReason,
|
|
743
1068
|
original_response: options.include_original_response ? result : undefined,
|
|
744
1069
|
};
|
|
745
1070
|
}
|
|
746
1071
|
|
|
747
|
-
private async requestTwelvelabsPegasusCompletionStream(
|
|
748
|
-
|
|
1072
|
+
private async requestTwelvelabsPegasusCompletionStream(
|
|
1073
|
+
prompt: TwelvelabsPegasusRequest,
|
|
1074
|
+
options: ExecutionOptions,
|
|
1075
|
+
): Promise<AsyncIterable<CompletionChunkObject>> {
|
|
1076
|
+
const executorScope = this.getScopedExecutor(options);
|
|
1077
|
+
|
|
1078
|
+
try {
|
|
1079
|
+
const res = await executorScope.executor.invokeModelWithResponseStream({
|
|
1080
|
+
modelId: options.model,
|
|
1081
|
+
contentType: 'application/json',
|
|
1082
|
+
accept: 'application/json',
|
|
1083
|
+
body: JSON.stringify(prompt),
|
|
1084
|
+
});
|
|
749
1085
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
accept: "application/json",
|
|
754
|
-
body: JSON.stringify(prompt),
|
|
755
|
-
});
|
|
1086
|
+
if (!res.body) {
|
|
1087
|
+
throw new Error('[Bedrock] Stream not found in response');
|
|
1088
|
+
}
|
|
756
1089
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
break;
|
|
779
|
-
default:
|
|
780
|
-
finishReason = result.finishReason;
|
|
1090
|
+
const stream = transformAsyncIterator(res.body, (chunk) => {
|
|
1091
|
+
if (chunk.chunk?.bytes) {
|
|
1092
|
+
const decoder = new TextDecoder();
|
|
1093
|
+
const body = decoder.decode(chunk.chunk.bytes);
|
|
1094
|
+
|
|
1095
|
+
try {
|
|
1096
|
+
const result = JSON.parse(body);
|
|
1097
|
+
|
|
1098
|
+
// Extract streaming response according to TwelveLabs Pegasus format
|
|
1099
|
+
let finishReason: string | undefined;
|
|
1100
|
+
if (result.finishReason) {
|
|
1101
|
+
switch (result.finishReason) {
|
|
1102
|
+
case 'stop':
|
|
1103
|
+
finishReason = 'stop';
|
|
1104
|
+
break;
|
|
1105
|
+
case 'length':
|
|
1106
|
+
finishReason = 'length';
|
|
1107
|
+
break;
|
|
1108
|
+
default:
|
|
1109
|
+
finishReason = result.finishReason;
|
|
1110
|
+
}
|
|
781
1111
|
}
|
|
782
|
-
}
|
|
783
1112
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
1113
|
+
return {
|
|
1114
|
+
result:
|
|
1115
|
+
result.delta || result.message
|
|
1116
|
+
? [{ type: 'text' as const, value: result.delta || result.message || '' }]
|
|
1117
|
+
: [],
|
|
1118
|
+
finish_reason: finishReason,
|
|
1119
|
+
} satisfies CompletionChunkObject;
|
|
1120
|
+
} catch {
|
|
1121
|
+
// If JSON parsing fails, return empty chunk
|
|
1122
|
+
return {
|
|
1123
|
+
result: [],
|
|
1124
|
+
} satisfies CompletionChunkObject;
|
|
1125
|
+
}
|
|
793
1126
|
}
|
|
794
|
-
}
|
|
795
1127
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
1128
|
+
return {
|
|
1129
|
+
result: [],
|
|
1130
|
+
} satisfies CompletionChunkObject;
|
|
1131
|
+
});
|
|
1132
|
+
return withBedrockRuntimeScope(stream, executorScope);
|
|
1133
|
+
} catch (err) {
|
|
1134
|
+
executorScope.close();
|
|
1135
|
+
throw err;
|
|
1136
|
+
}
|
|
800
1137
|
}
|
|
801
1138
|
|
|
802
|
-
async requestTextCompletionStream(
|
|
1139
|
+
async requestTextCompletionStream(
|
|
1140
|
+
prompt: BedrockPrompt,
|
|
1141
|
+
options: ExecutionOptions,
|
|
1142
|
+
): Promise<AsyncIterable<CompletionChunkObject>> {
|
|
803
1143
|
// Handle Twelvelabs Pegasus models
|
|
804
|
-
if (options.model.includes(
|
|
1144
|
+
if (options.model.includes('twelvelabs.pegasus')) {
|
|
805
1145
|
return this.requestTwelvelabsPegasusCompletionStream(prompt as TwelvelabsPegasusRequest, options);
|
|
806
1146
|
}
|
|
807
1147
|
|
|
@@ -814,49 +1154,58 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
814
1154
|
const conversation = updateConversation(incomingConversation, conversePrompt);
|
|
815
1155
|
|
|
816
1156
|
const payload = this.preparePayload(conversation, options);
|
|
817
|
-
const
|
|
818
|
-
return executor
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
throw new Error("[Bedrock] Stream not found in response");
|
|
825
|
-
}
|
|
1157
|
+
const executorScope = this.getScopedExecutor(options);
|
|
1158
|
+
return executorScope.executor
|
|
1159
|
+
.converseStream({
|
|
1160
|
+
...payload,
|
|
1161
|
+
})
|
|
1162
|
+
.then((res) => {
|
|
1163
|
+
const stream = res.stream;
|
|
826
1164
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
});
|
|
1165
|
+
if (!stream) {
|
|
1166
|
+
throw new Error('[Bedrock] Stream not found in response');
|
|
1167
|
+
}
|
|
831
1168
|
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
1169
|
+
const streamingToolBlocks = new Map<number, { id: string; name: string }>();
|
|
1170
|
+
const transformedStream = transformAsyncIterator(stream, (streamSegment: ConverseStreamOutput) => {
|
|
1171
|
+
return this.getExtractedStream(streamSegment, conversePrompt, options, streamingToolBlocks);
|
|
1172
|
+
});
|
|
1173
|
+
return withBedrockRuntimeScope(transformedStream, executorScope);
|
|
1174
|
+
})
|
|
1175
|
+
.catch((err) => {
|
|
1176
|
+
executorScope.close();
|
|
1177
|
+
this.logger.error({ error: err }, '[Bedrock] Failed to stream');
|
|
1178
|
+
throw err;
|
|
1179
|
+
});
|
|
836
1180
|
}
|
|
837
1181
|
|
|
838
1182
|
preparePayload(prompt: ConverseRequest, options: ExecutionOptions) {
|
|
839
|
-
const model_options: TextFallbackOptions = options.model_options as TextFallbackOptions ?? {
|
|
1183
|
+
const model_options: TextFallbackOptions = (options.model_options as TextFallbackOptions) ?? {
|
|
1184
|
+
_option_id: 'text-fallback',
|
|
1185
|
+
};
|
|
840
1186
|
|
|
841
|
-
let additionalField = {};
|
|
1187
|
+
let additionalField: Record<string, unknown> = {};
|
|
842
1188
|
let supportsJSONPrefill = false;
|
|
843
1189
|
|
|
844
1190
|
// Resolve thinking, effort, and sampling restrictions using shared Claude helper
|
|
845
|
-
const claudeThinking = resolveClaudeThinking(
|
|
1191
|
+
const claudeThinking = resolveClaudeThinking(
|
|
1192
|
+
options.model,
|
|
1193
|
+
options.model_options as BedrockClaudeOptions | undefined,
|
|
1194
|
+
);
|
|
846
1195
|
const hasSamplingRestriction = claudeThinking.hasSamplingRestriction;
|
|
847
1196
|
|
|
848
|
-
if (options.model.includes(
|
|
1197
|
+
if (options.model.includes('amazon')) {
|
|
849
1198
|
supportsJSONPrefill = true;
|
|
850
1199
|
//Titan models also exists but does not support any additional options
|
|
851
|
-
if (options.model.includes(
|
|
1200
|
+
if (options.model.includes('nova')) {
|
|
852
1201
|
additionalField = { inferenceConfig: { topK: model_options.top_k } };
|
|
853
1202
|
}
|
|
854
|
-
} else if (options.model.includes(
|
|
1203
|
+
} else if (options.model.includes('claude')) {
|
|
855
1204
|
const claude_options = model_options as ModelOptions as BedrockClaudeOptions;
|
|
856
1205
|
// Thinking is active when extended (budget set) or adaptive (effort set) thinking is enabled.
|
|
857
1206
|
// JSON prefill is incompatible with active thinking.
|
|
858
|
-
const thinkingActive = claudeThinking.thinking != null && claudeThinking.thinking.type !==
|
|
859
|
-
supportsJSONPrefill = !thinkingActive
|
|
1207
|
+
const thinkingActive = claudeThinking.thinking != null && claudeThinking.thinking.type !== 'disabled';
|
|
1208
|
+
supportsJSONPrefill = !thinkingActive;
|
|
860
1209
|
|
|
861
1210
|
// Claude 3.7+ supports thinking — use shared helper for reasoning_config
|
|
862
1211
|
if (claudeThinking.supportsThinking) {
|
|
@@ -867,12 +1216,14 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
867
1216
|
};
|
|
868
1217
|
}
|
|
869
1218
|
// For Claude 3.7 with extended thinking + high output, add beta header
|
|
870
|
-
if (
|
|
871
|
-
|
|
872
|
-
|
|
1219
|
+
if (
|
|
1220
|
+
claudeThinking.thinking?.type === 'enabled' &&
|
|
1221
|
+
options.model.includes('claude-3-7-sonnet') &&
|
|
1222
|
+
((claude_options.max_tokens ?? 0) > 64000 || (claude_options.thinking_budget_tokens ?? 0) > 64000)
|
|
1223
|
+
) {
|
|
873
1224
|
additionalField = {
|
|
874
1225
|
...additionalField,
|
|
875
|
-
anthropic_beta: [
|
|
1226
|
+
anthropic_beta: ['output-128k-2025-02-19'],
|
|
876
1227
|
};
|
|
877
1228
|
}
|
|
878
1229
|
}
|
|
@@ -880,7 +1231,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
880
1231
|
if (claudeThinking.outputConfig) {
|
|
881
1232
|
additionalField = {
|
|
882
1233
|
...additionalField,
|
|
883
|
-
output_config: claudeThinking.outputConfig
|
|
1234
|
+
output_config: claudeThinking.outputConfig,
|
|
884
1235
|
};
|
|
885
1236
|
}
|
|
886
1237
|
// Claude 4.6 and later versions don't support JSON prefill
|
|
@@ -895,11 +1246,11 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
895
1246
|
if (!hasSamplingRestriction) {
|
|
896
1247
|
additionalField = { ...additionalField, top_k: model_options.top_k };
|
|
897
1248
|
}
|
|
898
|
-
} else if (options.model.includes(
|
|
1249
|
+
} else if (options.model.includes('meta')) {
|
|
899
1250
|
//LLaMA models support no additional options
|
|
900
|
-
} else if (options.model.includes(
|
|
1251
|
+
} else if (options.model.includes('mistral')) {
|
|
901
1252
|
//7B instruct and 8x7B instruct
|
|
902
|
-
if (options.model.includes(
|
|
1253
|
+
if (options.model.includes('7b')) {
|
|
903
1254
|
additionalField = { top_k: model_options.top_k };
|
|
904
1255
|
//Does not support system messages
|
|
905
1256
|
if (prompt.system && prompt.system?.length !== 0) {
|
|
@@ -911,10 +1262,10 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
911
1262
|
//Other models such as Mistral Small,Large and Large 2
|
|
912
1263
|
//Support no additional fields.
|
|
913
1264
|
}
|
|
914
|
-
} else if (options.model.includes(
|
|
1265
|
+
} else if (options.model.includes('ai21')) {
|
|
915
1266
|
//Jamba models support no additional options
|
|
916
1267
|
//Jurassic 2 models do.
|
|
917
|
-
if (options.model.includes(
|
|
1268
|
+
if (options.model.includes('j2')) {
|
|
918
1269
|
additionalField = {
|
|
919
1270
|
presencePenalty: { scale: model_options.presence_penalty },
|
|
920
1271
|
frequencyPenalty: { scale: model_options.frequency_penalty },
|
|
@@ -926,10 +1277,10 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
926
1277
|
prompt.messages = converseConcatMessages(prompt.messages);
|
|
927
1278
|
}
|
|
928
1279
|
}
|
|
929
|
-
} else if (options.model.includes(
|
|
1280
|
+
} else if (options.model.includes('cohere.command')) {
|
|
930
1281
|
// If last message is "```json", remove it.
|
|
931
1282
|
//Command R and R plus
|
|
932
|
-
if (options.model.includes(
|
|
1283
|
+
if (options.model.includes('cohere.command-r')) {
|
|
933
1284
|
additionalField = {
|
|
934
1285
|
k: model_options.top_k,
|
|
935
1286
|
frequency_penalty: model_options.frequency_penalty,
|
|
@@ -945,19 +1296,19 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
945
1296
|
prompt.messages = converseConcatMessages(prompt.messages);
|
|
946
1297
|
}
|
|
947
1298
|
}
|
|
948
|
-
} else if (options.model.includes(
|
|
1299
|
+
} else if (options.model.includes('palmyra')) {
|
|
949
1300
|
const palmyraOptions = model_options as ModelOptions as BedrockPalmyraOptions;
|
|
950
1301
|
additionalField = {
|
|
951
1302
|
seed: palmyraOptions?.seed,
|
|
952
1303
|
presence_penalty: palmyraOptions?.presence_penalty,
|
|
953
1304
|
frequency_penalty: palmyraOptions?.frequency_penalty,
|
|
954
1305
|
min_tokens: palmyraOptions?.min_tokens,
|
|
955
|
-
}
|
|
956
|
-
} else if (options.model.includes(
|
|
1306
|
+
};
|
|
1307
|
+
} else if (options.model.includes('deepseek')) {
|
|
957
1308
|
// DeepSeek models: no additional options, no stopSequences, only one of temperature/top_p
|
|
958
1309
|
model_options.stop_sequence = undefined;
|
|
959
1310
|
model_options.top_p = undefined;
|
|
960
|
-
} else if (options.model.includes(
|
|
1311
|
+
} else if (options.model.includes('gpt-oss')) {
|
|
961
1312
|
const gptOssOptions = model_options as ModelOptions as BedrockGptOssOptions;
|
|
962
1313
|
additionalField = {
|
|
963
1314
|
reasoning_effort: gptOssOptions?.reasoning_effort,
|
|
@@ -966,12 +1317,12 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
966
1317
|
|
|
967
1318
|
//If last message is "```json", add corresponding ``` as a stop sequence.
|
|
968
1319
|
if (prompt.messages && prompt.messages.length > 0) {
|
|
969
|
-
if (prompt.messages[prompt.messages.length - 1].content?.[0].text ===
|
|
1320
|
+
if (prompt.messages[prompt.messages.length - 1].content?.[0].text === '```json') {
|
|
970
1321
|
const stopSeq = model_options.stop_sequence;
|
|
971
1322
|
if (!stopSeq) {
|
|
972
|
-
model_options.stop_sequence = [
|
|
973
|
-
} else if (!stopSeq.includes(
|
|
974
|
-
stopSeq.push(
|
|
1323
|
+
model_options.stop_sequence = ['```'];
|
|
1324
|
+
} else if (!stopSeq.includes('```')) {
|
|
1325
|
+
stopSeq.push('```');
|
|
975
1326
|
model_options.stop_sequence = stopSeq;
|
|
976
1327
|
}
|
|
977
1328
|
}
|
|
@@ -990,10 +1341,12 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
990
1341
|
// Models with sampling parameter restrictions don't support temperature/top_p - exclude them from inference config
|
|
991
1342
|
const cleanedModelOptions = removeUndefinedValues({
|
|
992
1343
|
maxTokens: model_options.max_tokens,
|
|
993
|
-
...(hasSamplingRestriction
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1344
|
+
...(hasSamplingRestriction
|
|
1345
|
+
? {}
|
|
1346
|
+
: {
|
|
1347
|
+
temperature: model_options.temperature,
|
|
1348
|
+
topP: model_options.temperature != null ? undefined : model_options.top_p,
|
|
1349
|
+
}),
|
|
997
1350
|
stopSequences: model_options.stop_sequence,
|
|
998
1351
|
} satisfies InferenceConfiguration);
|
|
999
1352
|
|
|
@@ -1012,17 +1365,18 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1012
1365
|
}
|
|
1013
1366
|
|
|
1014
1367
|
if (Object.keys(cleanedModelOptions).length > 0) {
|
|
1015
|
-
request.inferenceConfig = cleanedModelOptions
|
|
1368
|
+
request.inferenceConfig = cleanedModelOptions;
|
|
1016
1369
|
}
|
|
1017
1370
|
|
|
1018
1371
|
if (Object.keys(cleanedAdditionalFields).length > 0) {
|
|
1019
|
-
request.additionalModelRequestFields =
|
|
1372
|
+
request.additionalModelRequestFields =
|
|
1373
|
+
cleanedAdditionalFields as unknown as ConverseRequest['additionalModelRequestFields'];
|
|
1020
1374
|
}
|
|
1021
1375
|
|
|
1022
1376
|
if (tool_defs?.length) {
|
|
1023
1377
|
request.toolConfig = {
|
|
1024
1378
|
tools: tool_defs,
|
|
1025
|
-
}
|
|
1379
|
+
};
|
|
1026
1380
|
} else if (request.messages && messagesContainToolBlocks(request.messages)) {
|
|
1027
1381
|
// Bedrock requires toolConfig when conversation contains toolUse/toolResult blocks.
|
|
1028
1382
|
// When no tools are provided (e.g. checkpoint summary calls), convert tool blocks
|
|
@@ -1075,37 +1429,51 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1075
1429
|
return request;
|
|
1076
1430
|
}
|
|
1077
1431
|
|
|
1078
|
-
|
|
1079
1432
|
protected isImageModel(model: string): boolean {
|
|
1080
|
-
return model.includes(
|
|
1433
|
+
return model.includes('titan-image') || model.includes('stable-diffusion') || model.includes('nova-canvas');
|
|
1081
1434
|
}
|
|
1082
1435
|
|
|
1083
1436
|
async requestImageGeneration(prompt: NovaMessagesPrompt, options: ExecutionOptions): Promise<Completion> {
|
|
1084
|
-
if (
|
|
1085
|
-
|
|
1437
|
+
if (
|
|
1438
|
+
options.model_options?._option_id !== undefined &&
|
|
1439
|
+
options.model_options?._option_id !== 'bedrock-nova-canvas'
|
|
1440
|
+
) {
|
|
1441
|
+
this.logger.debug({ options: options.model_options }, 'Unexpected option id');
|
|
1086
1442
|
}
|
|
1087
1443
|
const model_options = options.model_options as NovaCanvasOptions;
|
|
1088
1444
|
|
|
1089
|
-
const executor = this.getExecutor();
|
|
1090
1445
|
const taskType = model_options.taskType ?? NovaImageGenerationTaskType.TEXT_IMAGE;
|
|
1091
1446
|
|
|
1092
|
-
this.logger.info(
|
|
1447
|
+
this.logger.info(`Task type: ${taskType}`);
|
|
1093
1448
|
|
|
1094
|
-
if (typeof prompt ===
|
|
1095
|
-
throw new Error(
|
|
1449
|
+
if (typeof prompt === 'string') {
|
|
1450
|
+
throw new Error('Bad prompt format');
|
|
1096
1451
|
}
|
|
1097
1452
|
|
|
1098
1453
|
const payload = await formatNovaImageGenerationPayload(taskType, prompt, options);
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1454
|
+
const executorScope = this.getScopedExecutor(options);
|
|
1455
|
+
|
|
1456
|
+
let res: InvokeModelCommandOutput;
|
|
1457
|
+
try {
|
|
1458
|
+
const requestTimeout = options.httpTimeout
|
|
1459
|
+
? resolveDriverHttpTimeouts(
|
|
1460
|
+
mergeDriverHttpTimeoutOptions(this.options.httpTimeout, options.httpTimeout),
|
|
1461
|
+
).headersTimeout
|
|
1462
|
+
: (this.options.httpTimeout?.headersTimeout ?? 60_000 * 5);
|
|
1463
|
+
res = await executorScope.executor.invokeModel(
|
|
1464
|
+
{
|
|
1465
|
+
modelId: options.model,
|
|
1466
|
+
contentType: 'application/json',
|
|
1467
|
+
accept: 'application/json',
|
|
1468
|
+
body: JSON.stringify(payload),
|
|
1469
|
+
},
|
|
1470
|
+
{
|
|
1471
|
+
requestTimeout,
|
|
1472
|
+
},
|
|
1473
|
+
);
|
|
1474
|
+
} finally {
|
|
1475
|
+
executorScope.close();
|
|
1476
|
+
}
|
|
1109
1477
|
|
|
1110
1478
|
const decoder = new TextDecoder();
|
|
1111
1479
|
const body = decoder.decode(res.body);
|
|
@@ -1113,15 +1481,14 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1113
1481
|
|
|
1114
1482
|
return {
|
|
1115
1483
|
error: bedrockResult.error,
|
|
1116
|
-
result: bedrockResult.images.map((image:
|
|
1117
|
-
type:
|
|
1118
|
-
value: image
|
|
1119
|
-
}))
|
|
1120
|
-
}
|
|
1484
|
+
result: bedrockResult.images.map((image: string) => ({
|
|
1485
|
+
type: 'image' as const,
|
|
1486
|
+
value: image,
|
|
1487
|
+
})),
|
|
1488
|
+
};
|
|
1121
1489
|
}
|
|
1122
1490
|
|
|
1123
1491
|
async startTraining(dataset: DataSource, options: TrainingOptions): Promise<TrainingJob> {
|
|
1124
|
-
|
|
1125
1492
|
//convert options.params to Record<string, string>
|
|
1126
1493
|
const params: Record<string, string> = {};
|
|
1127
1494
|
for (const [key, value] of Object.entries(options.params || {})) {
|
|
@@ -1129,7 +1496,9 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1129
1496
|
}
|
|
1130
1497
|
|
|
1131
1498
|
if (!this.options.training_bucket) {
|
|
1132
|
-
throw new Error(
|
|
1499
|
+
throw new Error(
|
|
1500
|
+
"Training cannot nbe used since the 'training_bucket' property was not specified in driver options",
|
|
1501
|
+
);
|
|
1133
1502
|
}
|
|
1134
1503
|
|
|
1135
1504
|
const s3 = new S3Client({ region: this.options.region, credentials: this.options.credentials });
|
|
@@ -1137,45 +1506,56 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1137
1506
|
const upload = await forceUploadFile(s3, stream, this.options.training_bucket, dataset.name);
|
|
1138
1507
|
|
|
1139
1508
|
const service = this.getService();
|
|
1140
|
-
const response = await service.send(
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1509
|
+
const response = await service.send(
|
|
1510
|
+
new CreateModelCustomizationJobCommand({
|
|
1511
|
+
jobName: `${options.name}-job`,
|
|
1512
|
+
customModelName: options.name,
|
|
1513
|
+
roleArn: this.options.training_role_arn || undefined,
|
|
1514
|
+
baseModelIdentifier: options.model,
|
|
1515
|
+
clientRequestToken: `llumiverse-${Date.now()}`,
|
|
1516
|
+
trainingDataConfig: {
|
|
1517
|
+
s3Uri: `s3://${upload.Bucket}/${upload.Key}`,
|
|
1518
|
+
},
|
|
1519
|
+
outputDataConfig: undefined,
|
|
1520
|
+
hyperParameters: params,
|
|
1521
|
+
//TODO not supported?
|
|
1522
|
+
//customizationType: "FINE_TUNING",
|
|
1523
|
+
}),
|
|
1524
|
+
);
|
|
1154
1525
|
|
|
1155
|
-
const job = await service.send(
|
|
1156
|
-
|
|
1157
|
-
|
|
1526
|
+
const job = await service.send(
|
|
1527
|
+
new GetModelCustomizationJobCommand({
|
|
1528
|
+
jobIdentifier: response.jobArn,
|
|
1529
|
+
}),
|
|
1530
|
+
);
|
|
1158
1531
|
|
|
1532
|
+
// biome-ignore lint/style/noNonNullAssertion: intentional non-null assertion; TS can't prove narrowing here
|
|
1159
1533
|
return jobInfo(job, response.jobArn!);
|
|
1160
1534
|
}
|
|
1161
1535
|
|
|
1162
1536
|
async cancelTraining(jobId: string): Promise<TrainingJob> {
|
|
1163
1537
|
const service = this.getService();
|
|
1164
|
-
await service.send(
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1538
|
+
await service.send(
|
|
1539
|
+
new StopModelCustomizationJobCommand({
|
|
1540
|
+
jobIdentifier: jobId,
|
|
1541
|
+
}),
|
|
1542
|
+
);
|
|
1543
|
+
const job = await service.send(
|
|
1544
|
+
new GetModelCustomizationJobCommand({
|
|
1545
|
+
jobIdentifier: jobId,
|
|
1546
|
+
}),
|
|
1547
|
+
);
|
|
1170
1548
|
|
|
1171
1549
|
return jobInfo(job, jobId);
|
|
1172
1550
|
}
|
|
1173
1551
|
|
|
1174
1552
|
async getTrainingJob(jobId: string): Promise<TrainingJob> {
|
|
1175
1553
|
const service = this.getService();
|
|
1176
|
-
const job = await service.send(
|
|
1177
|
-
|
|
1178
|
-
|
|
1554
|
+
const job = await service.send(
|
|
1555
|
+
new GetModelCustomizationJobCommand({
|
|
1556
|
+
jobIdentifier: jobId,
|
|
1557
|
+
}),
|
|
1558
|
+
);
|
|
1179
1559
|
|
|
1180
1560
|
return jobInfo(job, jobId);
|
|
1181
1561
|
}
|
|
@@ -1184,22 +1564,24 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1184
1564
|
|
|
1185
1565
|
async validateConnection(): Promise<boolean> {
|
|
1186
1566
|
const service = this.getService();
|
|
1187
|
-
this.logger.debug(
|
|
1567
|
+
this.logger.debug('[Bedrock] validating connection', service.config.credentials.name);
|
|
1188
1568
|
//return true as if the client has been initialized, it means the connection is valid
|
|
1189
1569
|
return true;
|
|
1190
1570
|
}
|
|
1191
1571
|
|
|
1192
|
-
|
|
1193
1572
|
async listTrainableModels(): Promise<AIModel<string>[]> {
|
|
1194
|
-
this.logger.debug(
|
|
1195
|
-
return this._listModels(m =>
|
|
1573
|
+
this.logger.debug('[Bedrock] listing trainable models');
|
|
1574
|
+
return this._listModels((m) =>
|
|
1575
|
+
m.customizationsSupported ? m.customizationsSupported.includes('FINE_TUNING') : false,
|
|
1576
|
+
);
|
|
1196
1577
|
}
|
|
1197
1578
|
|
|
1198
1579
|
async listModels(): Promise<AIModel[]> {
|
|
1199
|
-
this.logger.debug(
|
|
1580
|
+
this.logger.debug('[Bedrock] listing models');
|
|
1200
1581
|
// exclude trainable models since they are not executable
|
|
1201
1582
|
// exclude embedding models, not to be used for typical completions.
|
|
1202
|
-
const filter = (m: FoundationModelSummary) =>
|
|
1583
|
+
const filter = (m: FoundationModelSummary) =>
|
|
1584
|
+
(m.inferenceTypesSupported?.includes('ON_DEMAND') && !m.outputModalities?.includes('EMBEDDING')) ?? false;
|
|
1203
1585
|
return this._listModels(filter);
|
|
1204
1586
|
}
|
|
1205
1587
|
|
|
@@ -1207,21 +1589,25 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1207
1589
|
const service = this.getService();
|
|
1208
1590
|
const [foundationModelsList, customModelsList, inferenceProfilesList] = await Promise.all([
|
|
1209
1591
|
service.listFoundationModels({}).catch(() => {
|
|
1210
|
-
this.logger.warn(
|
|
1211
|
-
|
|
1592
|
+
this.logger.warn(
|
|
1593
|
+
"[Bedrock] Can't list foundation models. Check if the user has the right permissions.",
|
|
1594
|
+
);
|
|
1595
|
+
return undefined;
|
|
1212
1596
|
}),
|
|
1213
1597
|
service.listCustomModels({}).catch(() => {
|
|
1214
1598
|
this.logger.warn("[Bedrock] Can't list custom models. Check if the user has the right permissions.");
|
|
1215
|
-
return undefined
|
|
1599
|
+
return undefined;
|
|
1216
1600
|
}),
|
|
1217
1601
|
service.listInferenceProfiles({}).catch(() => {
|
|
1218
|
-
this.logger.warn(
|
|
1219
|
-
|
|
1602
|
+
this.logger.warn(
|
|
1603
|
+
"[Bedrock] Can't list inference profiles. Check if the user has the right permissions.",
|
|
1604
|
+
);
|
|
1605
|
+
return undefined;
|
|
1220
1606
|
}),
|
|
1221
1607
|
]);
|
|
1222
1608
|
|
|
1223
1609
|
if (!foundationModelsList?.modelSummaries) {
|
|
1224
|
-
throw new Error(
|
|
1610
|
+
throw new Error('Foundation models not found');
|
|
1225
1611
|
}
|
|
1226
1612
|
|
|
1227
1613
|
let foundationModels = foundationModelsList.modelSummaries || [];
|
|
@@ -1229,20 +1615,30 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1229
1615
|
foundationModels = foundationModels.filter(foundationFilter);
|
|
1230
1616
|
}
|
|
1231
1617
|
|
|
1232
|
-
const supportedPublishers = [
|
|
1233
|
-
|
|
1234
|
-
|
|
1618
|
+
const supportedPublishers = [
|
|
1619
|
+
'amazon',
|
|
1620
|
+
'anthropic',
|
|
1621
|
+
'cohere',
|
|
1622
|
+
'ai21',
|
|
1623
|
+
'mistral',
|
|
1624
|
+
'meta',
|
|
1625
|
+
'deepseek',
|
|
1626
|
+
'writer',
|
|
1627
|
+
'openai',
|
|
1628
|
+
'twelvelabs',
|
|
1629
|
+
'qwen',
|
|
1630
|
+
];
|
|
1235
1631
|
const unsupportedModelsByPublisher = {
|
|
1236
|
-
amazon: [
|
|
1632
|
+
amazon: ['titan-image-generator', 'nova-reel', 'nova-sonic', 'rerank'],
|
|
1237
1633
|
anthropic: [],
|
|
1238
|
-
cohere: [
|
|
1634
|
+
cohere: ['rerank', 'embed'],
|
|
1239
1635
|
ai21: [],
|
|
1240
1636
|
mistral: [],
|
|
1241
1637
|
meta: [],
|
|
1242
1638
|
deepseek: [],
|
|
1243
1639
|
writer: [],
|
|
1244
1640
|
openai: [],
|
|
1245
|
-
twelvelabs: [
|
|
1641
|
+
twelvelabs: ['marengo'],
|
|
1246
1642
|
qwen: [],
|
|
1247
1643
|
};
|
|
1248
1644
|
|
|
@@ -1253,33 +1649,27 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1253
1649
|
const normalizedProvider = providerName.toLowerCase();
|
|
1254
1650
|
|
|
1255
1651
|
// Check if provider is supported
|
|
1256
|
-
const isProviderSupported = supportedPublishers.some(provider =>
|
|
1257
|
-
normalizedProvider.includes(provider)
|
|
1258
|
-
);
|
|
1652
|
+
const isProviderSupported = supportedPublishers.some((provider) => normalizedProvider.includes(provider));
|
|
1259
1653
|
|
|
1260
1654
|
if (!isProviderSupported) return false;
|
|
1261
1655
|
|
|
1262
1656
|
// Check if model is in the unsupported list for its provider
|
|
1263
1657
|
for (const provider of supportedPublishers) {
|
|
1264
1658
|
if (normalizedProvider.includes(provider)) {
|
|
1265
|
-
const unsupportedModels =
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
);
|
|
1659
|
+
const unsupportedModels =
|
|
1660
|
+
unsupportedModelsByPublisher[provider as keyof typeof unsupportedModelsByPublisher] || [];
|
|
1661
|
+
return !unsupportedModels.some((unsupported) => modelId.toLowerCase().includes(unsupported));
|
|
1269
1662
|
}
|
|
1270
1663
|
}
|
|
1271
1664
|
|
|
1272
1665
|
return true;
|
|
1273
1666
|
};
|
|
1274
1667
|
|
|
1275
|
-
foundationModels = foundationModels.filter(m =>
|
|
1276
|
-
shouldIncludeModel(m.modelId, m.providerName)
|
|
1277
|
-
);
|
|
1668
|
+
foundationModels = foundationModels.filter((m) => shouldIncludeModel(m.modelId, m.providerName));
|
|
1278
1669
|
|
|
1279
1670
|
const aiModels: AIModel[] = foundationModels.map((m) => {
|
|
1280
|
-
|
|
1281
1671
|
if (!m.modelId) {
|
|
1282
|
-
throw new Error(
|
|
1672
|
+
throw new Error('modelId not found');
|
|
1283
1673
|
}
|
|
1284
1674
|
|
|
1285
1675
|
const modelCapability = getModelCapabilities(m.modelArn ?? m.modelId, this.provider);
|
|
@@ -1290,8 +1680,12 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1290
1680
|
provider: this.provider,
|
|
1291
1681
|
owner: m.providerName,
|
|
1292
1682
|
can_stream: m.responseStreamingSupported ?? false,
|
|
1293
|
-
input_modalities: m.inputModalities
|
|
1294
|
-
|
|
1683
|
+
input_modalities: m.inputModalities
|
|
1684
|
+
? formatAmazonModalities(m.inputModalities)
|
|
1685
|
+
: modelModalitiesToArray(modelCapability.input),
|
|
1686
|
+
output_modalities: m.outputModalities
|
|
1687
|
+
? formatAmazonModalities(m.outputModalities)
|
|
1688
|
+
: modelModalitiesToArray(modelCapability.input),
|
|
1295
1689
|
tool_support: modelCapability.tool_support,
|
|
1296
1690
|
};
|
|
1297
1691
|
|
|
@@ -1301,9 +1695,8 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1301
1695
|
//add custom models
|
|
1302
1696
|
if (customModelsList?.modelSummaries) {
|
|
1303
1697
|
customModelsList.modelSummaries.forEach((m) => {
|
|
1304
|
-
|
|
1305
1698
|
if (!m.modelArn) {
|
|
1306
|
-
throw new Error(
|
|
1699
|
+
throw new Error('Model ID not found');
|
|
1307
1700
|
}
|
|
1308
1701
|
|
|
1309
1702
|
const modelCapability = getModelCapabilities(m.modelArn, this.provider);
|
|
@@ -1312,7 +1705,7 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1312
1705
|
id: m.modelArn,
|
|
1313
1706
|
name: m.modelName ?? m.modelArn,
|
|
1314
1707
|
provider: this.provider,
|
|
1315
|
-
owner:
|
|
1708
|
+
owner: 'custom',
|
|
1316
1709
|
description: `Custom model from ${m.baseModelName}`,
|
|
1317
1710
|
is_custom: true,
|
|
1318
1711
|
input_modalities: modelModalitiesToArray(modelCapability.input),
|
|
@@ -1321,7 +1714,6 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1321
1714
|
};
|
|
1322
1715
|
|
|
1323
1716
|
aiModels.push(model);
|
|
1324
|
-
this.validateConnection;
|
|
1325
1717
|
});
|
|
1326
1718
|
}
|
|
1327
1719
|
|
|
@@ -1329,15 +1721,15 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1329
1721
|
if (inferenceProfilesList?.inferenceProfileSummaries) {
|
|
1330
1722
|
inferenceProfilesList.inferenceProfileSummaries.forEach((p) => {
|
|
1331
1723
|
if (!p.inferenceProfileArn) {
|
|
1332
|
-
throw new Error(
|
|
1724
|
+
throw new Error('Profile ARN not found');
|
|
1333
1725
|
}
|
|
1334
1726
|
|
|
1335
1727
|
// Apply the same filtering logic to inference profiles based on their name
|
|
1336
|
-
const profileId = p.inferenceProfileId ||
|
|
1337
|
-
const profileName = p.inferenceProfileName ||
|
|
1728
|
+
const profileId = p.inferenceProfileId || '';
|
|
1729
|
+
const profileName = p.inferenceProfileName || '';
|
|
1338
1730
|
|
|
1339
1731
|
// Extract provider name from profile name or ID
|
|
1340
|
-
let providerName =
|
|
1732
|
+
let providerName = '';
|
|
1341
1733
|
for (const provider of supportedPublishers) {
|
|
1342
1734
|
if (profileName.toLowerCase().includes(provider) || profileId.toLowerCase().includes(provider)) {
|
|
1343
1735
|
providerName = provider;
|
|
@@ -1345,7 +1737,10 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1345
1737
|
}
|
|
1346
1738
|
}
|
|
1347
1739
|
|
|
1348
|
-
const modelCapability = getModelCapabilities(
|
|
1740
|
+
const modelCapability = getModelCapabilities(
|
|
1741
|
+
p.inferenceProfileArn ?? p.inferenceProfileId,
|
|
1742
|
+
this.provider,
|
|
1743
|
+
);
|
|
1349
1744
|
|
|
1350
1745
|
if (providerName && shouldIncludeModel(profileId, providerName)) {
|
|
1351
1746
|
const model: AIModel = {
|
|
@@ -1366,92 +1761,8 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1366
1761
|
return aiModels;
|
|
1367
1762
|
}
|
|
1368
1763
|
|
|
1369
|
-
async generateEmbeddings(
|
|
1370
|
-
|
|
1371
|
-
this.logger.info("[Bedrock] Generating embeddings with model " + model);
|
|
1372
|
-
|
|
1373
|
-
// Handle TwelveLabs Marengo models
|
|
1374
|
-
if (model?.includes("twelvelabs.marengo")) {
|
|
1375
|
-
return this.generateTwelvelabsMarengoEmbeddings({ text, image, model });
|
|
1376
|
-
}
|
|
1377
|
-
|
|
1378
|
-
// Handle other Bedrock embedding models
|
|
1379
|
-
const defaultModel = image ? "amazon.titan-embed-image-v1" : "amazon.titan-embed-text-v2:0";
|
|
1380
|
-
const modelID = model ?? defaultModel;
|
|
1381
|
-
|
|
1382
|
-
const invokeBody = {
|
|
1383
|
-
inputText: text,
|
|
1384
|
-
inputImage: image
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
const executor = this.getExecutor();
|
|
1388
|
-
const res = await executor.invokeModel(
|
|
1389
|
-
{
|
|
1390
|
-
modelId: modelID,
|
|
1391
|
-
contentType: "application/json",
|
|
1392
|
-
body: JSON.stringify(invokeBody),
|
|
1393
|
-
}
|
|
1394
|
-
);
|
|
1395
|
-
|
|
1396
|
-
const decoder = new TextDecoder();
|
|
1397
|
-
const body = decoder.decode(res.body);
|
|
1398
|
-
|
|
1399
|
-
const result = JSON.parse(body);
|
|
1400
|
-
|
|
1401
|
-
if (!result.embedding) {
|
|
1402
|
-
throw new Error("Embeddings not found");
|
|
1403
|
-
}
|
|
1404
|
-
|
|
1405
|
-
return {
|
|
1406
|
-
values: result.embedding,
|
|
1407
|
-
model: modelID,
|
|
1408
|
-
token_count: result.inputTextTokenCount
|
|
1409
|
-
};
|
|
1410
|
-
}
|
|
1411
|
-
|
|
1412
|
-
private async generateTwelvelabsMarengoEmbeddings({ text, image, model }: EmbeddingsOptions): Promise<EmbeddingsResult> {
|
|
1413
|
-
const executor = this.getExecutor();
|
|
1414
|
-
|
|
1415
|
-
// Prepare the request payload for TwelveLabs Marengo
|
|
1416
|
-
const invokeBody: TwelvelabsMarengoRequest = {
|
|
1417
|
-
inputType: "text"
|
|
1418
|
-
};
|
|
1419
|
-
|
|
1420
|
-
if (text) {
|
|
1421
|
-
invokeBody.inputText = text;
|
|
1422
|
-
invokeBody.inputType = "text";
|
|
1423
|
-
}
|
|
1424
|
-
|
|
1425
|
-
if (image) {
|
|
1426
|
-
// For the embeddings interface, image is expected to be base64
|
|
1427
|
-
invokeBody.mediaSource = {
|
|
1428
|
-
base64String: image
|
|
1429
|
-
};
|
|
1430
|
-
invokeBody.inputType = "image";
|
|
1431
|
-
}
|
|
1432
|
-
|
|
1433
|
-
const res = await executor.invokeModel({
|
|
1434
|
-
modelId: model!,
|
|
1435
|
-
contentType: "application/json",
|
|
1436
|
-
accept: "application/json",
|
|
1437
|
-
body: JSON.stringify(invokeBody),
|
|
1438
|
-
});
|
|
1439
|
-
|
|
1440
|
-
const decoder = new TextDecoder();
|
|
1441
|
-
const body = decoder.decode(res.body);
|
|
1442
|
-
const result: TwelvelabsMarengoResponse = JSON.parse(body);
|
|
1443
|
-
|
|
1444
|
-
// TwelveLabs Marengo returns embedding data
|
|
1445
|
-
if (!result.embedding) {
|
|
1446
|
-
throw new Error("Embeddings not found in TwelveLabs Marengo response");
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
return {
|
|
1450
|
-
values: result.embedding,
|
|
1451
|
-
model: model!,
|
|
1452
|
-
// TwelveLabs Marengo doesn't return token count in the same way
|
|
1453
|
-
token_count: undefined
|
|
1454
|
-
};
|
|
1764
|
+
async generateEmbeddings(options: EmbeddingsOptions): Promise<EmbeddingsResult> {
|
|
1765
|
+
return generateBedrockEmbeddings(this, options);
|
|
1455
1766
|
}
|
|
1456
1767
|
|
|
1457
1768
|
/**
|
|
@@ -1460,6 +1771,9 @@ export class BedrockDriver extends AbstractDriver<BedrockDriverOptions, BedrockP
|
|
|
1460
1771
|
destroy(): void {
|
|
1461
1772
|
this._executor?.destroy();
|
|
1462
1773
|
this._service?.destroy();
|
|
1774
|
+
this._executor = undefined;
|
|
1775
|
+
this._service = undefined;
|
|
1776
|
+
super.destroy();
|
|
1463
1777
|
}
|
|
1464
1778
|
}
|
|
1465
1779
|
|
|
@@ -1471,20 +1785,19 @@ function jobInfo(job: GetModelCustomizationJobCommandOutput, jobId: string): Tra
|
|
|
1471
1785
|
status = TrainingJobStatus.succeeded;
|
|
1472
1786
|
} else if (jobStatus === ModelCustomizationJobStatus.FAILED) {
|
|
1473
1787
|
status = TrainingJobStatus.failed;
|
|
1474
|
-
details = job.failureMessage ||
|
|
1788
|
+
details = job.failureMessage || 'error';
|
|
1475
1789
|
} else if (jobStatus === ModelCustomizationJobStatus.STOPPED) {
|
|
1476
1790
|
status = TrainingJobStatus.cancelled;
|
|
1477
1791
|
} else {
|
|
1478
1792
|
status = TrainingJobStatus.running;
|
|
1479
1793
|
details = jobStatus;
|
|
1480
1794
|
}
|
|
1481
|
-
job.baseModelArn
|
|
1482
1795
|
return {
|
|
1483
1796
|
id: jobId,
|
|
1484
1797
|
model: job.outputModelArn,
|
|
1485
1798
|
status,
|
|
1486
|
-
details
|
|
1487
|
-
}
|
|
1799
|
+
details,
|
|
1800
|
+
};
|
|
1488
1801
|
}
|
|
1489
1802
|
|
|
1490
1803
|
function getToolDefinitions(tools?: ToolDefinition[]): Tool[] | undefined {
|
|
@@ -1497,10 +1810,10 @@ function getToolDefinition(tool: ToolDefinition): Tool.ToolSpecMember {
|
|
|
1497
1810
|
name: tool.name,
|
|
1498
1811
|
description: tool.description,
|
|
1499
1812
|
inputSchema: {
|
|
1500
|
-
json: tool.input_schema
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1503
|
-
}
|
|
1813
|
+
json: tool.input_schema,
|
|
1814
|
+
} as NonNullable<NonNullable<Tool.ToolSpecMember['toolSpec']>['inputSchema']>,
|
|
1815
|
+
},
|
|
1816
|
+
};
|
|
1504
1817
|
}
|
|
1505
1818
|
|
|
1506
1819
|
/**
|
|
@@ -1510,8 +1823,7 @@ export function messagesContainToolBlocks(messages: Message[]): boolean {
|
|
|
1510
1823
|
for (const msg of messages) {
|
|
1511
1824
|
if (!msg.content) continue;
|
|
1512
1825
|
for (const block of msg.content) {
|
|
1513
|
-
if ((block as ContentBlock.ToolUseMember).toolUse ||
|
|
1514
|
-
(block as ContentBlock.ToolResultMember).toolResult) {
|
|
1826
|
+
if ((block as ContentBlock.ToolUseMember).toolUse || (block as ContentBlock.ToolResultMember).toolResult) {
|
|
1515
1827
|
return true;
|
|
1516
1828
|
}
|
|
1517
1829
|
}
|
|
@@ -1528,12 +1840,11 @@ export function messagesContainToolBlocks(messages: Message[]): boolean {
|
|
|
1528
1840
|
* conversation history contains tool interactions from prior turns.
|
|
1529
1841
|
*/
|
|
1530
1842
|
export function convertToolBlocksToText(messages: Message[]): Message[] {
|
|
1531
|
-
return messages.map(msg => {
|
|
1843
|
+
return messages.map((msg) => {
|
|
1532
1844
|
if (!msg.content) return msg;
|
|
1533
1845
|
let hasToolBlocks = false;
|
|
1534
1846
|
for (const block of msg.content) {
|
|
1535
|
-
if ((block as ContentBlock.ToolUseMember).toolUse ||
|
|
1536
|
-
(block as ContentBlock.ToolResultMember).toolResult) {
|
|
1847
|
+
if ((block as ContentBlock.ToolUseMember).toolUse || (block as ContentBlock.ToolResultMember).toolResult) {
|
|
1537
1848
|
hasToolBlocks = true;
|
|
1538
1849
|
break;
|
|
1539
1850
|
}
|
|
@@ -1546,7 +1857,7 @@ export function convertToolBlocksToText(messages: Message[]): Message[] {
|
|
|
1546
1857
|
const toolResult = (block as ContentBlock.ToolResultMember).toolResult;
|
|
1547
1858
|
if (toolUse) {
|
|
1548
1859
|
const inputStr = toolUse.input ? JSON.stringify(toolUse.input) : '';
|
|
1549
|
-
const truncatedInput = inputStr.length > 500 ? inputStr.substring(0, 500)
|
|
1860
|
+
const truncatedInput = inputStr.length > 500 ? `${inputStr.substring(0, 500)}...` : inputStr;
|
|
1550
1861
|
newContent.push({
|
|
1551
1862
|
text: `[Tool call: ${toolUse.name}(${truncatedInput})]`,
|
|
1552
1863
|
} as ContentBlock.TextMember);
|
|
@@ -1554,9 +1865,9 @@ export function convertToolBlocksToText(messages: Message[]): Message[] {
|
|
|
1554
1865
|
const resultTexts: string[] = [];
|
|
1555
1866
|
if (toolResult.content) {
|
|
1556
1867
|
for (const c of toolResult.content) {
|
|
1557
|
-
if (
|
|
1558
|
-
const text =
|
|
1559
|
-
resultTexts.push(text.length > 500 ? text.substring(0, 500)
|
|
1868
|
+
if ('text' in c && typeof c.text === 'string') {
|
|
1869
|
+
const text = c.text;
|
|
1870
|
+
resultTexts.push(text.length > 500 ? `${text.substring(0, 500)}...` : text);
|
|
1560
1871
|
}
|
|
1561
1872
|
}
|
|
1562
1873
|
}
|
|
@@ -1577,16 +1888,16 @@ export function convertToolBlocksToText(messages: Message[]): Message[] {
|
|
|
1577
1888
|
* AWS Bedrock's additionalModelRequestFields must be valid JSON, and undefined is not valid JSON.
|
|
1578
1889
|
* Any unrecognized parameters will cause an exception.
|
|
1579
1890
|
*/
|
|
1580
|
-
function removeUndefinedValues
|
|
1891
|
+
function removeUndefinedValues(obj: Record<string, unknown>): Record<string, unknown> {
|
|
1581
1892
|
if (obj === null || typeof obj !== 'object' || Array.isArray(obj)) {
|
|
1582
1893
|
return obj;
|
|
1583
1894
|
}
|
|
1584
1895
|
|
|
1585
|
-
const cleaned:
|
|
1896
|
+
const cleaned: Record<string, unknown> = {};
|
|
1586
1897
|
for (const [key, value] of Object.entries(obj)) {
|
|
1587
1898
|
if (value !== undefined) {
|
|
1588
1899
|
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
1589
|
-
const cleanedNested = removeUndefinedValues(value);
|
|
1900
|
+
const cleanedNested = removeUndefinedValues(value as Record<string, unknown>);
|
|
1590
1901
|
// Only include nested objects if they have properties after cleaning
|
|
1591
1902
|
if (Object.keys(cleanedNested).length > 0) {
|
|
1592
1903
|
cleaned[key] = cleanedNested;
|
|
@@ -1609,8 +1920,11 @@ function updateConversation(conversation: ConverseRequest, prompt: ConverseReque
|
|
|
1609
1920
|
const combinedMessages = [...(conversation?.messages || []), ...(prompt.messages || [])];
|
|
1610
1921
|
const combinedSystem = prompt.system || conversation?.system;
|
|
1611
1922
|
|
|
1612
|
-
// Fix
|
|
1613
|
-
|
|
1923
|
+
// Fix both orphan directions before returning: a toolUse with no result
|
|
1924
|
+
// (interrupted run) gets a synthetic result; a toolResult with no matching
|
|
1925
|
+
// toolUse in the previous message (e.g. compaction-trimmed) is dropped. Either
|
|
1926
|
+
// would otherwise trip the Converse API's toolUse/toolResult pairing check.
|
|
1927
|
+
const fixedMessages = fixOrphanedToolResults(fixOrphanedToolUse(combinedMessages));
|
|
1614
1928
|
|
|
1615
1929
|
return {
|
|
1616
1930
|
modelId: prompt?.modelId || conversation?.modelId,
|
|
@@ -1620,20 +1934,24 @@ function updateConversation(conversation: ConverseRequest, prompt: ConverseReque
|
|
|
1620
1934
|
}
|
|
1621
1935
|
|
|
1622
1936
|
function stripClaudeCachePoints(messages: Message[]): Message[] {
|
|
1623
|
-
return messages.map(message => ({
|
|
1937
|
+
return messages.map((message) => ({
|
|
1624
1938
|
...message,
|
|
1625
|
-
content: message.content?.filter(block => !('cachePoint' in block)),
|
|
1939
|
+
content: message.content?.filter((block) => !('cachePoint' in block)),
|
|
1626
1940
|
}));
|
|
1627
1941
|
}
|
|
1628
1942
|
|
|
1629
1943
|
function stripClaudeCachePointsFromSystem(system?: ConverseRequest['system']): ConverseRequest['system'] | undefined {
|
|
1630
|
-
return (system?.filter(block => !('cachePoint' in (block as object))) ?? undefined) as
|
|
1944
|
+
return (system?.filter((block) => !('cachePoint' in (block as object))) ?? undefined) as
|
|
1945
|
+
| ConverseRequest['system']
|
|
1946
|
+
| undefined;
|
|
1631
1947
|
}
|
|
1632
1948
|
|
|
1633
1949
|
function stripClaudeCachePointsFromTools(
|
|
1634
|
-
tools?: NonNullable<NonNullable<ConverseRequest['toolConfig']>['tools']
|
|
1950
|
+
tools?: NonNullable<NonNullable<ConverseRequest['toolConfig']>['tools']>,
|
|
1635
1951
|
): NonNullable<NonNullable<ConverseRequest['toolConfig']>['tools']> | undefined {
|
|
1636
|
-
return (tools?.filter(tool => !('cachePoint' in (tool as object))) ?? undefined) as
|
|
1952
|
+
return (tools?.filter((tool) => !('cachePoint' in (tool as object))) ?? undefined) as
|
|
1953
|
+
| NonNullable<NonNullable<ConverseRequest['toolConfig']>['tools']>
|
|
1954
|
+
| undefined;
|
|
1637
1955
|
}
|
|
1638
1956
|
|
|
1639
1957
|
/**
|
|
@@ -1663,7 +1981,7 @@ export function fixOrphanedToolUse(messages: Message[]): Message[] {
|
|
|
1663
1981
|
if (block.toolUse?.toolUseId) {
|
|
1664
1982
|
toolUseBlocks.push({
|
|
1665
1983
|
toolUseId: block.toolUse.toolUseId,
|
|
1666
|
-
name: block.toolUse.name ?? 'unknown'
|
|
1984
|
+
name: block.toolUse.name ?? 'unknown',
|
|
1667
1985
|
});
|
|
1668
1986
|
}
|
|
1669
1987
|
}
|
|
@@ -1682,23 +2000,25 @@ export function fixOrphanedToolUse(messages: Message[]): Message[] {
|
|
|
1682
2000
|
}
|
|
1683
2001
|
|
|
1684
2002
|
// Find orphaned toolUse blocks (no matching toolResult)
|
|
1685
|
-
const orphanedToolUse = toolUseBlocks.filter(tu => !toolResultIds.has(tu.toolUseId));
|
|
2003
|
+
const orphanedToolUse = toolUseBlocks.filter((tu) => !toolResultIds.has(tu.toolUseId));
|
|
1686
2004
|
|
|
1687
2005
|
if (orphanedToolUse.length > 0) {
|
|
1688
2006
|
// Inject synthetic toolResults for orphaned toolUse
|
|
1689
|
-
const syntheticResults: ContentBlock[] = orphanedToolUse.map(tu => ({
|
|
2007
|
+
const syntheticResults: ContentBlock[] = orphanedToolUse.map((tu) => ({
|
|
1690
2008
|
toolResult: {
|
|
1691
2009
|
toolUseId: tu.toolUseId,
|
|
1692
|
-
content: [
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
2010
|
+
content: [
|
|
2011
|
+
{
|
|
2012
|
+
text: `[Tool interrupted: The user stopped the operation before "${tu.name}" could execute.]`,
|
|
2013
|
+
},
|
|
2014
|
+
],
|
|
2015
|
+
},
|
|
1696
2016
|
}));
|
|
1697
2017
|
|
|
1698
2018
|
// Prepend synthetic results to the next user message
|
|
1699
2019
|
const updatedNextMessage: Message = {
|
|
1700
2020
|
...nextMessage,
|
|
1701
|
-
content: [...syntheticResults, ...nextMessage.content]
|
|
2021
|
+
content: [...syntheticResults, ...nextMessage.content],
|
|
1702
2022
|
};
|
|
1703
2023
|
|
|
1704
2024
|
// Replace the next message in our iteration
|
|
@@ -1707,18 +2027,20 @@ export function fixOrphanedToolUse(messages: Message[]): Message[] {
|
|
|
1707
2027
|
} else if (nextMessage && nextMessage.role === 'user' && !nextMessage.content) {
|
|
1708
2028
|
// Next message is a user message but has no content
|
|
1709
2029
|
// We need to add toolResults
|
|
1710
|
-
const syntheticResults: ContentBlock[] = toolUseBlocks.map(tu => ({
|
|
2030
|
+
const syntheticResults: ContentBlock[] = toolUseBlocks.map((tu) => ({
|
|
1711
2031
|
toolResult: {
|
|
1712
2032
|
toolUseId: tu.toolUseId,
|
|
1713
|
-
content: [
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
2033
|
+
content: [
|
|
2034
|
+
{
|
|
2035
|
+
text: `[Tool interrupted: The user stopped the operation before "${tu.name}" could execute.]`,
|
|
2036
|
+
},
|
|
2037
|
+
],
|
|
2038
|
+
},
|
|
1717
2039
|
}));
|
|
1718
2040
|
|
|
1719
2041
|
const updatedNextMessage: Message = {
|
|
1720
2042
|
role: 'user',
|
|
1721
|
-
content: syntheticResults
|
|
2043
|
+
content: syntheticResults,
|
|
1722
2044
|
};
|
|
1723
2045
|
|
|
1724
2046
|
messages[i + 1] = updatedNextMessage;
|
|
@@ -1732,19 +2054,63 @@ export function fixOrphanedToolUse(messages: Message[]): Message[] {
|
|
|
1732
2054
|
return result;
|
|
1733
2055
|
}
|
|
1734
2056
|
|
|
2057
|
+
/**
|
|
2058
|
+
* Drop toolResult blocks whose toolUseId has no matching toolUse in the
|
|
2059
|
+
* immediately-preceding assistant message. Mirror of {@link fixOrphanedToolUse}:
|
|
2060
|
+
* that function synthesizes results for an unanswered toolUse (e.g. a cancelled
|
|
2061
|
+
* run); this one removes results left dangling after their toolUse was dropped
|
|
2062
|
+
* (e.g. by conversation compaction/trimming).
|
|
2063
|
+
*
|
|
2064
|
+
* Without this, the AWS Converse API rejects the request because every
|
|
2065
|
+
* toolResult must correspond to a toolUse in the previous message. Bedrock
|
|
2066
|
+
* conversations are already role-alternating, so a compaction that drops an
|
|
2067
|
+
* assistant toolUse turn leaves an orphaned toolResult (and a user/user
|
|
2068
|
+
* adjacency); dropping the orphan — and the now-empty message — repairs both.
|
|
2069
|
+
*/
|
|
2070
|
+
export function fixOrphanedToolResults(messages: Message[]): Message[] {
|
|
2071
|
+
if (messages.length === 0) return messages;
|
|
2072
|
+
const result: Message[] = [];
|
|
2073
|
+
for (let i = 0; i < messages.length; i++) {
|
|
2074
|
+
const message = messages[i];
|
|
2075
|
+
if (message.role !== 'user' || !message.content) {
|
|
2076
|
+
result.push(message);
|
|
2077
|
+
continue;
|
|
2078
|
+
}
|
|
2079
|
+
const hasToolResult = message.content.some((block) => block.toolResult);
|
|
2080
|
+
if (!hasToolResult) {
|
|
2081
|
+
result.push(message);
|
|
2082
|
+
continue;
|
|
2083
|
+
}
|
|
2084
|
+
const prev = messages[i - 1];
|
|
2085
|
+
const allowedIds = new Set<string>();
|
|
2086
|
+
if (prev && prev.role === 'assistant' && prev.content) {
|
|
2087
|
+
for (const block of prev.content) {
|
|
2088
|
+
if (block.toolUse?.toolUseId) allowedIds.add(block.toolUse.toolUseId);
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
const filtered = message.content.filter((block) =>
|
|
2092
|
+
block.toolResult ? allowedIds.has(block.toolResult.toolUseId ?? '') : true,
|
|
2093
|
+
);
|
|
2094
|
+
// Drop the message if every block was an orphaned toolResult.
|
|
2095
|
+
if (filtered.length === 0) continue;
|
|
2096
|
+
result.push(filtered.length === message.content.length ? message : { ...message, content: filtered });
|
|
2097
|
+
}
|
|
2098
|
+
return result;
|
|
2099
|
+
}
|
|
2100
|
+
|
|
1735
2101
|
function formatAmazonModalities(modalities: ModelModality[]): string[] {
|
|
1736
2102
|
const standardizedModalities: string[] = [];
|
|
1737
2103
|
for (const modality of modalities) {
|
|
1738
2104
|
if (modality === ModelModality.TEXT) {
|
|
1739
|
-
standardizedModalities.push(
|
|
2105
|
+
standardizedModalities.push('text');
|
|
1740
2106
|
} else if (modality === ModelModality.IMAGE) {
|
|
1741
|
-
standardizedModalities.push(
|
|
2107
|
+
standardizedModalities.push('image');
|
|
1742
2108
|
} else if (modality === ModelModality.EMBEDDING) {
|
|
1743
|
-
standardizedModalities.push(
|
|
1744
|
-
} else if (modality ===
|
|
1745
|
-
standardizedModalities.push(
|
|
1746
|
-
} else if (modality ===
|
|
1747
|
-
standardizedModalities.push(
|
|
2109
|
+
standardizedModalities.push('embedding');
|
|
2110
|
+
} else if (modality === 'SPEECH') {
|
|
2111
|
+
standardizedModalities.push('audio');
|
|
2112
|
+
} else if (modality === 'VIDEO') {
|
|
2113
|
+
standardizedModalities.push('video');
|
|
1748
2114
|
} else {
|
|
1749
2115
|
// Handle other modalities as needed
|
|
1750
2116
|
standardizedModalities.push((modality as string).toString().toLowerCase());
|