Bedrock Runtime
Protocol: REST JSON
Endpoint: POST http://localhost:4566/model/{modelId}/...
Floci emulates the AWS Bedrock Runtime data-plane API. The response shape matches the real AWS Converse and InvokeModel contracts so AWS SDK and CLI clients accept the reply without error.
Two backends are available, selected via floci.services.bedrock-runtime.backend:
stub(default) — no real model inference: every call returns a fixed assistant turn plus synthetic token usage metadata.proxy— forwardsConverserequests to any OpenAI-compatible/chat/completionsendpoint (Ollama, OpenRouter, LiteLLM, vLLM, ...), translating request/response shapes including tool use.InvokeModelstill falls back to the stub response in this mode. See Proxy Backend below.
The Bedrock management plane (aws bedrock ...: ListFoundationModels, GetFoundationModel, customization) is not yet emulated.
Supported Operations
| Operation | Endpoint | Notes |
|---|---|---|
Converse |
POST /model/{modelId}/converse |
stub: returns a static assistant message. proxy: forwards to the configured OpenAI-compatible backend and translates the reply. |
InvokeModel |
POST /model/{modelId}/invoke |
Returns Anthropic-shaped body for anthropic.* and *.anthropic.* model ids; generic {"outputs": [...]} shape otherwise. Not proxied yet — always the stub response, regardless of backend. |
ConverseStream |
POST /model/{modelId}/converse-stream |
Returns 501 UnsupportedOperationException |
InvokeModelWithResponseStream |
POST /model/{modelId}/invoke-with-response-stream |
Returns 501 UnsupportedOperationException |
modelId is URL-decoded by JAX-RS and echoed verbatim. Plain model ids (e.g. anthropic.claude-3-haiku-20240307-v1:0), inference-profile ids (e.g. us.anthropic.claude-3-5-sonnet-20241022-v2:0), and full ARNs containing slashes (e.g. arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.anthropic.claude-3-5-sonnet-20241022-v2:0) are all accepted.
Converse accepts messages, system, inferenceConfig, and toolConfig fields. Only messages is validated (non-empty array). With the stub backend, other fields are accepted and ignored, and tool-use round-tripping is not implemented. With the proxy backend, system, toolConfig.tools and toolConfig.toolChoice, and inferenceConfig (maxTokens, temperature, topP, stopSequences) are translated and forwarded (see below).
InvokeModel bodies are passed through as opaque bytes; neither backend parses request payloads.
Configuration
| Variable | Default | Description |
|---|---|---|
FLOCI_SERVICES_BEDROCK_RUNTIME_ENABLED |
true |
Enable or disable the service |
FLOCI_SERVICES_BEDROCK_RUNTIME_BACKEND |
stub |
stub or proxy |
FLOCI_SERVICES_BEDROCK_RUNTIME_PROXY_URL |
(none) | Base URL of the OpenAI-compatible backend, e.g. http://localhost:11434/v1. Required when backend=proxy. |
FLOCI_SERVICES_BEDROCK_RUNTIME_PROXY_API_KEY |
(none) | Sent as Authorization: Bearer {value} when set |
FLOCI_SERVICES_BEDROCK_RUNTIME_PROXY_DEFAULT_MODEL |
(none) | Fallback OpenAI-side model id when no mapping matches and passthrough is disabled |
FLOCI_SERVICES_BEDROCK_RUNTIME_PROXY_MODEL_MAPPING |
(none) | Comma-separated bedrockModelId=openaiModelId pairs, e.g. anthropic.claude-3-sonnet-20240229-v1:0=claude-3-sonnet |
FLOCI_SERVICES_BEDROCK_RUNTIME_PROXY_PASSTHROUGH |
false |
When true, forward the raw Bedrock model id as-is if no mapping matches |
Proxy Backend
Model resolution order for an incoming modelId: explicit model-mapping entry, then (if passthrough=true) the raw modelId as-is, then default-model, else a 400 ValidationException.
# Ollama (local, no API key needed)
export FLOCI_SERVICES_BEDROCK_RUNTIME_BACKEND=proxy
export FLOCI_SERVICES_BEDROCK_RUNTIME_PROXY_URL=http://localhost:11434/v1
export FLOCI_SERVICES_BEDROCK_RUNTIME_PROXY_DEFAULT_MODEL=llama3.2
Useful for integration testing: applications that call Bedrock directly don't need to stand up their own stub/mock of Bedrock — point the existing SDK client at Floci and get real responses from whatever OpenAI-compatible backend is already available, with the stubbing concern handled by Floci instead of the application under test.
Examples
export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_DEFAULT_REGION=us-east-1
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
# Converse
aws bedrock-runtime converse \
--model-id anthropic.claude-3-haiku-20240307-v1:0 \
--messages '[{"role":"user","content":[{"text":"hi"}]}]'
# InvokeModel (Anthropic Claude)
aws bedrock-runtime invoke-model \
--model-id anthropic.claude-3-haiku-20240307-v1:0 \
--body '{"anthropic_version":"bedrock-2023-05-31","max_tokens":100,"messages":[{"role":"user","content":"hi"}]}' \
--cli-binary-format raw-in-base64-out \
/tmp/response.json
cat /tmp/response.json
import boto3
client = boto3.client("bedrock-runtime", endpoint_url="http://localhost:4566")
resp = client.converse(
modelId="anthropic.claude-3-haiku-20240307-v1:0",
messages=[{"role": "user", "content": [{"text": "hi"}]}],
)
print(resp["output"]["message"]["content"][0]["text"])
Out of Scope
- Real model inference with the
stubbackend (always returns a fixed string). InvokeModelagainst theproxybackend (still returns the stub response).- Streaming (
ConverseStream,InvokeModelWithResponseStream) return 501, regardless of backend. - Bedrock management plane (
ListFoundationModels,GetFoundationModel, model customisation). - Bedrock Agents, Knowledge Bases, Guardrails, provisioned throughput.