feat(ai): add requestMetadata support to BedrockOptions for cost allocation tagging (#2511)

Add an optional requestMetadata field to BedrockOptions that forwards
key-value pairs to the Bedrock Converse API ConverseStreamCommand. Tags
appear in AWS Cost Explorer split cost allocation data, enabling callers
to attribute inference costs to specific applications or contexts.

Changes:
- Add requestMetadata?: Record<string, string> to BedrockOptions with
  JSDoc documenting AWS constraints (max 50 pairs, key 64 chars, value
  256 chars, no aws: prefix)
- Pass requestMetadata to commandInput via conditional spread to avoid
  sending undefined when omitted
- Export BedrockOptions from package root (consistent with other
  provider option types)
- Add E2E tests: metadata forwarded to SDK payload, and omitted when
  not provided

closes #2510
This commit is contained in:
wjonaskr
2026-03-23 03:05:55 +09:00
committed by GitHub
parent b21b42d032
commit 3bcbae490c
4 changed files with 66 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ export { Type } from "@sinclair/typebox";
export * from "./api-registry.js";
export * from "./env-api-keys.js";
export * from "./models.js";
export type { BedrockOptions } from "./providers/amazon-bedrock.js";
export type { AnthropicOptions } from "./providers/anthropic.js";
export type { AzureOpenAIResponsesOptions } from "./providers/azure-openai-responses.js";
export type { GoogleOptions } from "./providers/google.js";

View File

@@ -55,6 +55,11 @@ export interface BedrockOptions extends StreamOptions {
thinkingBudgets?: ThinkingBudgets;
/* Only supported by Claude 4.x models, see https://docs.aws.amazon.com/bedrock/latest/userguide/claude-messages-extended-thinking.html#claude-messages-extended-thinking-tool-use-interleaved */
interleavedThinking?: boolean;
/** Key-value pairs attached to the inference request for cost allocation tagging.
* Keys: max 64 chars, no `aws:` prefix. Values: max 256 chars. Max 50 pairs.
* Tags appear in AWS Cost Explorer split cost allocation data.
* @see https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseStream.html */
requestMetadata?: Record<string, string>;
}
type Block = (TextContent | ThinkingContent | ToolCall) & { index?: number; partialJson?: string };
@@ -153,6 +158,7 @@ export const streamBedrock: StreamFunction<"bedrock-converse-stream", BedrockOpt
inferenceConfig: { maxTokens: options.maxTokens, temperature: options.temperature },
toolConfig: convertToolConfig(context.tools, options.toolChoice),
additionalModelRequestFields: buildAdditionalModelRequestFields(model, options),
...(options.requestMetadata !== undefined && { requestMetadata: options.requestMetadata }),
};
const nextCommandInput = await options?.onPayload?.(commandInput, model);
if (nextCommandInput !== undefined) {