Skip to content

Add support for AWS Bedrock LLM integration #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
848 changes: 846 additions & 2 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
[workspace]
resolver = "2"


members = [
"llm",
"llm-anthropic",
"llm-grok",
"llm-ollama",
"llm-openai",
"llm-openrouter",
"llm-bedrock"
]

[profile.release]
Expand Down
41 changes: 41 additions & 0 deletions Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,23 @@ install_crate = { crate_name = "cargo-component", version = "0.20.0" }
command = "cargo-component"
args = ["build", "-p", "golem-llm-openrouter", "--no-default-features"]

[tasks.build-bedrock]
install_crate = { crate_name = "cargo-component", version = "0.20.0" }
command = "cargo-component"
args = ["build", "-p", "golem-llm-bedrock"]

[tasks.build-bedrock-portable]
install_crate = { crate_name = "cargo-component", version = "0.20.0" }
command = "cargo-component"
args = ["build", "-p", "golem-llm-bedrock", "--no-default-features"]

[tasks.build]
dependencies = [
"build-anthropic",
"build-grok",
"build-openai",
"build-openrouter",
"build-bedrock",
"build-ollama",
]

Expand All @@ -77,6 +88,7 @@ dependencies = [
"build-grok-portable",
"build-openai-portable",
"build-openrouter-portable",
"build-bedrock-portable",
"build-ollama-portable",
]

Expand All @@ -92,6 +104,7 @@ cp target/wasm32-wasip1/debug/golem_llm_anthropic.wasm components/debug/golem_ll
cp target/wasm32-wasip1/debug/golem_llm_grok.wasm components/debug/golem_llm_grok.wasm
cp target/wasm32-wasip1/debug/golem_llm_openai.wasm components/debug/golem_llm_openai.wasm
cp target/wasm32-wasip1/debug/golem_llm_openrouter.wasm components/debug/golem_llm_openrouter.wasm
cp target/wasm32-wasip1/debug/golem_llm_bedrock.wasm components/debug/golem_llm_bedrock.wasm
cp target/wasm32-wasip1/debug/golem_llm_ollama.wasm components/debug/golem_llm_ollama.wasm

cm_run_task clean
Expand All @@ -101,6 +114,7 @@ cp target/wasm32-wasip1/debug/golem_llm_anthropic.wasm components/debug/golem_ll
cp target/wasm32-wasip1/debug/golem_llm_grok.wasm components/debug/golem_llm_grok-portable.wasm
cp target/wasm32-wasip1/debug/golem_llm_openai.wasm components/debug/golem_llm_openai-portable.wasm
cp target/wasm32-wasip1/debug/golem_llm_openrouter.wasm components/debug/golem_llm_openrouter-portable.wasm
cp target/wasm32-wasip1/debug/golem_llm_bedrock.wasm components/debug/golem_llm_bedrock-portable.wasm
cp target/wasm32-wasip1/debug/golem_llm_ollama.wasm components/debug/golem_llm_ollama-portable.wasm
'''

Expand Down Expand Up @@ -167,12 +181,29 @@ args = [
"--no-default-features",
]

[tasks.release-build-bedrock]
install_crate = { crate_name = "cargo-component", version = "0.20.0" }
command = "cargo-component"
args = ["build", "-p", "golem-llm-bedrock", "--release"]

[tasks.release-build-bedrock-portable]
install_crate = { crate_name = "cargo-component", version = "0.20.0" }
command = "cargo-component"
args = [
"build",
"-p",
"golem-llm-bedrock",
"--release",
"--no-default-features",
]

[tasks.release-build]
dependencies = [
"release-build-anthropic",
"release-build-grok",
"release-build-openai",
"release-build-openrouter",
"release-build-bedrock",
"release-build-ollama",
]

Expand All @@ -182,6 +213,7 @@ dependencies = [
"release-build-grok-portable",
"release-build-openai-portable",
"release-build-openrouter-portable",
"release-build-bedrock-portable",
"release-build-ollama-portable",
]

Expand All @@ -199,6 +231,7 @@ cp target/wasm32-wasip1/release/golem_llm_anthropic.wasm components/release/gole
cp target/wasm32-wasip1/release/golem_llm_grok.wasm components/release/golem_llm_grok.wasm
cp target/wasm32-wasip1/release/golem_llm_openai.wasm components/release/golem_llm_openai.wasm
cp target/wasm32-wasip1/release/golem_llm_openrouter.wasm components/release/golem_llm_openrouter.wasm
cp target/wasm32-wasip1/release/golem_llm_bedrock.wasm components/release/golem_llm_bedrock.wasm
cp target/wasm32-wasip1/release/golem_llm_ollama.wasm components/release/golem_llm_ollama.wasm

cm_run_task clean
Expand All @@ -208,6 +241,7 @@ cp target/wasm32-wasip1/release/golem_llm_anthropic.wasm components/release/gole
cp target/wasm32-wasip1/release/golem_llm_grok.wasm components/release/golem_llm_grok-portable.wasm
cp target/wasm32-wasip1/release/golem_llm_openai.wasm components/release/golem_llm_openai-portable.wasm
cp target/wasm32-wasip1/release/golem_llm_openrouter.wasm components/release/golem_llm_openrouter-portable.wasm
cp target/wasm32-wasip1/release/golem_llm_bedrock.wasm components/release/golem_llm_bedrock-portable.wasm
cp target/wasm32-wasip1/release/golem_llm_ollama.wasm components/release/golem_llm_ollama-portable.wasm
'''

Expand All @@ -228,6 +262,7 @@ dependencies = ["wit-update"]
# "llm-grok/wit/deps/golem-llm/golem-llm.wit",
# "llm-openai/wit/deps/golem-llm/golem-llm.wit",
# "llm-openrouter/wit/deps/golem-llm/golem-llm.wit",
# "llm-bedrock/wit/deps/golem-llm/golem-llm.wit",
#] } }

script_runner = "@duckscript"
Expand All @@ -252,6 +287,10 @@ rm -r llm-openrouter/wit/deps
mkdir llm-openrouter/wit/deps/golem-llm
cp wit/golem-llm.wit llm-openrouter/wit/deps/golem-llm/golem-llm.wit
cp wit/deps/wasi:io llm-openrouter/wit/deps
rm -r llm-bedrock/wit/deps
mkdir llm-bedrock/wit/deps/golem-llm
cp wit/golem-llm.wit llm-bedrock/wit/deps/golem-llm/golem-llm.wit
cp wit/deps/wasi:io llm-bedrock/wit/deps
rm -r llm-ollama/wit/deps
mkdir llm-ollama/wit/deps/golem-llm
cp wit/golem-llm.wit llm-ollama/wit/deps/golem-llm/golem-llm.wit
Expand Down Expand Up @@ -320,6 +359,8 @@ golem-cli --version
golem-cli app clean
golem-cli app build -b anthropic-debug
golem-cli app clean
golem-cli app build -b bedrock-debug
golem-cli app clean
golem-cli app build -b grok-debug
golem-cli app clean
golem-cli app build -b openai-debug
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ There are 8 published WASM files for each release:
| `golem-llm-grok.wasm` | LLM implementation for xAI (Grok), using custom Golem specific durability features |
| `golem-llm-openai.wasm` | LLM implementation for OpenAI, using custom Golem specific durability features |
| `golem-llm-openrouter.wasm` | LLM implementation for OpenRouter, using custom Golem specific durability features |
| `golem-llm-bedrock.wasm` | LLM implementation for AWS Bedrock, using custom Golem specific durability features |
| `golem-llm-anthropic-portable.wasm` | LLM implementation for Anthropic AI, with no Golem specific dependencies. |
| `golem-llm-ollama-portable.wasm` | LLM implementation for Ollama, with no Golem specific dependencies. |
| `golem-llm-grok-portable.wasm` | LLM implementation for xAI (Grok), with no Golem specific dependencies. |
| `golem-llm-openai-portable.wasm` | LLM implementation for OpenAI, with no Golem specific dependencies. |
| `golem-llm-openrouter-portable.wasm` | LLM implementation for OpenRouter, with no Golem specific dependencies. |
| `golem-llm-bedrock-portable.wasm` | LLM implementation for AWS Bedrock, with no Golem specific dependencies. |

Every component **exports** the same `golem:llm` interface, [defined here](wit/golem-llm.wit).

Expand All @@ -36,6 +38,8 @@ Each provider has to be configured with an API key passed as an environment vari
| Grok | `XAI_API_KEY` |
| OpenAI | `OPENAI_API_KEY` |
| OpenRouter | `OPENROUTER_API_KEY` |
| Bedrock | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN (optional), AWS_REGION (or AWS_DEFAULT_REGION). Relies on standard AWS SDK credential chain. The region can also be set via provider-options in the Config with key AWS_REGION. |
=======
| Ollama | `GOLEM_OLLAMA_BASE_URL` |

Additionally, setting the `GOLEM_LLM_LOG=trace` environment variable enables trace logging for all the communication
Expand Down
55 changes: 55 additions & 0 deletions llm-bedrock/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[package]
name = "golem-llm-bedrock"
version = "0.0.0"
edition = "2021"
license = "Apache-2.0"
homepage = "https://golem.cloud"
repository = "https://github.com/golemcloud/golem-llm"
description = "WebAssembly component for working with AWS Bedrock APIs, with special support for Golem Cloud"

[lib]
path = "src/lib.rs"
crate-type = ["cdylib"]

[features]
default = ["durability"]
durability = ["golem-rust/durability", "golem-llm/durability"]

[dependencies]
golem-llm = { path = "../llm", version = "0.0.0", default-features = false }
golem-rust = { workspace = true }
log = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
wit-bindgen-rt = { workspace = true }

# AWS SDK with WASI support - minimal configuration
aws-config = { version = "1.5.19", default-features = false, features = ["behavior-version-latest"] }
aws-sdk-bedrockruntime = { version = "1.56.0", default-features = false }
aws-smithy-wasm = { version = "0.1.4", default-features = false }
aws-types = { version = "1.3.4", default-features = false }
# Minimal tokio for WASI (only WASM-compatible features)
tokio = { version = "1.40", default-features = false, features = ["macros", "rt", "time", "io-util"] }
# HTTP client for image fetching (Bedrock requires image bytes, not URLs)
reqwest = { workspace = true }
# Base64 decoding for data URL images
base64 = "0.22"



[package.metadata.component]
package = "golem:llm-bedrock"

[package.metadata.component.bindings]
generate_unused_types = true

[package.metadata.component.bindings.with]
"golem:llm/llm@1.0.0" = "golem_llm::golem::llm::llm"
"wasi:io/poll@0.2.0" = "golem_rust::wasm_rpc::wasi::io::poll"

[package.metadata.component.target]
path = "wit"

[package.metadata.component.target.dependencies]
"golem:llm" = { path = "wit/deps/golem-llm" }
"wasi:io" = { path = "wit/deps/wasi:io"}
60 changes: 60 additions & 0 deletions llm-bedrock/src/bindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Generated by `wit-bindgen` 0.41.0. DO NOT EDIT!
// Options used:
// * runtime_path: "wit_bindgen_rt"
// * with "wasi:io/poll@0.2.0" = "golem_rust::wasm_rpc::wasi::io::poll"
// * with "golem:llm/llm@1.0.0" = "golem_llm::golem::llm::llm"
// * generate_unused_types
use golem_rust::wasm_rpc::wasi::io::poll as __with_name0;
use golem_llm::golem::llm::llm as __with_name1;
#[cfg(target_arch = "wasm32")]
#[unsafe(
link_section = "component-type:wit-bindgen:0.41.0:golem:llm-bedrock@1.0.0:llm-library:encoded world"
)]
#[doc(hidden)]
#[allow(clippy::octal_escapes)]
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1892] = *b"\
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xe2\x0d\x01A\x02\x01\
A\x05\x01B\x0a\x04\0\x08pollable\x03\x01\x01h\0\x01@\x01\x04self\x01\0\x7f\x04\0\
\x16[method]pollable.ready\x01\x02\x01@\x01\x04self\x01\x01\0\x04\0\x16[method]p\
ollable.block\x01\x03\x01p\x01\x01py\x01@\x01\x02in\x04\0\x05\x04\0\x04poll\x01\x06\
\x03\0\x12wasi:io/poll@0.2.0\x05\0\x02\x03\0\0\x08pollable\x01BO\x02\x03\x02\x01\
\x01\x04\0\x08pollable\x03\0\0\x01m\x04\x04user\x09assistant\x06system\x04tool\x04\
\0\x04role\x03\0\x02\x01m\x06\x0finvalid-request\x15authentication-failed\x13rat\
e-limit-exceeded\x0einternal-error\x0bunsupported\x07unknown\x04\0\x0aerror-code\
\x03\0\x04\x01m\x06\x04stop\x06length\x0atool-calls\x0econtent-filter\x05error\x05\
other\x04\0\x0dfinish-reason\x03\0\x06\x01m\x03\x03low\x04high\x04auto\x04\0\x0c\
image-detail\x03\0\x08\x01k\x09\x01r\x02\x03urls\x06detail\x0a\x04\0\x09image-ur\
l\x03\0\x0b\x01q\x02\x04text\x01s\0\x05image\x01\x0c\0\x04\0\x0ccontent-part\x03\
\0\x0d\x01ks\x01p\x0e\x01r\x03\x04role\x03\x04name\x0f\x07content\x10\x04\0\x07m\
essage\x03\0\x11\x01r\x03\x04names\x0bdescription\x0f\x11parameters-schemas\x04\0\
\x0ftool-definition\x03\0\x13\x01r\x03\x02ids\x04names\x0earguments-jsons\x04\0\x09\
tool-call\x03\0\x15\x01ky\x01r\x04\x02ids\x04names\x0bresult-jsons\x11execution-\
time-ms\x17\x04\0\x0ctool-success\x03\0\x18\x01r\x04\x02ids\x04names\x0derror-me\
ssages\x0aerror-code\x0f\x04\0\x0ctool-failure\x03\0\x1a\x01q\x02\x07success\x01\
\x19\0\x05error\x01\x1b\0\x04\0\x0btool-result\x03\0\x1c\x01r\x02\x03keys\x05val\
ues\x04\0\x02kv\x03\0\x1e\x01kv\x01ps\x01k!\x01p\x14\x01p\x1f\x01r\x07\x05models\
\x0btemperature\x20\x0amax-tokens\x17\x0estop-sequences\"\x05tools#\x0btool-choi\
ce\x0f\x10provider-options$\x04\0\x06config\x03\0%\x01r\x03\x0cinput-tokens\x17\x0d\
output-tokens\x17\x0ctotal-tokens\x17\x04\0\x05usage\x03\0'\x01k\x07\x01k(\x01r\x05\
\x0dfinish-reason)\x05usage*\x0bprovider-id\x0f\x09timestamp\x0f\x16provider-met\
adata-json\x0f\x04\0\x11response-metadata\x03\0+\x01p\x16\x01r\x04\x02ids\x07con\
tent\x10\x0atool-calls-\x08metadata,\x04\0\x11complete-response\x03\0.\x01r\x03\x04\
code\x05\x07messages\x13provider-error-json\x0f\x04\0\x05error\x03\00\x01q\x03\x07\
message\x01/\0\x0ctool-request\x01-\0\x05error\x011\0\x04\0\x0achat-event\x03\02\
\x01k\x10\x01k-\x01r\x02\x07content4\x0atool-calls5\x04\0\x0cstream-delta\x03\06\
\x01q\x03\x05delta\x017\0\x06finish\x01,\0\x05error\x011\0\x04\0\x0cstream-event\
\x03\08\x04\0\x0bchat-stream\x03\x01\x01h:\x01p9\x01k<\x01@\x01\x04self;\0=\x04\0\
\x1c[method]chat-stream.get-next\x01>\x01@\x01\x04self;\0<\x04\0%[method]chat-st\
ream.blocking-get-next\x01?\x01i\x01\x01@\x01\x04self;\0\xc0\0\x04\0\x1d[method]\
chat-stream.subscribe\x01A\x01p\x12\x01@\x02\x08messages\xc2\0\x06config&\03\x04\
\0\x04send\x01C\x01o\x02\x16\x1d\x01p\xc4\0\x01@\x03\x08messages\xc2\0\x0ctool-r\
esults\xc5\0\x06config&\03\x04\0\x08continue\x01F\x01i:\x01@\x02\x08messages\xc2\
\0\x06config&\0\xc7\0\x04\0\x06stream\x01H\x04\0\x13golem:llm/llm@1.0.0\x05\x02\x04\
\0#golem:llm-bedrock/llm-library@1.0.0\x04\0\x0b\x11\x01\0\x0bllm-library\x03\0\0\
\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.227.1\x10wit-bind\
gen-rust\x060.41.0";
#[inline(never)]
#[doc(hidden)]
pub fn __link_custom_section_describing_imports() {
wit_bindgen_rt::maybe_link_cabi_realloc();
}
Loading
Loading