feat: add Bedrock Mantle API format support for harness#1412
Conversation
Package TarballHow to installgh release download pr-1412-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.18.0.tgz |
|
Claude Security Review: no high-confidence findings. (run) |
|
Claude Security Review: no high-confidence findings. (run) |
|
I have tested this E2E using the tarball |
|
Claude Security Review: no high-confidence findings. (run) |
Add apiFormat field to harness bedrockModelConfig that allows users to select between converse_stream (default Bedrock), responses, or chat_completions (Bedrock Mantle) when creating a harness. - Schema: add BedrockApiFormatSchema enum and apiFormat field to HarnessModelSchema - API types: add apiFormat to BedrockModelConfig interface - Mapper: include apiFormat in bedrockModelConfig when not converse_stream - TUI: add api-format wizard step for bedrock provider (gated behind isPreviewEnabled) - CDK: add BedrockMantleInference/CallWithBearerToken IAM policies when mantle format selected - CLI: add --api-format flag, default model ID to openai.gpt-oss-120b for mantle formats - Validation: reject apiFormat for non-bedrock providers E2E tested against account 998846730471 in ap-southeast-2.
- Schema: accepts/rejects apiFormat for bedrock/non-bedrock providers - Mapper: verifies apiFormat included in bedrockModelConfig, omitted for converse_stream - Validate: tests CLI --api-format flag validation
…n to add harness path Address review feedback: - Replace hardcoded format array with BedrockApiFormatSchema.options in create harness validation - Add upfront apiFormat validation to validateAddHarnessOptions (add harness path) so invalid values fail early instead of falling through to a Zod ConfigValidationError
The Loopy service Smithy model defines HarnessOpenAiApiFormat with responses and chat_completions values. This change extends the CLI to support apiFormat for the open_ai provider in addition to bedrock. - Add OpenAiApiFormatSchema (responses | chat_completions) and HarnessApiFormatSchema (union of all formats) to schema - Update HarnessModelSchema superRefine to validate per-provider formats - Add apiFormat field to OpenAiModelConfig API type - Update deploy mapper to pass apiFormat in openAiModelConfig - Update CLI validation (create + add) to accept apiFormat for open_ai - Update TUI wizard to show format step for open_ai with correct options - Fix default model ID logic: only use Bedrock Mantle model ID for bedrock provider, not open_ai - Add tests for OpenAI apiFormat in validation and mapper
|
Claude Security Review: no high-confidence findings. (run) |
| if (!allFormats.includes(options.apiFormat as (typeof allFormats)[number])) { | ||
| return { | ||
| valid: false, | ||
| error: `Invalid API format: ${options.apiFormat}. Use ${allFormats.join(', ')}`, |
There was a problem hiding this comment.
maybe OOS,but we should migrate the error to a typed error instead of a string to get better error classification in telemetry.
| const VALID_GATEWAY_OUTBOUND_AUTH = ['awsIam', 'none', 'oauth'] as const; | ||
|
|
||
| export function validateAddHarnessOptions(options: AddHarnessCliOptions): ValidationResult { | ||
| if (options.apiFormat) { |
There was a problem hiding this comment.
Could this validation logic live on the schema itself as either a discriminated union or part of the superRefine block? curious if we can get zod to do some of the heavy lifting here.
| openAiModelConfig: { | ||
| modelId, | ||
| ...(apiKeyArn && { apiKeyArn }), | ||
| ...(apiFormat && apiFormat !== 'responses' && { apiFormat: apiFormat as 'responses' | 'chat_completions' }), |
There was a problem hiding this comment.
I think this cast is only necessary because the the validation logic isn't on the schema.
| export const OpenAiApiFormatSchema = z.enum(['responses', 'chat_completions']); | ||
| export type OpenAiApiFormat = z.infer<typeof OpenAiApiFormatSchema>; | ||
|
|
||
| export const HarnessApiFormatSchema = z.enum(['converse_stream', 'responses', 'chat_completions']); |
There was a problem hiding this comment.
nit: isn't this just the union of the above in the general case?
Add validateApiFormat() helper in the schema that delegates to HarnessModelSchema.safeParse(), eliminating duplicated provider/format checking in both validateAddHarnessOptions and validateCreateHarnessOptions. The schema's superRefine remains the single source of truth for which providers support which formats.
|
Claude Security Review: no high-confidence findings. (run) |
|
Nice, I like that the schema is the source of truth and the logic is centralized. Looks like we might be missing some cases based on some failing unit tests?: |
yeah it was the error message wording that was different between the implementation and test. |
|
Claude Security Review: no high-confidence findings. (run) |
Summary
apiFormatfield to harness model configuration allowing users to select the API format for model invocationconverse_stream(default),responses, orchat_completions(via Bedrock Mantle)responses(default) orchat_completionsresponsesorchat_completionsfor Bedrock, the CLI defaults model ID toopenai.gpt-oss-120band adds Bedrock Mantle IAM permissions to the harness execution roleisPreviewEnabled()since harness is in previewapiFormatlives inside provider-specific model config (bedrockModelConfig/openAiModelConfig)Changes
primitives/harness.ts,primitives/index.ts,agentcore-project.tsaws/agentcore-harness.tsharness-mapper.tstypes.ts,useAddHarnessWizard.ts,AddHarnessScreen.tsx,AddHarnessFlow.tsx,useCreateFlow.tsHarnessPrimitive.ts,harness-action.ts,harness-validate.tsadd/validate.tsAgentCoreHarnessRole.ts(in agentcore-cdk repo)assets/cdk/bin/cdk.tsTest plan
agentcore add harness --api-format responses→ deploy → harness READY (account 998846730471, ap-southeast-2)bedrock-mantle:CreateInferenceas expected — CDK IAM PR needed)Notes
HarnessOpenAiApiFormatenum withresponsesandchat_completions)converse_streamis omitted from API payloads for Bedrock (it's the default);responsesis omitted for OpenAI (it's the default)