Feature: Implement Kiro AI Provider
Category: Feature
Priority: High
Related: Providers module (crates/infrastructure/providers-kiro)
What
Implement a Kiro AI provider that integrates with AWS CodeWhisperer / AWS Bedrock API. This enables Cortex users to use Kiro AI through the gateway.
Why
Kiro AI is a popular IDE coding assistant that uses AWS CodeWhisperer under the hood. Users want to route Kiro AI traffic through Cortex for:
- Unified API access across multiple providers
- Cost tracking and analytics
- Fallback and retry logic
- Protocol translation (OpenAI-compatible API)
API Overview
Based on OmniRoute's implementation, Kiro uses AWS CodeWhisperer streaming API:
Endpoint
POST /prod/codewhisperer/streaming
Base URL
https://us-east-1.api.aws
Authentication
- Bearer token (AWS credentials: access token)
- Header:
Authorization: Bearer <token>
Additional Headers
Amz-Sdk-Request: attempt=1; max=3
Amz-Sdk-Invocation-Id: <uuid>
x-amzn-bedrock-cache-control: enable
anthropic-beta: prompt-caching-2024-07-31
Request Format
Kiro expects a simplified JSON payload (NOT OpenAI format):
{
"conversationState": {
"history": [
{
"userInputMessage": {
"content": "message content",
"modelId": "anthropic.claude-3-5-sonnet-20241022-v2:0",
"origin": "AI_EDITOR",
"userInputMessageContext": {
"toolResults": [...],
"tools": [...]
}
}
},
{
"assistantResponseMessage": {
"content": "response content",
"toolUses": [...]
}
}
],
"currentMessage": {
"userInputMessage": {
"content": "latest user message",
"modelId": "anthropic.claude-3-5-sonnet-20241022-v2:0",
"origin": "AI_EDITOR"
}
}
},
"profileArn": "arn:aws:codewhisperer:us-east-1:...",
"inferenceConfig": {
"maxTokens": 2048,
"temperature": 0.5
}
}
Message Conversion Rules
- Roles: OpenAI
system, tool, user → Kiro userInputMessage
- Roles: OpenAI
assistant → Kiro assistantResponseMessage
- Tool calls: Convert to Kiro
toolUses format
- Images: Convert to
{ format: string, source: { bytes: string } }
Tool Schema Restrictions
Kiro API is strict:
required arrays cannot be empty []
additionalProperties is not supported
- Tool descriptions > 10,000 chars cause errors
Response Format (EventStream)
Kiro uses AWS EventStream binary format. Each frame has:
- 4-byte length header (big-endian)
- JSON payload with
headers and payload
Event Types to Handle
-
assistantResponseEvent: Main text content
{ "content": "text response" }
-
codeEvent: Code blocks
{ "content": "code content" }
-
toolUseEvent: Tool call requests
{
"toolUseId": "...",
"name": "tool_name",
"input": { ... }
}
-
messageStopEvent: End of response
-
contextUsageEvent: Context window usage
{ "contextUsagePercentage": 45.2 }
-
metricsEvent: Token usage
{
"inputTokens": 1000,
"outputTokens": 500,
"cacheReadTokens": 200,
"cacheCreationTokens": 100
}
-
meteringEvent: Usage tracking
Output Format (OpenAI SSE)
Convert Kiro events to OpenAI streaming format:
{
"id": "chatcmpl-xxx",
"object": "chat.completion.chunk",
"created": 1234567890,
"model": "kiro",
"choices": [{
"index": 0,
"delta": { "role": "assistant", "content": "..." },
"finish_reason": null
}]
}
Tool Calls Format
{
"delta": {
"tool_calls": [{
"index": 0,
"id": "call_xxx",
"type": "function",
"function": {
"name": "tool_name",
"arguments": "{\"arg\": \"value\"}"
}
}]
}
}
Finish Chunk
{
"choices": [{
"delta": {},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 1000,
"completion_tokens": 500,
"total_tokens": 1500,
"cache_read_input_tokens": 200,
"cache_creation_input_tokens": 100
}
}
What's Already There (Template)
Based on other providers in crates/infrastructure/providers-*/:
Implementation Tasks
1. Create Provider Module
crates/infrastructure/providers-kiro/
├── Cargo.toml
├── src/
│ ├── lib.rs # Config + Provider struct
│ ├── client.rs # HTTP client + request building
│ ├── translator.rs # OpenAI → Kiro request translation
│ ├── parser.rs # EventStream binary parsing
│ └── response.rs # Kiro → OpenAI response translation
└── tests/
└── integration.rs
2. Implement Request Translation
Convert CompletionRequest → Kiro format:
convert_messages(): OpenAI messages → Kiro conversation state
convert_tools(): OpenAI tools → Kiro tool specifications
convert_images(): OpenAI image URLs → Kiro base64 format
- Handle role normalization and message merging
3. Implement EventStream Parser
Parse AWS EventStream binary frames:
- Read 4-byte length header
- Parse headers (
:event-type, etc.)
- Extract payload JSON
- Handle different event types
4. Implement Response Translation
Convert Kiro events → OpenAI SSE:
assistantResponseEvent → text delta
codeEvent → code delta
toolUseEvent → tool call delta
messageStopEvent → finish chunk
metricsEvent → usage data
5. Implement complete() and stream()
async fn complete(&self, req: &CompletionRequest) -> NuxaResult<CompletionResponse>
async fn stream(&self, req: &CompletionRequest) -> NuxaResult<BoxStream<'_, NuxaResult<StreamChunk>>>
6. Error Handling
- Handle AWS EventStream parsing errors
- Handle invalid credentials
- Handle rate limiting
- Handle model not available (HTTP 400)
- Handle timeout
7. Testing
Acceptance Criteria
References
- OmniRoute Kiro implementation: https://github.com/diegosouzapw/OmniRoute
- Executors:
open-sse/executors/kiro.ts
- Request translator:
open-sse/translator/request/openai-to-kiro.ts
- Response translator:
open-sse/translator/response/kiro-to-openai.ts
- MITM config:
src/mitm/targets/kiro.ts
- AWS CodeWhisperer API docs (requires AWS account)
Notes
- Kiro is essentially AWS CodeWhisperer rebranded
- Uses AWS EventStream binary format (different from SSE)
- Requires valid AWS credentials with CodeWhisperer access
- Profile ARN identifies the CodeWhisperer profile to use
- Supports prompt caching with
anthropic-beta header
Feature: Implement Kiro AI Provider
Category: Feature
Priority: High
Related: Providers module (crates/infrastructure/providers-kiro)
What
Implement a Kiro AI provider that integrates with AWS CodeWhisperer / AWS Bedrock API. This enables Cortex users to use Kiro AI through the gateway.
Why
Kiro AI is a popular IDE coding assistant that uses AWS CodeWhisperer under the hood. Users want to route Kiro AI traffic through Cortex for:
API Overview
Based on OmniRoute's implementation, Kiro uses AWS CodeWhisperer streaming API:
Endpoint
Base URL
Authentication
Authorization: Bearer <token>Additional Headers
Request Format
Kiro expects a simplified JSON payload (NOT OpenAI format):
{ "conversationState": { "history": [ { "userInputMessage": { "content": "message content", "modelId": "anthropic.claude-3-5-sonnet-20241022-v2:0", "origin": "AI_EDITOR", "userInputMessageContext": { "toolResults": [...], "tools": [...] } } }, { "assistantResponseMessage": { "content": "response content", "toolUses": [...] } } ], "currentMessage": { "userInputMessage": { "content": "latest user message", "modelId": "anthropic.claude-3-5-sonnet-20241022-v2:0", "origin": "AI_EDITOR" } } }, "profileArn": "arn:aws:codewhisperer:us-east-1:...", "inferenceConfig": { "maxTokens": 2048, "temperature": 0.5 } }Message Conversion Rules
system,tool,user→ KirouserInputMessageassistant→ KiroassistantResponseMessagetoolUsesformat{ format: string, source: { bytes: string } }Tool Schema Restrictions
Kiro API is strict:
requiredarrays cannot be empty[]additionalPropertiesis not supportedResponse Format (EventStream)
Kiro uses AWS EventStream binary format. Each frame has:
headersandpayloadEvent Types to Handle
assistantResponseEvent: Main text content{ "content": "text response" }codeEvent: Code blocks{ "content": "code content" }toolUseEvent: Tool call requests{ "toolUseId": "...", "name": "tool_name", "input": { ... } }messageStopEvent: End of responsecontextUsageEvent: Context window usage{ "contextUsagePercentage": 45.2 }metricsEvent: Token usage{ "inputTokens": 1000, "outputTokens": 500, "cacheReadTokens": 200, "cacheCreationTokens": 100 }meteringEvent: Usage trackingOutput Format (OpenAI SSE)
Convert Kiro events to OpenAI streaming format:
{ "id": "chatcmpl-xxx", "object": "chat.completion.chunk", "created": 1234567890, "model": "kiro", "choices": [{ "index": 0, "delta": { "role": "assistant", "content": "..." }, "finish_reason": null }] }Tool Calls Format
{ "delta": { "tool_calls": [{ "index": 0, "id": "call_xxx", "type": "function", "function": { "name": "tool_name", "arguments": "{\"arg\": \"value\"}" } }] } }Finish Chunk
{ "choices": [{ "delta": {}, "finish_reason": "stop" }], "usage": { "prompt_tokens": 1000, "completion_tokens": 500, "total_tokens": 1500, "cache_read_input_tokens": 200, "cache_creation_input_tokens": 100 } }What's Already There (Template)
Based on other providers in
crates/infrastructure/providers-*/:KiroProviderConfigstruct with:id: ProviderIdaccess_token: String(Bearer token)profile_arn: Stringbase_url: String(default:https://us-east-1.api.aws)models: Vec<ModelId>timeout_secs: u64KiroProviderstruct withClientProviderPortimplementationImplementation Tasks
1. Create Provider Module
2. Implement Request Translation
Convert
CompletionRequest→ Kiro format:convert_messages(): OpenAI messages → Kiro conversation stateconvert_tools(): OpenAI tools → Kiro tool specificationsconvert_images(): OpenAI image URLs → Kiro base64 format3. Implement EventStream Parser
Parse AWS EventStream binary frames:
:event-type, etc.)4. Implement Response Translation
Convert Kiro events → OpenAI SSE:
assistantResponseEvent→ text deltacodeEvent→ code deltatoolUseEvent→ tool call deltamessageStopEvent→ finish chunkmetricsEvent→ usage data5. Implement
complete()andstream()6. Error Handling
7. Testing
Acceptance Criteria
References
open-sse/executors/kiro.tsopen-sse/translator/request/openai-to-kiro.tsopen-sse/translator/response/kiro-to-openai.tssrc/mitm/targets/kiro.tsNotes
anthropic-betaheader