@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
|
@@ -1,46 +1,41 @@
|
|
|
1
|
-
import { ExecutionOptions, NovaCanvasOptions } from
|
|
2
|
-
import { NovaMessage, NovaMessagesPrompt } from
|
|
1
|
+
import type { ExecutionOptions, NovaCanvasOptions } from '@llumiverse/core';
|
|
2
|
+
import type { NovaMessage, NovaMessagesPrompt } from '@llumiverse/core/formatters';
|
|
3
3
|
|
|
4
4
|
function getFirstImageFromPrompt(prompt: NovaMessage[]) {
|
|
5
|
-
|
|
6
|
-
const msgImage = prompt.find(m => m.content.find(c => c.image));
|
|
5
|
+
const msgImage = prompt.find((m) => m.content.find((c) => c.image));
|
|
7
6
|
if (!msgImage) {
|
|
8
7
|
return undefined;
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
return msgImage.content.find(c => c.image)?.image;
|
|
10
|
+
return msgImage.content.find((c) => c.image)?.image;
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const imgParts = contentMsg.filter(c => c.image);
|
|
19
|
-
if (!imgParts?.length) {
|
|
20
|
-
return undefined;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const images = imgParts.map(i => i.image).filter(i => i?.source?.bytes).map(i => i!.source.bytes);
|
|
24
|
-
return images;
|
|
13
|
+
function getAllImagesFromPrompt(prompt: NovaMessage[]): string[] | undefined {
|
|
14
|
+
const contentMsg = prompt.filter((m) => m.content).flatMap((m) => m.content);
|
|
15
|
+
const images = contentMsg.map((c) => c.image?.source?.bytes).filter((b): b is string => b !== undefined);
|
|
16
|
+
return images.length > 0 ? images : undefined;
|
|
25
17
|
}
|
|
26
18
|
|
|
27
|
-
async function textToImagePayload(
|
|
19
|
+
async function textToImagePayload(
|
|
20
|
+
prompt: NovaMessagesPrompt,
|
|
21
|
+
options: ExecutionOptions,
|
|
22
|
+
): Promise<NovaTextToImagePayload> {
|
|
28
23
|
const modelOptions = options.model_options as NovaCanvasOptions;
|
|
29
24
|
|
|
30
|
-
const textMessages = prompt.messages.
|
|
31
|
-
let text = textMessages.join(
|
|
32
|
-
text += prompt.system ?
|
|
25
|
+
const textMessages = prompt.messages.flatMap((m) => m.content.map((c) => c.text));
|
|
26
|
+
let text = textMessages.join('\n\n');
|
|
27
|
+
text += prompt.system ? `\n\n\nIMPORTANT: ${prompt.system?.map((m) => m.text).join('\n\n')}` : '';
|
|
33
28
|
|
|
34
29
|
const conditionImage = (conditionImage: boolean) => {
|
|
35
30
|
const img = getFirstImageFromPrompt(prompt.messages);
|
|
36
31
|
if (img && conditionImage) {
|
|
37
|
-
return img
|
|
32
|
+
return img;
|
|
38
33
|
}
|
|
39
34
|
return undefined;
|
|
40
|
-
}
|
|
35
|
+
};
|
|
41
36
|
|
|
42
37
|
const payload: NovaTextToImagePayload = {
|
|
43
|
-
taskType: NovaImageGenerationTaskType.TEXT_IMAGE,
|
|
38
|
+
taskType: NovaImageGenerationTaskType.TEXT_IMAGE, // Always TEXT_IMAGE, as TEXT_IMAGE_WITH_IMAGE_CONDITIONING is only an internal marker.
|
|
44
39
|
imageGenerationConfig: {
|
|
45
40
|
quality: modelOptions?.quality,
|
|
46
41
|
width: modelOptions.width,
|
|
@@ -51,20 +46,23 @@ async function textToImagePayload(prompt: NovaMessagesPrompt, options: Execution
|
|
|
51
46
|
},
|
|
52
47
|
textToImageParams: {
|
|
53
48
|
text: text,
|
|
54
|
-
conditionImage: conditionImage(modelOptions?.controlMode
|
|
49
|
+
conditionImage: conditionImage(!!modelOptions?.controlMode)?.source.bytes,
|
|
55
50
|
controlMode: modelOptions?.controlMode,
|
|
56
51
|
controlStrength: modelOptions?.controlStrength,
|
|
57
|
-
negativeText: prompt.negative
|
|
58
|
-
}
|
|
59
|
-
}
|
|
52
|
+
negativeText: prompt.negative,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
60
55
|
|
|
61
56
|
return payload;
|
|
62
57
|
}
|
|
63
58
|
|
|
64
|
-
async function imageVariationPayload(
|
|
59
|
+
async function imageVariationPayload(
|
|
60
|
+
prompt: NovaMessagesPrompt,
|
|
61
|
+
options: ExecutionOptions,
|
|
62
|
+
): Promise<NovaImageVariationPayload> {
|
|
65
63
|
const modelOptions = options.model_options as NovaCanvasOptions;
|
|
66
64
|
|
|
67
|
-
const text = prompt.messages.map(m => m.content).join(
|
|
65
|
+
const text = prompt.messages.map((m) => m.content).join('\n\n');
|
|
68
66
|
const images = getAllImagesFromPrompt(prompt.messages);
|
|
69
67
|
|
|
70
68
|
const payload: NovaImageVariationPayload = {
|
|
@@ -82,26 +80,29 @@ async function imageVariationPayload(prompt: NovaMessagesPrompt, options: Execut
|
|
|
82
80
|
text: text,
|
|
83
81
|
negativeText: prompt.negative,
|
|
84
82
|
similarityStrength: modelOptions?.similarityStrength,
|
|
85
|
-
}
|
|
86
|
-
}
|
|
83
|
+
},
|
|
84
|
+
};
|
|
87
85
|
|
|
88
86
|
return payload;
|
|
89
87
|
}
|
|
90
88
|
|
|
91
|
-
async function colorGuidedGenerationPayload(
|
|
89
|
+
async function colorGuidedGenerationPayload(
|
|
90
|
+
prompt: NovaMessagesPrompt,
|
|
91
|
+
options: ExecutionOptions,
|
|
92
|
+
): Promise<NovaColorGuidedGenerationPayload> {
|
|
92
93
|
const modelOptions = options.model_options as NovaCanvasOptions;
|
|
93
94
|
|
|
94
|
-
const textMessages = prompt.messages.
|
|
95
|
-
let text = textMessages.join(
|
|
96
|
-
text += prompt.system ?
|
|
95
|
+
const textMessages = prompt.messages.flatMap((m) => m.content.map((c) => c.text));
|
|
96
|
+
let text = textMessages.join('\n\n');
|
|
97
|
+
text += prompt.system ? `\n\n\nIMPORTANT: ${prompt.system?.map((m) => m.text).join('\n\n')}` : '';
|
|
97
98
|
|
|
98
99
|
const conditionImage = (conditionImage: boolean) => {
|
|
99
100
|
const img = getFirstImageFromPrompt(prompt.messages);
|
|
100
101
|
if (img && conditionImage) {
|
|
101
|
-
return img
|
|
102
|
+
return img;
|
|
102
103
|
}
|
|
103
104
|
return undefined;
|
|
104
|
-
}
|
|
105
|
+
};
|
|
105
106
|
|
|
106
107
|
const payload: NovaColorGuidedGenerationPayload = {
|
|
107
108
|
taskType: NovaImageGenerationTaskType.COLOR_GUIDED_GENERATION,
|
|
@@ -116,38 +117,40 @@ async function colorGuidedGenerationPayload(prompt: NovaMessagesPrompt, options:
|
|
|
116
117
|
colorGuidedGenerationParams: {
|
|
117
118
|
colors: modelOptions.colors ?? [],
|
|
118
119
|
text: text,
|
|
119
|
-
referenceImage: conditionImage(modelOptions?.controlMode
|
|
120
|
-
negativeText: prompt.negative
|
|
121
|
-
}
|
|
122
|
-
}
|
|
120
|
+
referenceImage: conditionImage(!!modelOptions?.controlMode)?.source.bytes,
|
|
121
|
+
negativeText: prompt.negative,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
123
124
|
|
|
124
125
|
return payload;
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
async function backgroundRemovalPayload(prompt: NovaMessagesPrompt): Promise<NovaBackgroundRemovalPayload> {
|
|
128
|
-
|
|
129
129
|
const image = getFirstImageFromPrompt(prompt.messages);
|
|
130
130
|
if (!image?.source.bytes) {
|
|
131
|
-
throw new Error(
|
|
131
|
+
throw new Error('No image found in prompt');
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
const payload: NovaBackgroundRemovalPayload = {
|
|
135
135
|
taskType: NovaImageGenerationTaskType.BACKGROUND_REMOVAL,
|
|
136
136
|
backgroundRemovalParams: {
|
|
137
|
-
image: image.source.bytes
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
console.log(payload)
|
|
137
|
+
image: image.source.bytes,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
console.log(payload);
|
|
141
141
|
|
|
142
142
|
return payload;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
async function inpaintingPayload(
|
|
145
|
+
async function inpaintingPayload(
|
|
146
|
+
prompt: NovaMessagesPrompt,
|
|
147
|
+
options: ExecutionOptions,
|
|
148
|
+
): Promise<NovaInpaintingPayload> {
|
|
146
149
|
const modelOptions = options.model_options as NovaCanvasOptions;
|
|
147
150
|
|
|
148
151
|
const images = getAllImagesFromPrompt(prompt.messages);
|
|
149
152
|
if (!images?.length || images.length < 2) {
|
|
150
|
-
throw new Error(
|
|
153
|
+
throw new Error('2 images are required for inpainting');
|
|
151
154
|
}
|
|
152
155
|
const sourceImage = images[0];
|
|
153
156
|
const maskImage = images[1];
|
|
@@ -165,20 +168,23 @@ async function inpaintingPayload(prompt: NovaMessagesPrompt, options: ExecutionO
|
|
|
165
168
|
inPaintingParams: {
|
|
166
169
|
image: sourceImage,
|
|
167
170
|
maskImage: maskImage,
|
|
168
|
-
text: prompt.messages.
|
|
169
|
-
negativeText: prompt.negative
|
|
170
|
-
}
|
|
171
|
-
}
|
|
171
|
+
text: prompt.messages.flatMap((m) => m.content.map((c) => c.text)).join('\n\n'),
|
|
172
|
+
negativeText: prompt.negative,
|
|
173
|
+
},
|
|
174
|
+
};
|
|
172
175
|
|
|
173
176
|
return payload;
|
|
174
177
|
}
|
|
175
178
|
|
|
176
|
-
async function outpaintingPayload(
|
|
179
|
+
async function outpaintingPayload(
|
|
180
|
+
prompt: NovaMessagesPrompt,
|
|
181
|
+
options: ExecutionOptions,
|
|
182
|
+
): Promise<NovaOutpaintingPayload> {
|
|
177
183
|
const modelOptions = options.model_options as NovaCanvasOptions;
|
|
178
184
|
|
|
179
185
|
const images = getAllImagesFromPrompt(prompt.messages);
|
|
180
186
|
if (!images?.length || images.length < 2) {
|
|
181
|
-
throw new Error(
|
|
187
|
+
throw new Error('2 images are required for outpainting');
|
|
182
188
|
}
|
|
183
189
|
const sourceImage = images[0];
|
|
184
190
|
const maskImage = images[1];
|
|
@@ -196,17 +202,20 @@ async function outpaintingPayload(prompt: NovaMessagesPrompt, options: Execution
|
|
|
196
202
|
outPaintingParams: {
|
|
197
203
|
image: sourceImage,
|
|
198
204
|
maskImage: maskImage,
|
|
199
|
-
text: prompt.messages.
|
|
205
|
+
text: prompt.messages.flatMap((m) => m.content.map((c) => c.text)).join('\n\n'),
|
|
200
206
|
negativeText: prompt.negative,
|
|
201
|
-
outPaintingMode: modelOptions?.outPaintingMode ??
|
|
202
|
-
}
|
|
203
|
-
}
|
|
207
|
+
outPaintingMode: modelOptions?.outPaintingMode ?? 'DEFAULT',
|
|
208
|
+
},
|
|
209
|
+
};
|
|
204
210
|
|
|
205
211
|
return payload;
|
|
206
212
|
}
|
|
207
213
|
|
|
208
|
-
export function formatNovaImageGenerationPayload(
|
|
209
|
-
|
|
214
|
+
export function formatNovaImageGenerationPayload(
|
|
215
|
+
taskType: string,
|
|
216
|
+
prompt: NovaMessagesPrompt,
|
|
217
|
+
options: ExecutionOptions,
|
|
218
|
+
) {
|
|
210
219
|
switch (taskType) {
|
|
211
220
|
case NovaImageGenerationTaskType.TEXT_IMAGE:
|
|
212
221
|
return textToImagePayload(prompt, options);
|
|
@@ -223,9 +232,8 @@ export function formatNovaImageGenerationPayload(taskType: string, prompt: NovaM
|
|
|
223
232
|
case NovaImageGenerationTaskType.BACKGROUND_REMOVAL:
|
|
224
233
|
return backgroundRemovalPayload(prompt);
|
|
225
234
|
default:
|
|
226
|
-
throw new Error(
|
|
235
|
+
throw new Error('Task type not supported');
|
|
227
236
|
}
|
|
228
|
-
|
|
229
237
|
}
|
|
230
238
|
|
|
231
239
|
export interface InvokeModelPayloadBase {
|
|
@@ -233,7 +241,7 @@ export interface InvokeModelPayloadBase {
|
|
|
233
241
|
imageGenerationConfig: {
|
|
234
242
|
width?: number;
|
|
235
243
|
height?: number;
|
|
236
|
-
quality?:
|
|
244
|
+
quality?: 'standard' | 'premium';
|
|
237
245
|
cfgScale?: number;
|
|
238
246
|
seed?: number;
|
|
239
247
|
numberOfImages?: number;
|
|
@@ -243,21 +251,20 @@ export interface InvokeModelPayloadBase {
|
|
|
243
251
|
export interface NovaTextToImagePayload extends InvokeModelPayloadBase {
|
|
244
252
|
textToImageParams: {
|
|
245
253
|
conditionImage?: string;
|
|
246
|
-
controlMode?:
|
|
254
|
+
controlMode?: 'CANNY_EDGE' | 'SEGMENTATION';
|
|
247
255
|
controlStrength?: number;
|
|
248
256
|
text: string;
|
|
249
257
|
negativeText?: string;
|
|
250
258
|
};
|
|
251
259
|
}
|
|
252
260
|
|
|
253
|
-
|
|
254
261
|
export interface NovaImageVariationPayload extends InvokeModelPayloadBase {
|
|
255
262
|
imageVariationParams: {
|
|
256
|
-
images: string[]
|
|
257
|
-
similarityStrength?: number
|
|
258
|
-
text?: string
|
|
259
|
-
negativeText?: string
|
|
260
|
-
}
|
|
263
|
+
images: string[]; //(list of Base64 encoded images),
|
|
264
|
+
similarityStrength?: number;
|
|
265
|
+
text?: string;
|
|
266
|
+
negativeText?: string;
|
|
267
|
+
};
|
|
261
268
|
}
|
|
262
269
|
|
|
263
270
|
export interface NovaColorGuidedGenerationPayload extends InvokeModelPayloadBase {
|
|
@@ -266,43 +273,43 @@ export interface NovaColorGuidedGenerationPayload extends InvokeModelPayloadBase
|
|
|
266
273
|
text: string;
|
|
267
274
|
referenceImage?: string;
|
|
268
275
|
negativeText?: string;
|
|
269
|
-
}
|
|
276
|
+
};
|
|
270
277
|
}
|
|
271
278
|
|
|
272
279
|
export interface NovaInpaintingPayload extends InvokeModelPayloadBase {
|
|
273
280
|
inPaintingParams: {
|
|
274
281
|
image: string; //(Base64 encoded image),
|
|
275
282
|
maskImage?: string; //(Base64 encoded image),
|
|
276
|
-
maskPrompt?: string
|
|
277
|
-
negativeText?: string
|
|
278
|
-
text?: string
|
|
279
|
-
}
|
|
283
|
+
maskPrompt?: string;
|
|
284
|
+
negativeText?: string;
|
|
285
|
+
text?: string;
|
|
286
|
+
};
|
|
280
287
|
}
|
|
281
288
|
|
|
282
289
|
export interface NovaOutpaintingPayload extends InvokeModelPayloadBase {
|
|
283
290
|
outPaintingParams: {
|
|
284
291
|
image: string; //(Base64 encoded image),
|
|
285
292
|
maskImage?: string; //(Base64 encoded image),
|
|
286
|
-
maskPrompt?: string
|
|
287
|
-
negativeText?: string
|
|
288
|
-
text?: string
|
|
289
|
-
outPaintingMode:
|
|
290
|
-
}
|
|
293
|
+
maskPrompt?: string;
|
|
294
|
+
negativeText?: string;
|
|
295
|
+
text?: string;
|
|
296
|
+
outPaintingMode: 'DEFAULT' | 'PRECISE';
|
|
297
|
+
};
|
|
291
298
|
}
|
|
292
299
|
|
|
293
300
|
export interface NovaBackgroundRemovalPayload {
|
|
294
301
|
taskType: NovaImageGenerationTaskType.BACKGROUND_REMOVAL;
|
|
295
302
|
backgroundRemovalParams: {
|
|
296
|
-
image: string //(Base64 encoded image),
|
|
297
|
-
}
|
|
303
|
+
image: string; //(Base64 encoded image),
|
|
304
|
+
};
|
|
298
305
|
}
|
|
299
306
|
|
|
300
307
|
export enum NovaImageGenerationTaskType {
|
|
301
|
-
TEXT_IMAGE =
|
|
302
|
-
TEXT_IMAGE_WITH_IMAGE_CONDITIONING =
|
|
303
|
-
COLOR_GUIDED_GENERATION =
|
|
304
|
-
IMAGE_VARIATION =
|
|
305
|
-
INPAINTING =
|
|
306
|
-
OUTPAINTING =
|
|
307
|
-
BACKGROUND_REMOVAL =
|
|
308
|
-
}
|
|
308
|
+
TEXT_IMAGE = 'TEXT_IMAGE',
|
|
309
|
+
TEXT_IMAGE_WITH_IMAGE_CONDITIONING = 'TEXT_IMAGE_WITH_IMAGE_CONDITIONING',
|
|
310
|
+
COLOR_GUIDED_GENERATION = 'COLOR_GUIDED_GENERATION',
|
|
311
|
+
IMAGE_VARIATION = 'IMAGE_VARIATION',
|
|
312
|
+
INPAINTING = 'INPAINTING',
|
|
313
|
+
OUTPAINTING = 'OUTPAINTING',
|
|
314
|
+
BACKGROUND_REMOVAL = 'BACKGROUND_REMOVAL',
|
|
315
|
+
}
|
package/src/bedrock/payloads.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { NovaMessagesPrompt } from
|
|
1
|
+
import type { NovaMessagesPrompt } from '@llumiverse/core/formatters';
|
|
2
2
|
|
|
3
3
|
//Docs at: https://docs.aws.amazon.com/nova/latest/userguide/complete-request-schema.html
|
|
4
4
|
export interface NovaPayload extends NovaMessagesPrompt {
|
|
5
|
-
schemaVersion: string
|
|
5
|
+
schemaVersion: string;
|
|
6
6
|
inferenceConfig?: {
|
|
7
|
-
max_new_tokens?: number
|
|
8
|
-
temperature?: number
|
|
9
|
-
top_p?: number
|
|
10
|
-
top_k?: number
|
|
11
|
-
stopSequences?: [string]
|
|
12
|
-
}
|
|
13
|
-
}
|
|
7
|
+
max_new_tokens?: number;
|
|
8
|
+
temperature?: number;
|
|
9
|
+
top_p?: number;
|
|
10
|
+
top_k?: number;
|
|
11
|
+
stopSequences?: [string];
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { isAmazonS3Hostname, parseS3UrlToUri } from './s3.js';
|
|
3
|
+
|
|
4
|
+
describe('isAmazonS3Hostname', () => {
|
|
5
|
+
it('accepts supported Amazon S3 hostnames', () => {
|
|
6
|
+
expect(isAmazonS3Hostname('s3.amazonaws.com')).toBe(true);
|
|
7
|
+
expect(isAmazonS3Hostname('s3.us-east-1.amazonaws.com')).toBe(true);
|
|
8
|
+
expect(isAmazonS3Hostname('s3.dualstack.us-east-1.amazonaws.com')).toBe(true);
|
|
9
|
+
expect(isAmazonS3Hostname('my-bucket.s3.amazonaws.com')).toBe(true);
|
|
10
|
+
expect(isAmazonS3Hostname('my-bucket.s3.us-east-1.amazonaws.com')).toBe(true);
|
|
11
|
+
expect(isAmazonS3Hostname('my-bucket.s3.dualstack.us-east-1.amazonaws.com')).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('rejects hostnames that only contain amazonaws.com as a substring', () => {
|
|
15
|
+
expect(isAmazonS3Hostname('s3.amazonaws.com.example.com')).toBe(false);
|
|
16
|
+
expect(isAmazonS3Hostname('example-s3.amazonaws.com')).toBe(false);
|
|
17
|
+
expect(isAmazonS3Hostname('bucket.s3.amazonaws.com.evil.test')).toBe(false);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('parseS3UrlToUri', () => {
|
|
22
|
+
it('converts virtual-hosted style S3 URLs', () => {
|
|
23
|
+
expect(parseS3UrlToUri(new URL('https://my-bucket.s3.us-east-1.amazonaws.com/folder/video.mp4'))).toBe(
|
|
24
|
+
's3://my-bucket/folder/video.mp4',
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('converts path-style S3 URLs', () => {
|
|
29
|
+
expect(parseS3UrlToUri(new URL('https://s3.us-east-1.amazonaws.com/my-bucket/folder/video.mp4'))).toBe(
|
|
30
|
+
's3://my-bucket/folder/video.mp4',
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('rejects spoofed S3-looking URLs', () => {
|
|
35
|
+
expect(() => parseS3UrlToUri(new URL('https://bucket.s3.amazonaws.com.evil.test/video.mp4'))).toThrow(
|
|
36
|
+
'Unable to determine bucket name from URL',
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
});
|
package/src/bedrock/s3.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import { CreateBucketCommand, HeadBucketCommand, S3Client } from
|
|
2
|
-
import { Progress, Upload } from
|
|
1
|
+
import { CreateBucketCommand, HeadBucketCommand, type S3Client } from '@aws-sdk/client-s3';
|
|
2
|
+
import { type Progress, Upload } from '@aws-sdk/lib-storage';
|
|
3
|
+
|
|
4
|
+
const S3_AMAZONAWS_HOSTNAME_RE = /^(?:s3(?:\.[a-z0-9-]+)*|.+\.s3(?:\.[a-z0-9-]+)*)\.amazonaws\.com$/;
|
|
5
|
+
|
|
6
|
+
export function isAmazonS3Hostname(hostname: string): boolean {
|
|
7
|
+
return S3_AMAZONAWS_HOSTNAME_RE.test(hostname.toLowerCase());
|
|
8
|
+
}
|
|
3
9
|
|
|
4
10
|
export async function doesBucketExist(s3: S3Client, bucketName: string): Promise<boolean> {
|
|
5
11
|
try {
|
|
6
12
|
await s3.send(new HeadBucketCommand({ Bucket: bucketName }));
|
|
7
13
|
return true;
|
|
8
|
-
} catch (err:
|
|
9
|
-
if (err.name === 'NotFound') {
|
|
14
|
+
} catch (err: unknown) {
|
|
15
|
+
if (err && typeof err === 'object' && (err as { name?: unknown }).name === 'NotFound') {
|
|
10
16
|
return false;
|
|
11
17
|
}
|
|
12
18
|
throw err;
|
|
@@ -14,12 +20,13 @@ export async function doesBucketExist(s3: S3Client, bucketName: string): Promise
|
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
export function createBucket(s3: S3Client, bucketName: string) {
|
|
17
|
-
return s3.send(
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
return s3.send(
|
|
24
|
+
new CreateBucketCommand({
|
|
25
|
+
Bucket: bucketName,
|
|
26
|
+
}),
|
|
27
|
+
);
|
|
20
28
|
}
|
|
21
29
|
|
|
22
|
-
|
|
23
30
|
export async function tryCreateBucket(s3: S3Client, bucketName: string) {
|
|
24
31
|
const exists = await doesBucketExist(s3, bucketName);
|
|
25
32
|
if (!exists) {
|
|
@@ -27,19 +34,23 @@ export async function tryCreateBucket(s3: S3Client, bucketName: string) {
|
|
|
27
34
|
}
|
|
28
35
|
}
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
export async function uploadFile(
|
|
38
|
+
s3: S3Client,
|
|
39
|
+
source: ReadableStream,
|
|
40
|
+
bucketName: string,
|
|
41
|
+
file: string,
|
|
42
|
+
onProgress?: (progress: Progress) => void,
|
|
43
|
+
) {
|
|
33
44
|
const upload = new Upload({
|
|
34
45
|
client: s3,
|
|
35
46
|
params: {
|
|
36
47
|
Bucket: bucketName,
|
|
37
48
|
Key: file,
|
|
38
49
|
Body: source,
|
|
39
|
-
}
|
|
50
|
+
},
|
|
40
51
|
});
|
|
41
52
|
|
|
42
|
-
onProgress
|
|
53
|
+
if (onProgress) upload.on('httpUploadProgress', onProgress);
|
|
43
54
|
|
|
44
55
|
const result = await upload.done();
|
|
45
56
|
return result;
|
|
@@ -47,20 +58,25 @@ export async function uploadFile(s3: S3Client, source: ReadableStream, bucketNam
|
|
|
47
58
|
|
|
48
59
|
/**
|
|
49
60
|
* Create the bucket if not already exists and then upload the file.
|
|
50
|
-
* @param s3
|
|
51
|
-
* @param source
|
|
52
|
-
* @param bucketName
|
|
53
|
-
* @param file
|
|
54
|
-
* @param onProgress
|
|
55
|
-
* @returns
|
|
61
|
+
* @param s3
|
|
62
|
+
* @param source
|
|
63
|
+
* @param bucketName
|
|
64
|
+
* @param file
|
|
65
|
+
* @param onProgress
|
|
66
|
+
* @returns
|
|
56
67
|
*/
|
|
57
|
-
export async function forceUploadFile(
|
|
68
|
+
export async function forceUploadFile(
|
|
69
|
+
s3: S3Client,
|
|
70
|
+
source: ReadableStream,
|
|
71
|
+
bucketName: string,
|
|
72
|
+
file: string,
|
|
73
|
+
onProgress?: (progress: Progress) => void,
|
|
74
|
+
) {
|
|
58
75
|
// make sure the bucket exists
|
|
59
76
|
await tryCreateBucket(s3, bucketName);
|
|
60
77
|
return uploadFile(s3, source, bucketName, file, onProgress);
|
|
61
78
|
}
|
|
62
79
|
|
|
63
|
-
|
|
64
80
|
/**
|
|
65
81
|
* Parse an S3 HTTPS URL into an S3 URI format
|
|
66
82
|
* s3Url - The S3 HTTPS URL (e.g., https://bucket.s3.region.amazonaws.com/key)
|
|
@@ -71,25 +87,28 @@ export function parseS3UrlToUri(s3Url: URL) {
|
|
|
71
87
|
const url = new URL(s3Url);
|
|
72
88
|
|
|
73
89
|
// Extract the hostname which contains the bucket and S3 endpoint
|
|
74
|
-
const hostname = url.hostname;
|
|
90
|
+
const hostname = url.hostname.toLowerCase();
|
|
91
|
+
|
|
92
|
+
if (!isAmazonS3Hostname(hostname)) {
|
|
93
|
+
throw new Error('Unable to determine bucket name from URL');
|
|
94
|
+
}
|
|
75
95
|
|
|
76
96
|
// Parse the hostname to extract the bucket name
|
|
77
|
-
let bucketName;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
} else if (hostname.startsWith('s3.')) {
|
|
83
|
-
// Format: s3.region.amazonaws.com/bucket-name
|
|
84
|
-
// In this case, the bucket is actually in the first segment of the pathname
|
|
85
|
-
bucketName = url.pathname.split('/')[1];
|
|
86
|
-
// Adjust the pathname to remove the bucket name
|
|
87
|
-
const pathParts = url.pathname.split('/').slice(2);
|
|
88
|
-
url.pathname = '/' + pathParts.join('/');
|
|
89
|
-
} else {
|
|
90
|
-
throw new Error('Unable to determine bucket name from URL');
|
|
91
|
-
}
|
|
97
|
+
let bucketName: string | undefined;
|
|
98
|
+
const virtualHostedMatch = hostname.match(/^(.+)\.s3(?:\.[a-z0-9-]+)*\.amazonaws\.com$/);
|
|
99
|
+
if (virtualHostedMatch) {
|
|
100
|
+
// Format: bucket-name.s3.region.amazonaws.com
|
|
101
|
+
bucketName = virtualHostedMatch[1];
|
|
92
102
|
} else {
|
|
103
|
+
// Format: s3.region.amazonaws.com/bucket-name
|
|
104
|
+
// In this case, the bucket is actually in the first segment of the pathname
|
|
105
|
+
bucketName = url.pathname.split('/')[1];
|
|
106
|
+
// Adjust the pathname to remove the bucket name
|
|
107
|
+
const pathParts = url.pathname.split('/').slice(2);
|
|
108
|
+
url.pathname = `/${pathParts.join('/')}`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!bucketName) {
|
|
93
112
|
throw new Error('Unable to determine bucket name from URL');
|
|
94
113
|
}
|
|
95
114
|
|
|
@@ -106,4 +125,4 @@ export function parseS3UrlToUri(s3Url: URL) {
|
|
|
106
125
|
console.error('Error parsing S3 URL:', error);
|
|
107
126
|
throw error;
|
|
108
127
|
}
|
|
109
|
-
}
|
|
128
|
+
}
|