# Kiro Gateway - Environment Configuration # Copy this file to .env and fill in your values # =========================================== # REQUIRED # =========================================== # Password to protect YOUR proxy server # This is NOT a token from anywhere - YOU make it up! # Use this same value as api_key when connecting to your gateway # Example: "my-super-secret-password-123" or any secure string PROXY_API_KEY="my-super-secret-password-123" # =========================================== # OPTION 1: Kiro IDE credentials (JSON file) # =========================================== # Path to JSON credentials file from Kiro IDE # KIRO_CREDS_FILE="~/.aws/sso/cache/kiro-auth-token.json" # =========================================== # OPTION 2: Kiro IDE refresh token # =========================================== # Your Kiro refresh token obtained from Kiro IDE traffic. # REFRESH_TOKEN="your_kiro_refresh_token_here" # =========================================== # OPTION 3: kiro-cli SQLite database (AWS SSO) # =========================================== # Path to kiro-cli SQLite database (for AWS IAM Identity Center users) # The gateway will auto-detect AWS SSO OIDC and use the correct endpoint # KIRO_CLI_DB_FILE="~/.local/share/kiro-cli/data.sqlite3" # Disable SQLite write-back (read-only mode) # When enabled, gateway will only read from kiro-cli database without modifying it. # Useful when kiro-cli is actively managing tokens and you don't want gateway to interfere. # Default: false (write-back enabled - gateway saves refreshed tokens back to SQLite) # SQLITE_READONLY=false # =========================================== # OPTION 4: AWS SSO cache file (kiro-cli) # =========================================== # Path to AWS SSO cache file (contains clientId and clientSecret) # The gateway will auto-detect AWS SSO OIDC and use the correct endpoint # KIRO_CREDS_FILE="~/.aws/sso/cache/your-sso-cache-file.json" # =========================================== # PROFILE ARN (optional) # =========================================== # AWS CodeWhisperer profile ARN # For Kiro IDE: usually auto-detected from credentials file # For kiro-cli (AWS SSO / Builder ID): not needed, will be ignored # PROFILE_ARN="arn:aws:codewhisperer:us-east-1:..." # =========================================== # OPTIONAL # =========================================== # AWS SSO/auth region (default: us-east-1) # This is where your AWS SSO/IAM Identity Center is configured. # Used for OIDC token refresh (authentication). # KIRO_REGION="us-east-1" # AWS Q API region (optional, auto-detected) # This is where Q Developer API endpoints are available. # The gateway automatically detects this from your credentials. # Only set manually if auto-detection fails or you need to override. # Example: Your SSO is in eu-west-1 but Q API only works in eu-central-1 # KIRO_API_REGION="eu-central-1" # =========================================== # SERVER SETTINGS # =========================================== # Server host (default: 0.0.0.0 - listen on all interfaces) # Use "127.0.0.1" to only allow local connections # SERVER_HOST="0.0.0.0" # Server port (default: 8000) # Useful when port 8000 is already in use by another application # # Configuration priority (highest to lowest): # 1. CLI arguments: python main.py --port 9000 # 2. Environment variables: SERVER_PORT=9000 # 3. Default value: 8000 # # Note: When using `uvicorn main:app --port 9000` directly, # uvicorn handles its own CLI arguments (this setting is ignored) # SERVER_PORT="8000" # =========================================== # VPN/PROXY SETTINGS # =========================================== # VPN/Proxy URL for accessing Kiro API through a proxy server. # Leave empty to connect directly (default). # # Use cases: # - China: GFW (Great Firewall) blocks AWS endpoints # - Corporate networks: Often require mandatory proxy # - Privacy: Hide your IP address from AWS # # Supports HTTP and SOCKS5 protocols. # Authentication can be embedded in the URL. # # Examples: # VPN_PROXY_URL="http://127.0.0.1:7890" # VPN_PROXY_URL="socks5://127.0.0.1:1080" # VPN_PROXY_URL="http://user:password@proxy.company.com:8080" # VPN_PROXY_URL="192.168.1.100:8080" # defaults to http:// # # VPN_PROXY_URL="" # =========================================== # MULTI-ACCOUNT SETTINGS # =========================================== # Enable multi-account system with intelligent failover (default: false) # # When false (legacy mode): # - Uses single account without failover # - credentials.json is recreated from .env on every startup # - Simpler for single-account setups # # When true (multi-account mode): # - Enables full failover loop with Circuit Breaker and sticky behavior # - Works even with single account (unified architecture) # - On first startup: automatically migrates .env → credentials.json (one-time) # - After migration: credentials.json takes priority, .env is ignored # - Manual credential management via credentials.json # # ACCOUNT_SYSTEM=false # Path to credentials configuration file # Automatically created from .env on first startup (if doesn't exist) # After creation, edit this file directly to manage accounts # See credentials.json.example for format # ACCOUNTS_CONFIG_FILE="credentials.json" # Path to runtime state file # Stores account statistics, failure counts, and model mappings # Automatically created and updated by the gateway # ACCOUNTS_STATE_FILE="state.json" # =========================================== # CIRCUIT BREAKER SETTINGS (Multi-Account) # =========================================== # Base recovery timeout in seconds (for exponential backoff) # Actual timeout = BASE * 2^(failures - 1), capped at BASE * MAX_MULTIPLIER # Examples with BASE=60s: 1 failure: 1m, 2: 2m, 3: 4m, 4: 8m, ..., 12+: 1d (cap) # ACCOUNT_RECOVERY_TIMEOUT=60 # Maximum backoff multiplier (cap for exponential backoff) # With BASE=60s and MAX=1440, maximum cooldown is 60 * 1440 = 86400s = 1 day # ACCOUNT_MAX_BACKOFF_MULTIPLIER=1440.0 # Probabilistic retry chance for "broken" accounts (0.0 - 1.0) # Even if account is broken and timeout hasn't passed, try with this probability # Default: 0.1 (10% chance) - prevents permanent "stuck" state # ACCOUNT_PROBABILISTIC_RETRY_CHANCE=0.1 # Model cache TTL in seconds (12 hours) # Cache is refreshed only when account is used (not in background) # ACCOUNT_CACHE_TTL=43200 # Interval for periodic state.json saving in seconds # STATE_SAVE_INTERVAL_SECONDS=10 # =========================================== # FIRST TOKEN TIMEOUT (Streaming Retry) # =========================================== # Timeout for waiting for the first token from the model (in seconds). # If the model doesn't respond within this time, the request will be cancelled and retried. # This helps handle "stuck" requests when the model takes too long to start responding. # Default: 15 seconds (recommended for production) # Set a lower value (e.g., 5-10) for more aggressive retry behavior. # FIRST_TOKEN_TIMEOUT="15" # Maximum number of retry attempts when first token timeout occurs. # After exhausting all attempts, a 504 Gateway Timeout error will be returned. # Default: 3 attempts # FIRST_TOKEN_MAX_RETRIES="3" # Read timeout for streaming responses (in seconds). # This is the maximum time to wait for data between chunks during streaming. # Should be longer than FIRST_TOKEN_TIMEOUT since the model may pause between chunks # while "thinking" (especially for tool calls or complex reasoning). # Default: 300 seconds (5 minutes) - generous timeout to avoid premature disconnects. # STREAMING_READ_TIMEOUT="300" # =========================================== # FAKE REASONING (Extended Thinking via Tag Injection) # =========================================== # Enable fake reasoning - injects special tags into requests to enable model reasoning. # When enabled, the model will include its reasoning process in the response. # The response is then parsed and converted to OpenAI-compatible reasoning_content format. # # WHY "FAKE"? This is NOT native extended thinking API support. Instead, we inject # enabled tags into the prompt, and the model responds # with ... blocks that we parse and convert to reasoning_content. # It works great, but it's a hack - hence "fake" reasoning. # # Default: true (ENABLED by default for premium experience out of the box) # To disable, set to false: # FAKE_REASONING=false # Maximum thinking length in tokens (default budget when client doesn't specify). # This value is injected into the request as {value} # Higher values allow for more detailed reasoning but increase response time and token usage. # Default: 4000 tokens # FAKE_REASONING_MAX_TOKENS=4000 # Maximum budget cap for client thinking budget requests. # Caps client's thinking budget to prevent consuming all output tokens on reasoning. # WHY CAP? Fake reasoning uses output tokens (not separate thinking tokens like native API). # Large budgets can cause the model to spend ALL output tokens on reasoning with NOTHING # left for actual content. This cap prevents that. # Default: 10000 tokens (2.5x default budget) - allows deeper reasoning while leaving room for response # Set to 0 to disable capping (not recommended for production) # FAKE_REASONING_BUDGET_CAP=10000 # How to handle the thinking block in responses: # - "as_reasoning_content": Extract to reasoning_content field (OpenAI-compatible, recommended) # - "remove": Remove thinking block completely, return only final answer # - "pass": Pass through as-is with original tags in content # - "strip_tags": Remove tags but keep thinking content in regular content # # Default: "as_reasoning_content" # FAKE_REASONING_HANDLING=as_reasoning_content # Maximum size of initial buffer for tag detection (characters). # The parser buffers this many characters before deciding if response contains thinking tags. # Lower values = faster first token appearance, but may miss tags with leading whitespace. # Default: 20 characters (enough for longest tag = 11 chars + some whitespace) # FAKE_REASONING_INITIAL_BUFFER_SIZE=20 # =========================================== # WEBSEARCH (MCP Tool Emulation) # =========================================== # Enable web_search tool auto-injection (default: true) # When enabled, web_search is automatically added as a tool for MCP emulation (Path B) # Model decides whether to use it or not # # Note: Native Anthropic server-side tools (Path A with "type" field) work ALWAYS, # regardless of this setting # WEB_SEARCH_ENABLED=true # =========================================== # PAYLOAD SIZE GUARD # =========================================== # Auto-trim conversation history when payload exceeds limit. # When enabled, oldest history pairs are removed until payload fits. # When disabled, returns clear error message instead. # Default: false (DISABLED by default - enable only if you use many tools and hit payload errors) # Enable if you use Claude Code or similar with 30+ tools and get "Improperly formed request" errors # AUTO_TRIM_PAYLOAD=false # Maximum payload size in bytes before auto-trim kicks in. # Kiro API rejects payloads over ~615KB with "Improperly formed request" error. # Default: 600000 (600KB) - leaves 15KB safety margin # KIRO_MAX_PAYLOAD_BYTES=600000 # =========================================== # TRUNCATION RECOVERY # =========================================== # Enable automatic truncation recovery when Kiro API cuts off large responses. # When the model generates large tool calls or content, the upstream API may truncate # the response mid-stream. This feature automatically notifies the model about truncation, # allowing it to adapt its approach (e.g., write smaller files, split operations). # # Default: true (ENABLED by default for better out-of-the-box experience) # TRUNCATION_RECOVERY=true # =========================================== # LOGGING # =========================================== # Log level: TRACE, DEBUG, INFO, WARNING, ERROR, CRITICAL # Default: INFO (recommended for production) # Set to DEBUG for detailed troubleshooting # LOG_LEVEL="INFO" # =========================================== # DEBUG (for development only) # =========================================== # Debug logging mode: # - off: disabled (default) # - errors: save logs only for failed requests (4xx, 5xx) - recommended for troubleshooting # - all: save logs for every request (overwrites on each request) # DEBUG_MODE=off # Directory for debug log files # DEBUG_DIR="debug_logs"