@sunerpy/kiro-provider 3.2.1 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +62 -469
  2. package/dist/cli.js +59 -58
  3. package/package.json +11 -6
package/README.md CHANGED
@@ -1,31 +1,23 @@
1
+ <div align="center">
2
+
1
3
  # kiro-provider
2
4
 
3
- > An OpenAI Responses-compatible provider over AWS KiroRuntime, with native Responses and protocol-fidelity stateless fallback transports.
5
+ ### OpenAI Responses and Anthropic Messages over AWS KiroRuntime
4
6
 
5
7
  [![CI](https://github.com/sunerpy/kiro-provider/actions/workflows/ci.yml/badge.svg)](https://github.com/sunerpy/kiro-provider/actions/workflows/ci.yml)
8
+ [![Release](https://img.shields.io/github/v/release/sunerpy/kiro-provider)](https://github.com/sunerpy/kiro-provider/releases)
9
+ [![npm](https://img.shields.io/npm/v/%40sunerpy%2Fkiro-provider)](https://www.npmjs.com/package/@sunerpy/kiro-provider)
6
10
  [![codecov](https://codecov.io/gh/sunerpy/kiro-provider/branch/main/graph/badge.svg)](https://codecov.io/gh/sunerpy/kiro-provider)
7
- [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
11
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
8
12
  [![Bun](https://img.shields.io/badge/runtime-bun-black)](https://bun.sh/)
9
13
 
10
- [简体中文](docs/readme/README.zh.md) · English
11
-
12
- ## Table of Contents
13
-
14
- - [Features](#features)
15
- - [Protocol compatibility](#protocol-compatibility)
16
- - [Install](#install)
17
- - [Quickstart](#quickstart)
18
- - [Run as a background service](#run-as-a-background-service)
19
- - [Configuration](#configuration)
20
- - [Proxy](#proxy)
21
- - [Security](#security)
22
- - [Using with an LLM](#using-with-an-llm)
23
- - [Use with Zuno](#use-with-zuno)
24
- - [Use with Codex CLI](#use-with-codex-cli)
25
- - [Use with Claude Code](#use-with-claude-code)
26
- - [Troubleshooting](#troubleshooting)
27
- - [Development](#development)
28
- - [License](#license)
14
+ [Install](#install) · [Quickstart](#quickstart) · [Protocol](#protocol-compatibility) · [Clients](#client-integrations) · [Docs](#documentation) · [Development](#development)
15
+
16
+ [**English**](./README.md) · [简体中文](./docs/readme/README.zh-CN.md)
17
+
18
+ </div>
19
+
20
+ ---
29
21
 
30
22
  ## Features
31
23
 
@@ -177,7 +169,7 @@ In the rest of this README, `./dist/kiro-provider` refers to any of the above; s
177
169
  ```
178
170
 
179
171
  Replace `sk-your-private-key` with a private, random value (for example
180
- `openssl rand -hex 24`). The fully annotated
172
+ `openssl rand -hex 24`). The complete
181
173
  [`config.example.json`](config.example.json) in the repository and
182
174
  [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md) describe every field.
183
175
 
@@ -266,282 +258,35 @@ In the rest of this README, `./dist/kiro-provider` refers to any of the above; s
266
258
 
267
259
  ## Run as a background service
268
260
 
269
- For an agent host, run **one long-lived provider per OS user** and point
270
- compatible OpenAI/Anthropic clients, OpenCode, Zuno, and compatibility probes
271
- for Codex or Claude Code at that local endpoint.
272
- Do not start a new provider for every agent or conversation. Keeping one
273
- process alive lets requests with an explicit affinity key reuse their
274
- persisted account/Kiro-conversation binding, while all requests can reuse
275
- process-local, account-scoped SDK clients and transport objects. A request
276
- without an explicit key starts a fresh Kiro conversation on its first turn,
277
- then can recover the same binding from exact assistant-output history on later
278
- turns. Kiro model-call HTTP sockets are fresh by default
279
- (`sdk_http_keep_alive: false`); enabling it is a best-effort transport
280
- optimization, never a promise that one session owns one physical TCP
281
- connection. The default `enforce_single_instance: true` also prevents a second
282
- service process from splitting the in-memory queues and pools.
283
-
284
- Use a pinned standalone binary for a service rather than fetching through
285
- `bunx` on every start. The examples below assume the release installers'
286
- defaults:
287
-
288
- - binary: `~/.local/bin/kiro-provider` on Linux,
289
- `%USERPROFILE%\.local\bin\kiro-provider.exe` on Windows;
290
- - config: `~/.config/kiro-provider/config.json` on Linux,
291
- `%APPDATA%\kiro-provider\config.json` on Windows;
292
- - service/task name: `kiro-provider`.
293
-
294
- Run the one-time import and the service as the **same OS user** so the service
295
- owns the same `~/.config/kiro-provider/accounts.db`, config, keyring, and
296
- instance lock. Running as `root`, `LocalSystem`, or another user normally
297
- selects a different local store. Use absolute paths and keep the API key in
298
- the protected config file rather than service arguments. The OpenCode
299
- database is not read again after the import.
300
-
301
- ### Linux: systemd user service
302
-
303
- Verify the installed binary and config first:
304
-
305
- ```bash
306
- test -x "$HOME/.local/bin/kiro-provider"
307
- test -r "$HOME/.config/kiro-provider/config.json"
308
- chmod 600 "$HOME/.config/kiro-provider/config.json"
309
- ```
310
-
311
- Install a [systemd user service](https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html):
312
-
313
- ```bash
314
- SERVICE_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user"
315
- install -d -m 700 "$SERVICE_DIR"
316
- cat > "$SERVICE_DIR/kiro-provider.service" <<'EOF'
317
- [Unit]
318
- Description=kiro-provider local Kiro gateway
319
-
320
- [Service]
321
- Type=exec
322
- ExecStart=%h/.local/bin/kiro-provider serve --config %h/.config/kiro-provider/config.json
323
- Restart=on-failure
324
- RestartSec=5s
325
- TimeoutStopSec=30s
326
- UMask=0077
327
-
328
- [Install]
329
- WantedBy=default.target
330
- EOF
331
- chmod 600 "$SERVICE_DIR/kiro-provider.service"
332
-
333
- systemctl --user daemon-reload
334
- systemctl --user enable --now kiro-provider.service
335
- ```
336
-
337
- If the binary or config is elsewhere, replace `ExecStart` with those absolute
338
- paths. For a custom `XDG_CONFIG_HOME`, also add an explicit
339
- `Environment=XDG_CONFIG_HOME=/absolute/path` line.
340
-
341
- Operate and inspect the service:
342
-
343
- ```bash
344
- systemctl --user is-active kiro-provider.service
345
- systemctl --user restart kiro-provider.service
346
- journalctl --user -u kiro-provider.service -n 100 --no-pager
347
- ```
348
-
349
- User services normally start with that user's service manager. If the
350
- provider must start at boot and remain after logout, an administrator may
351
- enable lingering with `loginctl enable-linger <user>` after reviewing the
352
- machine's security policy.
353
-
354
- To remove the unit:
355
-
356
- ```bash
357
- systemctl --user disable --now kiro-provider.service
358
- rm "${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/kiro-provider.service"
359
- systemctl --user daemon-reload
360
- ```
361
-
362
- ### Windows: per-user scheduled task
363
-
364
- `kiro-provider.exe` is a normal foreground executable, not a native Windows
365
- Service Control Manager executable. Do not register it directly with
366
- `sc.exe`. The built-in, dependency-free option is a
367
- [Scheduled Task](https://learn.microsoft.com/powershell/module/scheduledtasks/register-scheduledtask)
368
- that starts at sign-in, runs as the current user, and restarts after failure.
369
-
370
- Run the following in PowerShell as the same user that owns the provider's
371
- local authentication database and config. It creates a small launcher so
372
- stdout/stderr are retained under `%LOCALAPPDATA%\kiro-provider`:
373
-
374
- ```powershell
375
- $Binary = Join-Path $HOME ".local\bin\kiro-provider.exe"
376
- $Config = Join-Path $env:APPDATA "kiro-provider\config.json"
377
- $ServiceDir = Join-Path $env:APPDATA "kiro-provider"
378
- $LogDir = Join-Path $env:LOCALAPPDATA "kiro-provider"
379
- $Launcher = Join-Path $ServiceDir "service.ps1"
380
-
381
- if (-not (Test-Path -LiteralPath $Binary -PathType Leaf)) {
382
- throw "kiro-provider binary not found: $Binary"
383
- }
384
- if (-not (Test-Path -LiteralPath $Config -PathType Leaf)) {
385
- throw "kiro-provider config not found: $Config"
386
- }
387
-
388
- New-Item -ItemType Directory -Force -Path $ServiceDir, $LogDir | Out-Null
389
- @'
390
- $ErrorActionPreference = "Stop"
391
- $Binary = Join-Path $HOME ".local\bin\kiro-provider.exe"
392
- $Config = Join-Path $env:APPDATA "kiro-provider\config.json"
393
- $LogDir = Join-Path $env:LOCALAPPDATA "kiro-provider"
394
- $Log = Join-Path $LogDir "service.log"
395
- $PreviousLog = Join-Path $LogDir "service.previous.log"
396
-
397
- New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
398
- if ((Test-Path -LiteralPath $Log) -and ((Get-Item -LiteralPath $Log).Length -gt 10MB)) {
399
- Move-Item -Force -LiteralPath $Log -Destination $PreviousLog
400
- }
401
-
402
- & $Binary serve --config $Config *>> $Log
403
- exit $LASTEXITCODE
404
- '@ | Set-Content -LiteralPath $Launcher -Encoding UTF8
405
-
406
- $User = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
407
- $PowerShell = (Get-Command powershell.exe).Source
408
- $Action = New-ScheduledTaskAction `
409
- -Execute $PowerShell `
410
- -Argument ('-NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "{0}"' -f $Launcher)
411
- $Trigger = New-ScheduledTaskTrigger -AtLogOn -User $User
412
- $Principal = New-ScheduledTaskPrincipal `
413
- -UserId $User `
414
- -LogonType Interactive `
415
- -RunLevel Limited
416
- $Settings = New-ScheduledTaskSettingsSet `
417
- -RestartCount 999 `
418
- -RestartInterval (New-TimeSpan -Minutes 1) `
419
- -ExecutionTimeLimit ([TimeSpan]::Zero) `
420
- -MultipleInstances IgnoreNew `
421
- -AllowStartIfOnBatteries `
422
- -DontStopIfGoingOnBatteries `
423
- -StartWhenAvailable
424
-
425
- Stop-ScheduledTask -TaskName "kiro-provider" -ErrorAction SilentlyContinue
426
- Register-ScheduledTask `
427
- -TaskName "kiro-provider" `
428
- -Action $Action `
429
- -Trigger $Trigger `
430
- -Principal $Principal `
431
- -Settings $Settings `
432
- -Description "Local AWS Kiro gateway for AI agents" `
433
- -Force | Out-Null
434
- Start-ScheduledTask -TaskName "kiro-provider"
435
- ```
436
-
437
- Inspect, restart, and follow logs:
438
-
439
- ```powershell
440
- Get-ScheduledTask -TaskName "kiro-provider" | Get-ScheduledTaskInfo
441
- Stop-ScheduledTask -TaskName "kiro-provider"
442
- Start-ScheduledTask -TaskName "kiro-provider"
443
- Get-Content "$env:LOCALAPPDATA\kiro-provider\service.log" -Tail 100 -Wait
444
- ```
445
-
446
- To remove the task and launcher:
261
+ For an agent host, run one long-lived provider per OS user. Use a pinned
262
+ standalone binary, run authentication and the service as the same user, and
263
+ require both unauthenticated `/health` and authenticated `/ready` before
264
+ connecting clients. The default single-instance lock prevents a second process
265
+ from splitting account queues and session state.
447
266
 
448
- ```powershell
449
- Stop-ScheduledTask -TaskName "kiro-provider" -ErrorAction SilentlyContinue
450
- Unregister-ScheduledTask -TaskName "kiro-provider" -Confirm:$false
451
- Remove-Item "$env:APPDATA\kiro-provider\service.ps1"
452
- ```
453
-
454
- This task intentionally runs only in the current user's interactive session,
455
- so it can use that user's network access, provider database, and keyring
456
- without storing a Windows password. A true pre-login Windows service requires
457
- a service wrapper and a deliberately configured user account; do not run it
458
- as `LocalSystem` and expect the same provider-owned files.
459
-
460
- ### Health checks and automation contract
461
-
462
- After either installation, verify both process liveness and authenticated
463
- readiness:
464
-
465
- ```bash
466
- curl -fsS http://127.0.0.1:8787/health
467
- curl -fsS http://127.0.0.1:8787/ready \
468
- -H 'Authorization: Bearer sk-your-private-key'
469
- ```
470
-
471
- PowerShell equivalent:
472
-
473
- ```powershell
474
- Invoke-RestMethod "http://127.0.0.1:8787/health"
475
- $Headers = @{ Authorization = "Bearer sk-your-private-key" }
476
- Invoke-RestMethod "http://127.0.0.1:8787/ready" -Headers $Headers
477
- ```
478
-
479
- For an AI agent or installer, treat setup as successful only when:
480
-
481
- 1. the binary and explicit config path exist;
482
- 2. the service/task runs as the credential-owning user;
483
- 3. `/health` succeeds;
484
- 4. authenticated `/ready` succeeds, proving a readable auth source, at least
485
- one active account, writable provider state, an available reasoning keyring,
486
- and coverage for every key ID referenced by an unexpired replay record.
487
-
488
- Use the fixed service/task name above so repeated setup is idempotent. Restart
489
- it after changing the config or replacing the binary. Do not make the client
490
- responsible for starting a private provider process; configure clients only
491
- with the stable base URL and gateway API key.
267
+ The [background-service guide](docs/SERVICE.md) contains complete systemd user
268
+ service and Windows Scheduled Task examples, log locations, lifecycle commands,
269
+ health gates, and removal steps.
492
270
 
493
271
  ## Configuration
494
272
 
495
- Config is loaded from `~/.config/kiro-provider/config.json` (or `$XDG_CONFIG_HOME/kiro-provider/config.json`; on Windows `%APPDATA%\kiro-provider\config.json`, with the legacy `~/.config` location still read as a fallback), overridable by `KIRO_PROVIDER_*` environment variables and, for `serve`, by CLI flags. Unknown keys in the file are rejected with a suggestion, numeric fields are range-checked, and an empty environment variable counts as unset. Precedence is **CLI flag > environment variable > config file > schema default**.
496
-
497
- | Field | Default | Env var |
498
- | ---------------------------------- | ---------------------------------------- | ------------------------------------------------ |
499
- | `host` | `127.0.0.1` | `KIRO_PROVIDER_HOST` |
500
- | `port` | `8787` | `KIRO_PROVIDER_PORT` |
501
- | `api_keys` | required, non-empty | `KIRO_PROVIDER_API_KEYS` |
502
- | `enable_legacy_chat_completions` | `false` | `KIRO_PROVIDER_ENABLE_LEGACY_CHAT_COMPLETIONS` |
503
- | `protocol_projection_mode` | `v3-auto` | `KIRO_PROVIDER_PROTOCOL_PROJECTION_MODE` |
504
- | `session_affinity_mode` | `explicit-only` | `KIRO_PROVIDER_SESSION_AFFINITY_MODE` |
505
- | `auth_source` | `local` | `KIRO_PROVIDER_AUTH_SOURCE` |
506
- | `opencode_auth_db_path` | `null` (deprecated since 0.7.0, ignored) | `KIRO_PROVIDER_OPENCODE_AUTH_DB_PATH` |
507
- | `proxy_url` | `null` | `KIRO_PROVIDER_PROXY_URL` |
508
- | `default_region` | `us-east-1` | `KIRO_PROVIDER_DEFAULT_REGION` |
509
- | `sdk_http_keep_alive` | `false` | `KIRO_PROVIDER_SDK_HTTP_KEEP_ALIVE` |
510
- | `enforce_single_instance` | `true` | `KIRO_PROVIDER_ENFORCE_SINGLE_INSTANCE` |
511
- | `instance_lock_path` | platform config directory | `KIRO_PROVIDER_INSTANCE_LOCK_PATH` |
512
- | `runtime_endpoint_mode` | `kiro-runtime` | `KIRO_PROVIDER_RUNTIME_ENDPOINT_MODE` |
513
- | `dynamic_model_catalog` | `true` | `KIRO_PROVIDER_DYNAMIC_MODEL_CATALOG` |
514
- | `model_catalog_ttl_ms` | `900000` | `KIRO_PROVIDER_MODEL_CATALOG_TTL_MS` |
515
- | `model_catalog_stale_ttl_ms` | `86400000` | `KIRO_PROVIDER_MODEL_CATALOG_STALE_TTL_MS` |
516
- | `model_catalog_request_timeout_ms` | `10000` | `KIRO_PROVIDER_MODEL_CATALOG_REQUEST_TIMEOUT_MS` |
517
- | `account_selection_strategy` | `lowest-usage` | `KIRO_PROVIDER_ACCOUNT_SELECTION_STRATEGY` |
518
- | `quota_recheck_interval_ms` | `900000` | `KIRO_PROVIDER_QUOTA_RECHECK_INTERVAL_MS` |
519
- | `quota_recheck_timeout_ms` | `10000` | `KIRO_PROVIDER_QUOTA_RECHECK_TIMEOUT_MS` |
520
- | `quota_recheck_concurrency` | `4` | `KIRO_PROVIDER_QUOTA_RECHECK_CONCURRENCY` |
521
- | `account_maintenance_enabled` | `true` | `KIRO_PROVIDER_ACCOUNT_MAINTENANCE_ENABLED` |
522
- | `account_maintenance_interval_ms` | `60000` | `KIRO_PROVIDER_ACCOUNT_MAINTENANCE_INTERVAL_MS` |
523
- | `account_maintenance_timeout_ms` | `120000` | `KIRO_PROVIDER_ACCOUNT_MAINTENANCE_TIMEOUT_MS` |
524
- | `account_maintenance_concurrency` | `4` | `KIRO_PROVIDER_ACCOUNT_MAINTENANCE_CONCURRENCY` |
525
- | `usage_refresh_interval_ms` | `900000` | `KIRO_PROVIDER_USAGE_REFRESH_INTERVAL_MS` |
526
- | `session_affinity_ttl_ms` | `86400000` | `KIRO_PROVIDER_SESSION_AFFINITY_TTL_MS` |
527
- | `session_affinity_max_entries` | `10000` | `KIRO_PROVIDER_SESSION_AFFINITY_MAX_ENTRIES` |
528
- | `reasoning_replay_key_path` | auto-generated config path | `KIRO_PROVIDER_REASONING_REPLAY_KEY_PATH` |
529
- | `reasoning_replay_keys` | `[]` | `KIRO_PROVIDER_REASONING_REPLAY_KEYS` |
530
- | `reasoning_replay_ttl_ms` | `86400000` | `KIRO_PROVIDER_REASONING_REPLAY_TTL_MS` |
531
- | `reasoning_replay_max_entries` | `10000` | `KIRO_PROVIDER_REASONING_REPLAY_MAX_ENTRIES` |
532
- | `log_level` | `info` | `KIRO_PROVIDER_LOG_LEVEL` |
533
-
534
- The full field reference, including retry/timeout tuning and the test-only `test_upstream_endpoint`, lives in [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md).
535
-
536
- ## Proxy
537
-
538
- Some networks reach one model family directly while another needs a proxy (for example, GPT direct, Claude via an approved egress). Set `proxy_url` (config file, `KIRO_PROVIDER_PROXY_URL`, or `serve --proxy`) to route **all** upstream traffic — model calls, token refresh, quota probes, and device-code login — through a single HTTP(S) proxy. Leave it `null` for direct connections. See [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md#proxy) for precedence details and examples.
273
+ Configuration is loaded from the platform config directory, then overlaid by
274
+ `KIRO_PROVIDER_*` environment variables and supported `serve` flags. Precedence
275
+ is **CLI flag > environment variable > JSON file > schema default**. Unknown
276
+ keys and invalid ranges fail at startup; an empty environment value is treated
277
+ as unset.
278
+
279
+ The checked-in [`config.example.json`](config.example.json) is an annotated
280
+ starting point. The [configuration reference](docs/CONFIGURATION.md) is the
281
+ source of truth for every field, default, environment variable, timeout, proxy,
282
+ file location, and protocol switch. Do not copy provider-only fields such as
283
+ `responses_fidelity_mode` into a downstream client's request options.
539
284
 
540
285
  ## Security
541
286
 
542
287
  - **Fail-closed authentication.** The server will not start without at least one non-empty `api_keys` entry. OpenAI routes require `Authorization: Bearer <key>`; Anthropic routes also accept `x-api-key: <key>`.
543
288
  - **Local bind by default.** `host` defaults to `127.0.0.1`; only bind `0.0.0.0` behind a firewall or authenticated reverse proxy.
544
- - **Single authentication authority.** The default local mode makes kiro-provider the sole owner after one-time import. Do not keep two independent processes rotating the same imported refresh token. The explicit shared compatibility mode validates OpenCode's schema and never migrates it.
289
+ - **Single authentication authority.** The provider-owned local store is the sole authority after login or one-time import. Do not keep two independent processes rotating the same imported refresh token; the former live `opencode-shared` mode is no longer supported.
545
290
  - **Single service owner by default.** The compiled service acquires a platform-config lock before listening, so process-local account/session queues and SDK pools cannot be split accidentally.
546
291
  - **Locked-down provider state.** `accounts.db` (and its WAL/SHM files) are created with mode `0600`; in default local mode it contains credentials, usage, health, session affinity, and encrypted replay state.
547
292
  - **Authenticated reasoning replay.** The database stores token/fingerprint hashes and AES-256-GCM ciphertext, not raw `kr1_...` tokens. Missing active decryption keys fail startup.
@@ -549,184 +294,24 @@ Some networks reach one model family directly while another needs a proxy (for e
549
294
 
550
295
  > **Responsible use.** kiro-provider reuses AWS Kiro accounts you already control and consumes your own account quota. Supply your own accounts — this project is not a way to share or resell someone else's Kiro access, and it should not be used to circumvent per-account usage limits.
551
296
 
552
- ## Using with an LLM
553
-
554
- Use `POST /v1/responses` for OpenAI Responses clients. Use
555
- `POST /v1/messages` for Anthropic Messages clients. Only point a
556
- Chat-Completions-only client (`@ai-sdk/openai-compatible`, older LangChain
557
- adapters, or an OpenCode custom provider using that package) at
558
- `POST /v1/chat/completions` after explicitly enabling the legacy endpoint.
559
-
560
- The default `v3-auto` mode accepts standard instructions through KiroRuntime's
561
- native Responses field. Requests that need custom grammar, namespace tools,
562
- Codex collaboration items, encrypted reasoning replay, max effort, or
563
- `store:false` automatically use the stateless compatibility lane. Unsupported
564
- hosted capabilities fail with a field-level OpenAI error instead of being
565
- silently ignored.
566
-
567
- The default `session_affinity_mode: "explicit-only"` never hashes prompt text
568
- to guess a conversation. Responses checks, in order,
569
- `metadata.zuno_session_id`, `metadata.kiro_provider_session_id`, compatibility
570
- `client_metadata.thread_id|session_id|conversation_id`, and
571
- `prompt_cache_key`. Chat checks only `prompt_cache_key`; Anthropic Messages
572
- has no verified explicit affinity field. With no key, the request gets a
573
- fresh Kiro conversation on its first turn; a later full-history request can
574
- reuse the same account/conversation by matching the exact prior assistant
575
- output lineage. It can also reuse account-scoped SDK clients and transport
576
- objects. The Kiro SDK's direct/proxy agents use fresh sockets by default; set
577
- `sdk_http_keep_alive: true` only when the deployment has validated pooled
578
- socket behavior.
579
- The temporary `legacy-initial-input` mode restores only the old affinity
580
- heuristics and logs a startup warning; it does not alter request content.
581
-
582
- `previous_response_id` is supported for tenant-local mirrored responses.
583
- `conversation` objects remain unsupported. Retrieve, delete, input-items, and
584
- cancel use the local mirror; deleting it does not prove deletion of Kiro's
585
- upstream state.
586
-
587
- <details>
588
- <summary>Agent command reference</summary>
589
-
590
- - `kiro-provider serve [--config <path>] [--host <host>] [--port <port>] [--proxy <url>]` — start the gateway.
591
- - `kiro-provider login [--config <path>] [--start-url <url>] [--region <region>]` — authenticate directly into the provider-owned local store.
592
- - `kiro-provider accounts list [--details | --json]` — show aligned account health/usage; details and JSON include the stable account ID but never credentials.
593
- - `kiro-provider accounts refresh (--all | <id|email>) [--config <path>] [--json]` — bypass the usage cache, refresh authoritative Kiro usage, and renew an access token only when needed or rejected upstream.
594
- - `kiro-provider accounts relogin <id|email> [--config <path>] [--start-url <url>] [--region <region>]` — re-authenticate a selected account after Kiro identity verification while preserving its internal ID and session-affinity references.
595
- - `kiro-provider accounts import [--from <path>] [--force]` — copy authenticated OpenCode Kiro accounts once into the provider-owned local store; rows whose local copy is newer are skipped unless `--force` is given; no live database link remains.
596
- - `kiro-provider accounts remove <id|email> [--yes]` — remove one account and its affinity/lineage/reasoning state; interactive confirmation is required unless `--yes` is supplied.
597
-
598
- Contract: human-readable status lines go to stdout, errors to stderr, non-zero exit on failure. `GET /v1/models`, `GET /health`, and authenticated `GET /ready` return structured JSON.
599
-
600
- </details>
601
-
602
- ## Use with Zuno
603
-
604
- Run one compiled kiro-provider service as the credential-owning OS user, then
605
- configure Zuno's native Rust OpenAI transport. No Node package, AI SDK, private
606
- header, or provider-spawn hook is required:
607
-
608
- ```json
609
- {
610
- "model": "kiro/auto",
611
- "small_model": "kiro/auto",
612
- "provider": {
613
- "kiro": {
614
- "name": "Local kiro-provider",
615
- "transport": "openai",
616
- "surface": "responses",
617
- "env": ["KIRO_GATEWAY_API_KEY"],
618
- "options": {
619
- "baseURL": "http://127.0.0.1:8787/v1",
620
- "maxTokens": null
621
- },
622
- "models": {
623
- "auto": {
624
- "name": "Kiro Auto",
625
- "reasoning": true,
626
- "tool_call": true
627
- }
628
- }
629
- }
630
- }
631
- }
632
- ```
633
-
634
- Set `KIRO_GATEWAY_API_KEY` to one key from the provider's `api_keys`, then
635
- verify the native route:
636
-
637
- ```bash
638
- export KIRO_GATEWAY_API_KEY='sk-your-private-key'
639
- zuno debug config
640
- zuno models kiro --verbose
641
- ```
642
-
643
- The matching Zuno OpenAI Responses transport maps the durable Zuno session ID
644
- to standard `metadata.zuno_session_id` on every main turn and tool
645
- continuation. It does not add that ID to input, messages, instructions, tool
646
- descriptions, or any other model-visible field; internal title/summary calls
647
- do not join the main provider conversation. Therefore one Zuno session is
648
- serialized onto one persisted account/Kiro-conversation binding, while
649
- different sessions remain isolated even if their first prompt and upstream
650
- tool aliases are identical. Current declarations authorize new calls only.
651
- Private historical alias bindings can accompany stored Responses continuations;
652
- they never re-enable retired tools. See [historical tool scope](docs/HISTORICAL_TOOLS.md).
653
-
654
- Keep `surface: "responses"` for this integration. Selecting `chat` requires
655
- the separately enabled legacy endpoint and does not carry the Zuno Responses
656
- session metadata.
657
-
658
- Current Zuno sends agent instructions. Valid required-label
659
- `additionalContext` requests reached Kiro in live GPT and Claude probes, but
660
- the models did not receive the instruction content or preserve its priority.
661
- Consequently the verified functional path currently requires the provider's
662
- explicit `protocol_projection_mode: "legacy-user-prefix"`; `safe` correctly
663
- returns `unsupported_instruction_projection` and never rewrites the request.
664
- Set Zuno `options.maxTokens` to `null` as shown so its generic layer does not
665
- add the unsupported `max_output_tokens: 32000`. Neither setting uses a private
666
- Header or client-side prompt patch; the legacy mode is an explicit migration
667
- exception whose removal is gated on native instruction fidelity or completed
668
- client migration.
669
-
670
- ## Use with Codex CLI
671
-
672
- Codex uses the correct Responses endpoint. The last compiled protocol gate
673
- with Codex
674
- 0.150.0-alpha.9 and `claude-opus-5-max` now passes provider model validation,
675
- but its first request is rejected before Kiro at `reasoning.summary`, which
676
- has no proven native equivalent. The provider does not strip that field or
677
- simulate it with prompt text. The following isolated configuration reproduces
678
- the compatibility check without touching the real `~/.codex` state:
679
-
680
- ```bash
681
- export CODEX_TEST_ROOT="$(mktemp -d)"
682
- export CODEX_HOME="$CODEX_TEST_ROOT/home"
683
- export CODEX_SQLITE_HOME="$CODEX_TEST_ROOT/sqlite"
684
- mkdir -p "$CODEX_HOME" "$CODEX_SQLITE_HOME"
685
- export LOCALGW_KEY="sk-...your gateway api key..."
686
- cat > "$CODEX_HOME/config.toml" <<'EOF'
687
- model = "claude-opus-5-max"
688
- model_provider = "localgw"
689
- model_reasoning_effort = "high"
690
- [model_providers.localgw]
691
- name = "Local Gateway"
692
- base_url = "http://127.0.0.1:8787/v1"
693
- env_key = "LOCALGW_KEY"
694
- wire_api = "responses"
695
- EOF
696
- codex exec --skip-git-repo-check "say hi"
697
- ```
698
-
699
- For Codex 0.150.0-alpha.9 the expected result is a non-zero exit with
700
- `unsupported_reasoning_summary` at `reasoning.summary`. A future supported request shape must
701
- then pass a real shell/custom-tool loop, continuation, and restart reasoning
702
- replay before Codex is marked supported. Full details live in
703
- [`docs/CODEX.md`](docs/CODEX.md).
297
+ ## Client integrations
704
298
 
705
- ## Use with Claude Code
299
+ Use `POST /v1/responses` for OpenAI Responses clients and `POST /v1/messages`
300
+ for Anthropic Messages clients. Enable `POST /v1/chat/completions` only for a
301
+ client that cannot use either primary surface.
706
302
 
707
- Claude Code 2.1.263 is supported through the existing Anthropic Messages
708
- surface. For an isolated Linux profile that cannot affect a normal
709
- Bedrock-backed `claude` command, run the checkout-local launcher:
710
-
711
- ```bash
712
- PATH="$PWD/scripts:$PATH" kiroclaude
713
- ```
303
+ | Client | Endpoint | Guide |
304
+ | --- | --- | --- |
305
+ | Zuno | OpenAI Responses | [Configuration, session routing, and isolated validation](docs/ZUNO.md) |
306
+ | Codex CLI | OpenAI Responses | [Isolated profile and supported request boundary](docs/CODEX.md) |
307
+ | Claude Code | Anthropic Messages | [Isolated `kiroclaude` profile and compatibility boundary](docs/CLAUDE_CODE.md) |
308
+ | Other SDKs | Responses, Messages, or explicitly enabled legacy Chat | [V3 protocol compatibility](docs/PROTOCOL_COMPATIBILITY.md) |
714
309
 
715
- It uses a separate `CLAUDE_CONFIG_DIR`, `apiKeyHelper`, the gateway root
716
- `http://127.0.0.1:8787` (without `/v1`), and Kiro's Opus/Sonnet/Haiku plus
717
- GPT-5.6 Sol/Terra/Luna model IDs. GPT rows inherit Claude Code's effort picker
718
- behavior through a version-scoped `modelPicker` mapping. The default is Opus 5
719
- in Ultra mode, and away/recap summaries are disabled only in this profile.
720
- Ellipsis-only GPT reasoning is hidden behind a lossless replay token. A separate
721
- `kiroclaude --bedrock-fable` profile provides the existing native Bedrock Fable
722
- 5.1 model without mixing providers in one conversation. Because Kiro exposes
723
- no native GPT output-token field, only the launcher explicitly opts into an
724
- audited advisory `max_tokens` mode; every other client remains fail-closed.
725
- Current text, tool/result, mid-system, adaptive/omitted thinking, safe
726
- context-management, cache-hint, and SSE ping behavior is covered. The scripts
727
- are not installed by the release installer in this revision. See
728
- [`docs/CLAUDE_CODE.md`](docs/CLAUDE_CODE.md) for configuration, compatibility
729
- boundaries, and isolated validation.
310
+ The default `session_affinity_mode: "explicit-only"` never fingerprints prompt
311
+ text. Clients should send a stable standard affinity field, or resend complete
312
+ history / use `previous_response_id` as their API supports. Native and stateless
313
+ transport selection remains a gateway concern; clients should not force an
314
+ internal lane.
730
315
 
731
316
  ## Troubleshooting
732
317
 
@@ -742,10 +327,17 @@ stopped", reasoning-replay `400`s, the single-instance lock, configuration
742
327
  warnings, `413` variants, and proxy failures. It also lists `journalctl` grep
743
328
  recipes for the systemd service and the opt-in `request_shape` debug event.
744
329
 
330
+ ## Documentation
331
+
332
+ [`docs/README.md`](docs/README.md) is the complete documentation map. It
333
+ separates current operator/protocol guides from dated audit evidence and links
334
+ the English and Simplified Chinese variants. Release history lives under
335
+ [`changelog/`](changelog/README.md).
336
+
745
337
  ## Development
746
338
 
747
339
  ```bash
748
- bun install
340
+ bun install --frozen-lockfile
749
341
  bun run lint
750
342
  bun run typecheck
751
343
  bun test
@@ -754,10 +346,11 @@ bun run build:binary
754
346
  bash scripts/security-check.sh # security regression suite (Linux, needs openssl/curl/ss)
755
347
  ```
756
348
 
757
- `make ci` runs typecheck, lint, shell-script syntax checks, and the test suite.
758
- `make fmt-check` (and `make fmt`) additionally require the `oxfmt` formatter
759
- for YAML/JSON/Markdown; install the version CI uses with
760
- `bun install --global oxfmt@0.59.0`. `bun run scripts/smoke.ts --help` describes
349
+ `make ci` runs the repository's fast correctness gate: formatting, typecheck,
350
+ lint, shell-script syntax, tests, build, security self-tests, and coverage-config
351
+ parity. `make pre-ci` adds the full coverage run and enforced coverage floor.
352
+ `make fmt-check` uses the repository-pinned `oxfmt` version; install dependencies
353
+ first with `bun install --frozen-lockfile`. `bun run scripts/smoke.ts --help` describes
761
354
  the live end-to-end checks against a running gateway.
762
355
 
763
356
  ## License