ns-kiro-core 0.3.8 → 0.4.0

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.
package/README.md CHANGED
@@ -2,12 +2,13 @@
2
2
 
3
3
  The Kiro (AWS CodeWhisperer/Q) protocol, with no host types in it.
4
4
 
5
- This package is the shared half of
6
- [ns-kiro-provider](https://github.com/ngosangns/ns-kiro-provider): everything a
7
- Kiro client needs that is not specific to one coding agent.
5
+ This package is the Kiro vendor core of
6
+ [ns-bridge](https://github.com/ngosangns/ns-bridge): everything a Kiro client
7
+ needs that is not specific to one coding agent.
8
8
 
9
- Published on npm as `ns-kiro-core`. Pulled in as a dependency by the two
10
- adapters below — not meant to be installed on its own.
9
+ Published on npm as `ns-kiro-core`. Pulled in as a dependency by the Kiro host
10
+ adapters — `@ngosangns/ns-pi-provider`, `ns-omp-provider-kiro`,
11
+ `ns-dsh-llm-kiro` — not meant to be installed on its own.
11
12
 
12
13
  - **Endpoints** — SSO region to management/runtime host resolution.
13
14
  - **Model catalog** — the bootstrap list, the authenticated regional catalog,
@@ -29,6 +30,21 @@ adapters below — not meant to be installed on its own.
29
30
  retry ladder (transport timeouts, capacity pressure, request-rate windows, 403
30
31
  credential rotation, degenerate 200s).
31
32
 
33
+ ## Engine
34
+
35
+ Since 0.4.0 the public entry points (`streamKiro`, `updateKiroModelsCache`, `fetchKiroUsage`, `refreshKiroToken`) run in the
36
+ [`ns-bridge`](https://github.com/ngosangns/ns-bridge/tree/main/go) Go sidecar
37
+ when a binary is installed ([`ns-bridge-bin`](https://www.npmjs.com/package/ns-bridge-bin),
38
+ `NS_BRIDGE_BIN`, or `ns-bridge` on `PATH`), and in this package's TypeScript
39
+ otherwise. `NS_BRIDGE_ENGINE=ts` (or `NS_BRIDGE_ENGINE_KIRO=ts`) keeps
40
+ everything in-process; `…InProcess` exports always do. Per-process state
41
+ (profile-ARN and region caches, the cache-read estimate, catalog refresh scheduling) stays in TypeScript and is carried across each call.
42
+
43
+ The TypeScript implementation is now the fallback. A later major release is
44
+ expected to slim this package to the facade, types and credential stores, with
45
+ the protocol living in the binary only; nothing changes for callers of the
46
+ exports above.
47
+
32
48
  ## The neutral seam
33
49
 
34
50
  `streamKiro` takes a request built from this package's own vocabulary and yields
@@ -51,7 +67,10 @@ for await (const event of streamKiro({
51
67
  ```
52
68
 
53
69
  An adapter owes two translations — host messages in, host stream events out —
54
- and nothing else. Block indexes are monotonic across the whole response,
70
+ and nothing else; for Pi-family hosts and the Harness, `ns-bridge-core` already
71
+ does both. `loginKiroFromSession` / `resolveKiroRequestCredentials` (session
72
+ login and per-request credentials) and `toKiroModelForHost` (catalog entry to a
73
+ host model) are the other pieces every host needs, so they live here too. Block indexes are monotonic across the whole response,
55
74
  including across an internal retry, so a host that cannot un-deliver a block
56
75
  still receives a coherent sequence; `canDiscardEmittedBlocks` tells the core
57
76
  which kind of host it is talking to.
@@ -69,6 +88,48 @@ sourced elsewhere:
69
88
  | `KiroResponseAssembler` | Content blocks, thinking, tool calls, text-dialect recovery, usage, stop reason |
70
89
  | `abortableDelay`, `createResponseHeaderDeadline`, `logCapacityEvent` | Transport timing |
71
90
 
91
+ ## What Kiro reports, and what it does not
92
+
93
+ Measured 2026-09-06 against `claude-sonnet-5` in `us-east-1`. Recorded here so
94
+ the questions are not re-opened from first principles.
95
+
96
+ **Token counts: none.** Kiro's `usage` frame is a billing record —
97
+ `{unit: "credit", usage: 0.0659}` — not token counts. `usage.input` is therefore
98
+ derived from the `contextUsagePercentage` frame, and `usage.output` from a
99
+ tiktoken estimate over what the model emitted. `usage.credits` carries the
100
+ figure Kiro actually bills.
101
+
102
+ **Per-token prices: none.** Kiro bills in credits and publishes no per-token
103
+ rates, so every model's `cost` stays zero. `kiro-cli chat --list-models` does
104
+ publish a relative billing weight, which the catalog picks up as
105
+ `rateMultiplier` — 2.2 for `claude-opus-5` against 0.05 for `qwen3-coder-next`.
106
+ It is absent when kiro-cli is not installed.
107
+
108
+ **Prompt caching: real, but not controllable.** Kiro caches prompts server-side
109
+ on its own: a repeated prefix billed ~0.035 credits against ~0.066 for a fresh
110
+ one, and a changed prefix went straight back to the full price. There is no way
111
+ to ask for it — every model's `additionalModelRequestFieldsSchema` sets
112
+ `"additionalProperties": false` and allows only `thinking`/`output_config`/
113
+ `max_tokens` (Claude) or `reasoning` (GPT), so a `cachePoint` or `cache_control`
114
+ field is rejected rather than honoured. Kiro also reports no cache token counts.
115
+
116
+ Reasoning effort is part of the cache key: changing it misses even when the
117
+ prompt is byte-identical, and each effort level then warms its own entry.
118
+
119
+ **Stop reasons: reported when Kiro sends one, inferred otherwise.** Kiro now
120
+ closes a turn with a `metadataEvent` `stopReason` (`END_TURN` on every ordinary
121
+ turn checked, 2026-10-08). `MAX_TOKENS` is reported as `length`;
122
+ `CONTENT_FILTERED`, `MODEL_CONTEXT_WINDOW_EXCEEDED` (phrased
123
+ `context_length_exceeded`) and `PAUSE_TURN` end the call with an error and no
124
+ retry. Without a stop reason, a turn with no tool call that never carried a
125
+ `contextUsagePercentage` frame is reported as `length`. That frame arrived in
126
+ every case checked — a short reply, a ~5000-character one, a tool-call turn, a
127
+ model with no effort schema, and a non-Claude model — so its absence does mark
128
+ an abnormal turn rather than a normal short answer.
129
+
130
+ Set `KIRO_DEBUG=1` to log the frames verbatim (`~/.ns-kiro-provider/logs/`) if
131
+ any of this needs re-checking against a newer Kiro.
132
+
72
133
  ## Credit
73
134
 
74
135
  Ported from [pi-provider-kiro](https://github.com/mikeyobrien/pi-provider-kiro)
@@ -4,6 +4,10 @@ export interface KiroEndpoints {
4
4
  runtime: string;
5
5
  }
6
6
  export declare function resolveApiRegion(ssoRegion: string | undefined): string;
7
+ /** Overrides the runtime base URL; `{region}` is replaced with the region. */
8
+ export declare const KIRO_RUNTIME_ENDPOINT_ENV = "KIRO_RUNTIME_ENDPOINT";
9
+ /** Overrides the management base URL; `{region}` is replaced with the region. */
10
+ export declare const KIRO_MANAGEMENT_ENDPOINT_ENV = "KIRO_MANAGEMENT_ENDPOINT";
7
11
  export declare function getKiroEndpoints(region: string): KiroEndpoints;
8
12
  /**
9
13
  * A Kiro profile is owned by one region and its ARN carries that region. The
package/dist/endpoints.js CHANGED
@@ -23,11 +23,22 @@ export function resolveApiRegion(ssoRegion) {
23
23
  return "us-east-1";
24
24
  return API_REGION_MAP[ssoRegion] ?? ssoRegion;
25
25
  }
26
+ /** Overrides the runtime base URL; `{region}` is replaced with the region. */
27
+ export const KIRO_RUNTIME_ENDPOINT_ENV = "KIRO_RUNTIME_ENDPOINT";
28
+ /** Overrides the management base URL; `{region}` is replaced with the region. */
29
+ export const KIRO_MANAGEMENT_ENDPOINT_ENV = "KIRO_MANAGEMENT_ENDPOINT";
30
+ function endpointOverride(name, region) {
31
+ const value = process.env[name]?.trim();
32
+ if (!value)
33
+ return undefined;
34
+ const url = value.replaceAll("{region}", region);
35
+ return url.endsWith("/") ? url : `${url}/`;
36
+ }
26
37
  export function getKiroEndpoints(region) {
27
38
  return {
28
39
  region,
29
- management: `https://management.${region}.kiro.dev/`,
30
- runtime: `https://runtime.${region}.kiro.dev/`,
40
+ management: endpointOverride(KIRO_MANAGEMENT_ENDPOINT_ENV, region) ?? `https://management.${region}.kiro.dev/`,
41
+ runtime: endpointOverride(KIRO_RUNTIME_ENDPOINT_ENV, region) ?? `https://runtime.${region}.kiro.dev/`,
31
42
  };
32
43
  }
33
44
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,sFAAsF;AAEtF,MAAM,cAAc,GAA2B;IAC7C,WAAW,EAAE,WAAW;IACxB,WAAW,EAAE,WAAW;IACxB,WAAW,EAAE,WAAW;IACxB,WAAW,EAAE,WAAW;IACxB,gBAAgB,EAAE,WAAW;IAC7B,gBAAgB,EAAE,WAAW;IAC7B,gBAAgB,EAAE,WAAW;IAC7B,gBAAgB,EAAE,WAAW;IAC7B,YAAY,EAAE,WAAW;IACzB,WAAW,EAAE,cAAc;IAC3B,WAAW,EAAE,cAAc;IAC3B,WAAW,EAAE,cAAc;IAC3B,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,cAAc,EAAE,cAAc;CAC/B,CAAC;AAQF,MAAM,UAAU,gBAAgB,CAAC,SAA6B;IAC5D,IAAI,CAAC,SAAS;QAAE,OAAO,WAAW,CAAC;IACnC,OAAO,cAAc,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO;QACL,MAAM;QACN,UAAU,EAAE,sBAAsB,MAAM,YAAY;QACpD,OAAO,EAAE,mBAAmB,MAAM,YAAY;KAC/C,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CAAC,UAA8B;IACxE,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAClC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,MAAM,IAAI,2BAA2B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAgB;IACxD,IAAI,CAAC;QACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,SAAS,CAAC,IAAI,MAAM,KAAK,UAAU;YAAE,OAAO,MAAM,CAAC;QAChG,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,sFAAsF;AAEtF,MAAM,cAAc,GAA2B;IAC7C,WAAW,EAAE,WAAW;IACxB,WAAW,EAAE,WAAW;IACxB,WAAW,EAAE,WAAW;IACxB,WAAW,EAAE,WAAW;IACxB,gBAAgB,EAAE,WAAW;IAC7B,gBAAgB,EAAE,WAAW;IAC7B,gBAAgB,EAAE,WAAW;IAC7B,gBAAgB,EAAE,WAAW;IAC7B,YAAY,EAAE,WAAW;IACzB,WAAW,EAAE,cAAc;IAC3B,WAAW,EAAE,cAAc;IAC3B,WAAW,EAAE,cAAc;IAC3B,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,cAAc,EAAE,cAAc;CAC/B,CAAC;AAQF,MAAM,UAAU,gBAAgB,CAAC,SAA6B;IAC5D,IAAI,CAAC,SAAS;QAAE,OAAO,WAAW,CAAC;IACnC,OAAO,cAAc,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;AAChD,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AACjE,iFAAiF;AACjF,MAAM,CAAC,MAAM,4BAA4B,GAAG,0BAA0B,CAAC;AAEvE,SAAS,gBAAgB,CAAC,IAAY,EAAE,MAAc;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACjD,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO;QACL,MAAM;QACN,UAAU,EAAE,gBAAgB,CAAC,4BAA4B,EAAE,MAAM,CAAC,IAAI,sBAAsB,MAAM,YAAY;QAC9G,OAAO,EAAE,gBAAgB,CAAC,yBAAyB,EAAE,MAAM,CAAC,IAAI,mBAAmB,MAAM,YAAY;KACtG,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CAAC,UAA8B;IACxE,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAClC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,MAAM,IAAI,2BAA2B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAgB;IACxD,IAAI,CAAC;QACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,SAAS,CAAC,IAAI,MAAM,KAAK,UAAU;YAAE,OAAO,MAAM,CAAC;QAChG,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type SidecarError } from "ns-bridge-core/sidecar";
2
+ /**
3
+ * The Kiro error a sidecar failure stands for, rebuilt from the class the Go
4
+ * vendor names. Anything else (a missing or crashed binary, a network failure)
5
+ * stays a SidecarError.
6
+ */
7
+ export declare function kiroErrorFromSidecar(error: SidecarError): Error;
8
+ /**
9
+ * Run `op` in the Go sidecar (with this process's profile caches) or
10
+ * in-process, per NS_BRIDGE_ENGINE(_KIRO). The sidecar's cache changes are
11
+ * folded back before the result is returned.
12
+ */
13
+ export declare function runKiroOp<TResult>(op: string, request: () => Record<string, unknown>, inProcess: () => Promise<TResult>): Promise<TResult>;
@@ -0,0 +1,51 @@
1
+ // ABOUTME: Runs Kiro's one-shot operations (catalog refresh, usage, token refresh) on the selected engine,
2
+ // ABOUTME: carrying the profile caches across and mapping sidecar failures back to Kiro's error classes.
3
+ import { engineCall } from "ns-bridge-core/sidecar";
4
+ import { KiroApiError } from "./errors.js";
5
+ import { applyKiroProfileArnCacheChanges, applyKiroProfileRegionChanges, KiroManagementHttpError, snapshotKiroProfileArnCache, snapshotKiroProfileRegionCache, } from "./management.js";
6
+ /**
7
+ * The Kiro error a sidecar failure stands for, rebuilt from the class the Go
8
+ * vendor names. Anything else (a missing or crashed binary, a network failure)
9
+ * stays a SidecarError.
10
+ */
11
+ export function kiroErrorFromSidecar(error) {
12
+ switch (error.vendorError) {
13
+ case "KiroApiError":
14
+ return new KiroApiError(error.message, error.status ?? 0, error.reasonCode, error.retryAfterMs, error.providerAttempts);
15
+ case "KiroManagementHttpError":
16
+ return new KiroManagementHttpError(error.message, error.status ?? 0);
17
+ case "Error":
18
+ return new Error(error.message);
19
+ default:
20
+ return error;
21
+ }
22
+ }
23
+ /**
24
+ * Run `op` in the Go sidecar (with this process's profile caches) or
25
+ * in-process, per NS_BRIDGE_ENGINE(_KIRO). The sidecar's cache changes are
26
+ * folded back before the result is returned.
27
+ */
28
+ export async function runKiroOp(op, request, inProcess) {
29
+ let ranInProcess = false;
30
+ const result = await engineCall({
31
+ vendor: "kiro",
32
+ op,
33
+ request: () => ({
34
+ ...request(),
35
+ profileArnCache: snapshotKiroProfileArnCache(),
36
+ profileRegions: snapshotKiroProfileRegionCache(),
37
+ }),
38
+ inProcess: async () => {
39
+ ranInProcess = true;
40
+ return (await inProcess());
41
+ },
42
+ mapError: kiroErrorFromSidecar,
43
+ });
44
+ if (ranInProcess || !result || typeof result !== "object")
45
+ return result;
46
+ const { kiroProfileArns, kiroProfileRegions, ...rest } = result;
47
+ applyKiroProfileArnCacheChanges(kiroProfileArns);
48
+ applyKiroProfileRegionChanges(kiroProfileRegions);
49
+ return rest;
50
+ }
51
+ //# sourceMappingURL=engine-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine-ops.js","sourceRoot":"","sources":["../src/engine-ops.ts"],"names":[],"mappings":"AAAA,2GAA2G;AAC3G,yGAAyG;AAEzG,OAAO,EAAE,UAAU,EAAqB,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,YAAY,EAA6B,MAAM,aAAa,CAAC;AACtE,OAAO,EACL,+BAA+B,EAC/B,6BAA6B,EAC7B,uBAAuB,EACvB,2BAA2B,EAC3B,8BAA8B,GAC/B,MAAM,iBAAiB,CAAC;AAEzB;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAmB;IACtD,QAAQ,KAAK,CAAC,WAAW,EAAE,CAAC;QAC1B,KAAK,cAAc;YACjB,OAAO,IAAI,YAAY,CACrB,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,MAAM,IAAI,CAAC,EACjB,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,gBAAoD,CAC3D,CAAC;QACJ,KAAK,yBAAyB;YAC5B,OAAO,IAAI,uBAAuB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;QACvE,KAAK,OAAO;YACV,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClC;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAOD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAU,EACV,OAAsC,EACtC,SAAiC;IAEjC,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAkD;QAC/E,MAAM,EAAE,MAAM;QACd,EAAE;QACF,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;YACd,GAAG,OAAO,EAAE;YACZ,eAAe,EAAE,2BAA2B,EAAE;YAC9C,cAAc,EAAE,8BAA8B,EAAE;SACjD,CAAC;QACF,SAAS,EAAE,KAAK,IAAI,EAAE;YACpB,YAAY,GAAG,IAAI,CAAC;YACpB,OAAO,CAAC,MAAM,SAAS,EAAE,CAA2B,CAAC;QACvD,CAAC;QACD,QAAQ,EAAE,oBAAoB;KAC/B,CAAC,CAAC;IACH,IAAI,YAAY,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IACzE,MAAM,EAAE,eAAe,EAAE,kBAAkB,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IAChE,+BAA+B,CAAC,eAAe,CAAC,CAAC;IACjD,6BAA6B,CAAC,kBAAkB,CAAC,CAAC;IAClD,OAAO,IAAe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type BridgeEngine, SidecarError } from "ns-bridge-core/sidecar";
2
+ import { kiroErrorFromSidecar } from "./engine-ops.js";
3
+ import type { KiroStreamRequest } from "./stream.js";
4
+ import type { KiroStreamEvent } from "./types.js";
5
+ /** The sidecar vendor id. */
6
+ export declare const KIRO_SIDECAR_VENDOR = "kiro";
7
+ /** The engine a Kiro turn runs on right now (NS_BRIDGE_ENGINE_KIRO, then NS_BRIDGE_ENGINE). */
8
+ export declare function selectKiroEngine(): BridgeEngine;
9
+ /**
10
+ * The JSON the Go vendor reads (go/internal/vendors/kiro StreamRequest): the
11
+ * request with its model id pre-resolved, plus the state this process holds.
12
+ * Throws whatever {@link resolveKiroModel} throws.
13
+ */
14
+ export declare function toKiroSidecarRequest(request: KiroStreamRequest, conversationId: string): Record<string, unknown>;
15
+ /** Run a turn on the selected engine; `inProcess` is the TypeScript core. */
16
+ export declare function streamKiroOnEngine(request: KiroStreamRequest, inProcess: (request: KiroStreamRequest) => AsyncIterable<KiroStreamEvent>): AsyncIterable<KiroStreamEvent>;
17
+ export { kiroErrorFromSidecar, SidecarError };
package/dist/engine.js ADDED
@@ -0,0 +1,111 @@
1
+ // ABOUTME: Routes a Kiro turn to the ns-bridge Go sidecar or the in-process TypeScript core, carrying the
2
+ // ABOUTME: per-process state (profile ARNs, cache estimates, catalog refresh) a one-turn sidecar cannot hold.
3
+ import { engineStream, SidecarError, selectBridgeEngine } from "ns-bridge-core/sidecar";
4
+ import { applyCacheEstimate } from "./cache-estimator.js";
5
+ import { debugLog, formatSafeError } from "./debug.js";
6
+ import { getKiroRegionFromProfileArn } from "./endpoints.js";
7
+ import { kiroErrorFromSidecar } from "./engine-ops.js";
8
+ import { applyKiroProfileArnCacheChanges, snapshotKiroProfileArnCache } from "./management.js";
9
+ import { isCacheStale, resolveKiroModel, updateKiroModelsCache } from "./models.js";
10
+ import { capacityRetryConfig, firstTokenTimeoutForModel, retryConfig } from "./retry.js";
11
+ import { testProfileArnOverride } from "./stream.js";
12
+ import { KIRO_USAGE_TRACKING_DISABLED } from "./usage-tracking.js";
13
+ /** The sidecar vendor id. */
14
+ export const KIRO_SIDECAR_VENDOR = "kiro";
15
+ /** The engine a Kiro turn runs on right now (NS_BRIDGE_ENGINE_KIRO, then NS_BRIDGE_ENGINE). */
16
+ export function selectKiroEngine() {
17
+ return selectBridgeEngine(KIRO_SIDECAR_VENDOR);
18
+ }
19
+ /**
20
+ * The JSON the Go vendor reads (go/internal/vendors/kiro StreamRequest): the
21
+ * request with its model id pre-resolved, plus the state this process holds.
22
+ * Throws whatever {@link resolveKiroModel} throws.
23
+ */
24
+ export function toKiroSidecarRequest(request, conversationId) {
25
+ const { signal: _signal, ...wire } = request;
26
+ const kiroModelId = resolveKiroModel(request.model.id, request.model.kiroModelId);
27
+ const testProfileArn = testProfileArnOverride();
28
+ return {
29
+ ...wire,
30
+ model: { ...request.model, kiroModelId },
31
+ conversationId,
32
+ profileArnCache: snapshotKiroProfileArnCache(),
33
+ timeouts: {
34
+ firstTokenMs: request.model.firstTokenTimeout ?? firstTokenTimeoutForModel(request.model.id),
35
+ requestHeaderMs: retryConfig.requestHeaderTimeoutMs,
36
+ },
37
+ capacityRetry: { ...capacityRetryConfig },
38
+ ...(testProfileArn ? { testProfileArn } : {}),
39
+ };
40
+ }
41
+ /**
42
+ * Apply to sidecar events what the in-process core does with process state:
43
+ * fold profile ARNs back into the cache, estimate cache reads across turns,
44
+ * and refresh a stale model catalog in the background.
45
+ */
46
+ async function* postProcess(events, request, conversationId) {
47
+ let pendingUsage;
48
+ for await (const event of events) {
49
+ if (event.type === "usage") {
50
+ pendingUsage = event;
51
+ continue;
52
+ }
53
+ if (event.type !== "done") {
54
+ yield event;
55
+ continue;
56
+ }
57
+ const { kiroProfileArns, kiroRuntimeRegion, kiroProfileArn, ...done } = event;
58
+ applyKiroProfileArnCacheChanges(kiroProfileArns);
59
+ const region = kiroRuntimeRegion ?? getKiroRegionFromProfileArn(kiroProfileArn) ?? request.model.region;
60
+ if (!process.env.VITEST && region && kiroProfileArn && isCacheStale(region)) {
61
+ updateKiroModelsCache(request.accessToken, region, kiroProfileArn).catch((error) => {
62
+ console.warn(`[kiro-core] Failed to refresh Kiro model catalog in ${region}: ${formatSafeError(error)}`);
63
+ });
64
+ }
65
+ if (pendingUsage) {
66
+ const { kiroWireCache, ...usageEvent } = pendingUsage;
67
+ if (!done.errorMessage) {
68
+ const estimatedRead = applyCacheEstimate(conversationId, usageEvent.usage, kiroWireCache ? { cacheReadInputTokens: 0 } : null, request.usageTracking ?? KIRO_USAGE_TRACKING_DISABLED);
69
+ if (estimatedRead > 0) {
70
+ debugLog("usage.estimate", {
71
+ conversationId,
72
+ estimatedRead,
73
+ input: usageEvent.usage.input,
74
+ cacheRead: usageEvent.usage.cacheRead,
75
+ });
76
+ }
77
+ }
78
+ pendingUsage = undefined;
79
+ yield usageEvent;
80
+ }
81
+ yield done;
82
+ }
83
+ if (pendingUsage) {
84
+ const { kiroWireCache: _wire, ...usageEvent } = pendingUsage;
85
+ yield usageEvent;
86
+ }
87
+ }
88
+ /** Run a turn on the selected engine; `inProcess` is the TypeScript core. */
89
+ export function streamKiroOnEngine(request, inProcess) {
90
+ if (selectKiroEngine() === "ts" || !request.accessToken)
91
+ return inProcess(request);
92
+ const conversationId = request.sessionId ?? crypto.randomUUID();
93
+ let sidecarRequest;
94
+ try {
95
+ sidecarRequest = toKiroSidecarRequest(request, conversationId);
96
+ }
97
+ catch {
98
+ // An unknown model id: let the TypeScript core raise its own error.
99
+ return inProcess(request);
100
+ }
101
+ return engineStream({
102
+ vendor: KIRO_SIDECAR_VENDOR,
103
+ request: () => sidecarRequest,
104
+ inProcess: () => inProcess(request),
105
+ mapError: kiroErrorFromSidecar,
106
+ transform: (events) => postProcess(events, request, conversationId),
107
+ ...(request.signal ? { signal: request.signal } : {}),
108
+ });
109
+ }
110
+ export { kiroErrorFromSidecar, SidecarError };
111
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { type KiroCredentials } from "./oauth.js";
2
+ /** The subset of a host's login callbacks this flow uses (Pi's and OMP's both fit). */
3
+ export interface KiroHostLoginCallbacks {
4
+ onProgress?: (message: string) => void;
5
+ onPrompt?: (prompt: {
6
+ message: string;
7
+ placeholder?: string;
8
+ allowEmpty?: boolean;
9
+ secret?: boolean;
10
+ }) => Promise<string>;
11
+ }
12
+ export declare const KIRO_NO_SESSION_MESSAGE: string;
13
+ /**
14
+ * No browser flow of its own: every interactive method Kiro supports already
15
+ * lands a session in the kiro-cli store or the Kiro IDE token file, so this
16
+ * reads one of those (refreshing it when needed). The one credential with no
17
+ * browser step — an API key — is accepted directly.
18
+ */
19
+ export declare function loginKiroFromSession(callbacks: KiroHostLoginCallbacks): Promise<KiroCredentials>;
20
+ /** The token, region, and profile one request runs on. */
21
+ export interface ResolvedKiroRequestCredentials {
22
+ accessToken: string;
23
+ region: string;
24
+ profileArn?: string;
25
+ }
26
+ /**
27
+ * Decide which credential a request or catalog fetch runs on.
28
+ *
29
+ * The key a host resolves for the provider is the session returned from
30
+ * `/login kiro` — but it can also be an unresolved env reference such as
31
+ * `$KIRO_API_KEY` verbatim, and Kiro answers a bogus bearer with a 403 the core
32
+ * then has to recover from. So a host key is trusted only when it is
33
+ * recognizably a Kiro credential; anything else defers to the store, which is
34
+ * where the session actually lives.
35
+ *
36
+ * The stored record also carries the region and the profile ARN, and passing
37
+ * the ARN skips the ListAvailableProfiles round trip that a social login cannot
38
+ * answer anyway.
39
+ */
40
+ export declare function resolveKiroRequestCredentials(hostKey: string | undefined): Promise<ResolvedKiroRequestCredentials>;
@@ -0,0 +1,63 @@
1
+ // ABOUTME: Login and per-request credential choice for agent hosts (Pi, OMP), over the
2
+ // ABOUTME: sessions this machine already has. Host-neutral: hosts pass their own callbacks.
3
+ import { resolveApiRegion } from "./endpoints.js";
4
+ import { isApiKey, loginKiroWithApiKey, resolveKiroCredentials } from "./oauth.js";
5
+ export const KIRO_NO_SESSION_MESSAGE = "No Kiro session found. Sign in with `kiro-cli login` (Builder ID, IAM Identity Center, Google, or GitHub), " +
6
+ "then run /login kiro again — or paste a Kiro API key below.";
7
+ /**
8
+ * No browser flow of its own: every interactive method Kiro supports already
9
+ * lands a session in the kiro-cli store or the Kiro IDE token file, so this
10
+ * reads one of those (refreshing it when needed). The one credential with no
11
+ * browser step — an API key — is accepted directly.
12
+ */
13
+ export async function loginKiroFromSession(callbacks) {
14
+ callbacks.onProgress?.("Looking for an existing Kiro session…");
15
+ const existing = await resolveKiroCredentials();
16
+ if (existing) {
17
+ callbacks.onProgress?.(`Using the ${existing.authMethod} session from kiro-cli.`);
18
+ return existing;
19
+ }
20
+ if (!callbacks.onPrompt)
21
+ throw new Error(KIRO_NO_SESSION_MESSAGE);
22
+ const apiKey = (await callbacks.onPrompt({
23
+ message: KIRO_NO_SESSION_MESSAGE,
24
+ placeholder: "ksk_…",
25
+ allowEmpty: true,
26
+ secret: true,
27
+ })).trim();
28
+ if (!apiKey)
29
+ throw new Error(KIRO_NO_SESSION_MESSAGE);
30
+ return loginKiroWithApiKey(apiKey, callbacks.onProgress);
31
+ }
32
+ /**
33
+ * Decide which credential a request or catalog fetch runs on.
34
+ *
35
+ * The key a host resolves for the provider is the session returned from
36
+ * `/login kiro` — but it can also be an unresolved env reference such as
37
+ * `$KIRO_API_KEY` verbatim, and Kiro answers a bogus bearer with a 403 the core
38
+ * then has to recover from. So a host key is trusted only when it is
39
+ * recognizably a Kiro credential; anything else defers to the store, which is
40
+ * where the session actually lives.
41
+ *
42
+ * The stored record also carries the region and the profile ARN, and passing
43
+ * the ARN skips the ListAvailableProfiles round trip that a social login cannot
44
+ * answer anyway.
45
+ */
46
+ export async function resolveKiroRequestCredentials(hostKey) {
47
+ const stored = await resolveKiroCredentials();
48
+ const region = resolveApiRegion(stored?.region);
49
+ if (hostKey && (isApiKey(hostKey) || hostKey === stored?.access)) {
50
+ return { accessToken: hostKey, region, ...(stored?.profileArn ? { profileArn: stored.profileArn } : {}) };
51
+ }
52
+ if (stored) {
53
+ return {
54
+ accessToken: stored.access,
55
+ region,
56
+ ...(stored.profileArn ? { profileArn: stored.profileArn } : {}),
57
+ };
58
+ }
59
+ if (hostKey)
60
+ return { accessToken: hostKey, region };
61
+ throw new Error("Kiro credentials not set. Run `kiro-cli login`, or set KIRO_API_KEY to a `ksk_` API key.");
62
+ }
63
+ //# sourceMappingURL=host-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-auth.js","sourceRoot":"","sources":["../src/host-auth.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,4FAA4F;AAE5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAwB,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAazG,MAAM,CAAC,MAAM,uBAAuB,GAClC,6GAA6G;IAC7G,6DAA6D,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,SAAiC;IAC1E,SAAS,CAAC,UAAU,EAAE,CAAC,uCAAuC,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,MAAM,sBAAsB,EAAE,CAAC;IAChD,IAAI,QAAQ,EAAE,CAAC;QACb,SAAS,CAAC,UAAU,EAAE,CAAC,aAAa,QAAQ,CAAC,UAAU,yBAAyB,CAAC,CAAC;QAClF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,SAAS,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,CACb,MAAM,SAAS,CAAC,QAAQ,CAAC;QACvB,OAAO,EAAE,uBAAuB;QAChC,WAAW,EAAE,OAAO;QACpB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;KACb,CAAC,CACH,CAAC,IAAI,EAAE,CAAC;IACT,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACtD,OAAO,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;AAC3D,CAAC;AASD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAA2B;IAE3B,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;IAC9C,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;QACjE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC5G,CAAC;IACD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;YACL,WAAW,EAAE,MAAM,CAAC,MAAM;YAC1B,MAAM;YACN,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE,CAAC;IACJ,CAAC;IACD,IAAI,OAAO;QAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IACrD,MAAM,IAAI,KAAK,CAAC,0FAA0F,CAAC,CAAC;AAC9G,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { type KiroModel } from "./models.js";
2
+ /** What a host's model carries back to the provider; Pi's and OMP's models both fit. */
3
+ export interface KiroHostModel {
4
+ id: string;
5
+ name: string;
6
+ reasoning: boolean;
7
+ input: readonly ("text" | "image")[];
8
+ cost: {
9
+ input: number;
10
+ output: number;
11
+ cacheRead: number;
12
+ cacheWrite: number;
13
+ };
14
+ contextWindow?: number | null;
15
+ maxTokens?: number | null;
16
+ kiroModelId?: string;
17
+ kiroProfileArn?: string;
18
+ additionalModelRequestFieldsSchema?: Record<string, unknown>;
19
+ }
20
+ /**
21
+ * A host's registry keeps its own model, built from the config the provider
22
+ * registered, so the catalog entry is looked up again here rather than carried
23
+ * through: the effort ladder and the request-fields schema decide effort
24
+ * mapping, and a request must use the same ones the catalog advertised.
25
+ *
26
+ * Looks up the region's authenticated cache, not the static bootstrap list:
27
+ * models discovered only through the authenticated catalog would otherwise
28
+ * miss this lookup and fall through to guessing a wire id from the
29
+ * dash-spelled local `id`, which Kiro rejects as `INVALID_MODEL_ID`.
30
+ */
31
+ export declare function toKiroModelForHost(model: KiroHostModel, region: string): KiroModel;
@@ -0,0 +1,39 @@
1
+ // ABOUTME: Rebuilds the core's model descriptor from the model a host hands back at request time.
2
+ // ABOUTME: Shared by every agent host (Pi, OMP) whose registry keeps its own copy of the model.
3
+ import { getCachedModels } from "./models.js";
4
+ /**
5
+ * A host's registry keeps its own model, built from the config the provider
6
+ * registered, so the catalog entry is looked up again here rather than carried
7
+ * through: the effort ladder and the request-fields schema decide effort
8
+ * mapping, and a request must use the same ones the catalog advertised.
9
+ *
10
+ * Looks up the region's authenticated cache, not the static bootstrap list:
11
+ * models discovered only through the authenticated catalog would otherwise
12
+ * miss this lookup and fall through to guessing a wire id from the
13
+ * dash-spelled local `id`, which Kiro rejects as `INVALID_MODEL_ID`.
14
+ */
15
+ export function toKiroModelForHost(model, region) {
16
+ const known = getCachedModels(region).find((candidate) => candidate.id === model.id);
17
+ return {
18
+ ...(known ?? {
19
+ id: model.id,
20
+ // No fallback to `model.id`: that dash-spelled local id is not a valid
21
+ // Kiro wire id. `""` is falsy, so `resolveKiroModel` runs its own
22
+ // cache/bootstrap/dot-normalize resolution instead of being
23
+ // short-circuited by a value that is really just `model.id` again.
24
+ kiroModelId: model.kiroModelId ?? "",
25
+ name: model.name,
26
+ reasoning: model.reasoning,
27
+ input: [...model.input],
28
+ cost: { ...model.cost },
29
+ contextWindow: model.contextWindow ?? 200_000,
30
+ maxTokens: model.maxTokens ?? 8_192,
31
+ }),
32
+ region,
33
+ ...(model.kiroProfileArn ? { profileArn: model.kiroProfileArn } : {}),
34
+ ...(model.additionalModelRequestFieldsSchema
35
+ ? { additionalModelRequestFieldsSchema: model.additionalModelRequestFieldsSchema }
36
+ : {}),
37
+ };
38
+ }
39
+ //# sourceMappingURL=host-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-model.js","sourceRoot":"","sources":["../src/host-model.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,gGAAgG;AAEhG,OAAO,EAAE,eAAe,EAAkB,MAAM,aAAa,CAAC;AAgB9D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAoB,EAAE,MAAc;IACrE,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;IACrF,OAAO;QACL,GAAG,CAAC,KAAK,IAAI;YACX,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,uEAAuE;YACvE,kEAAkE;YAClE,4DAA4D;YAC5D,mEAAmE;YACnE,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;YACpC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;YACvB,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE;YACvB,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,OAAO;YAC7C,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,KAAK;SACpC,CAAC;QACF,MAAM;QACN,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,GAAG,CAAC,KAAK,CAAC,kCAAkC;YAC1C,CAAC,CAAC,EAAE,kCAAkC,EAAE,KAAK,CAAC,kCAAkC,EAAE;YAClF,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -4,21 +4,25 @@ export { applyCacheEstimate, resetCacheEstimatorForTests } from "./cache-estimat
4
4
  export { calculateKiroCost } from "./cost.js";
5
5
  export { debugEnabled, debugLog, formatSafeError, redactSensitiveText } from "./debug.js";
6
6
  export { buildKiroAdditionalModelRequestFields, clampKiroEffort, deriveKiroEffort, fallbackKiroEffort, getKiroEffortConfig, type KiroAdditionalModelRequestFields, type KiroEffortConfig, type KiroEffortField, mapEffortToKiroValue, } from "./effort.js";
7
- export { getKiroEndpoints, getKiroRegionFromEndpoint, getKiroRegionFromProfileArn, type KiroEndpoints, resolveApiRegion, } from "./endpoints.js";
7
+ export { getKiroEndpoints, getKiroRegionFromEndpoint, getKiroRegionFromProfileArn, KIRO_MANAGEMENT_ENDPOINT_ENV, KIRO_RUNTIME_ENDPOINT_ENV, type KiroEndpoints, resolveApiRegion, } from "./endpoints.js";
8
+ export { KIRO_SIDECAR_VENDOR, kiroErrorFromSidecar, SidecarError, selectKiroEngine, streamKiroOnEngine, toKiroSidecarRequest, } from "./engine.js";
9
+ export { runKiroOp } from "./engine-ops.js";
8
10
  export { extractKiroReasonCode, KiroApiError, type KiroProviderAttempts, parseRetryAfterMs, } from "./errors.js";
9
11
  export { isKiroEventKey, KIRO_ERROR_MEMBERS, KIRO_EVENT_KEYS, type KiroErrorData, type KiroErrorKind, type KiroEventKey, type KiroWireEvent, type KiroWireUsage, lookupKiroErrorMember, parseKiroEvent, parseKiroEventByShape, parseKiroExceptionFrame, } from "./event-parser.js";
10
12
  export { isKiroToolStructureRule, KIRO_TOOL_STRUCTURE_RULES, KIRO_VALIDATION_MESSAGES, type KiroRepairResult, type KiroToolStructureRule, type KiroValidationError, type KiroValidationResult, KiroValidationRule, kiroConversationEntries, repairKiroConversation, SYNTHETIC_FAILED_TOOL_RESULT_TEXT, validateKiroConversation, validateKiroToolStructure, } from "./history-validator.js";
13
+ export { KIRO_NO_SESSION_MESSAGE, type KiroHostLoginCallbacks, loginKiroFromSession, type ResolvedKiroRequestCredentials, resolveKiroRequestCredentials, } from "./host-auth.js";
14
+ export { type KiroHostModel, toKiroModelForHost } from "./host-model.js";
11
15
  export { parseInvokeToolCalls } from "./invoke-tool-parser.js";
12
16
  export { getKiroCliCredentials, getKiroCliCredentialsAllowExpired, getKiroCliDbPath, getKiroCliModelRates, getKiroCliSocialToken, getKiroCliSocialTokenAllowExpired, type KiroModelRate, refreshViaKiroCli, saveKiroCliCredentials, } from "./kiro-cli.js";
13
17
  export { getKiroIdeCredentials, getKiroIdeCredentialsAllowExpired } from "./kiro-ide.js";
14
- export { fetchKiroModelCatalog, type KiroCatalogModel, type KiroManagementAuth, KiroManagementHttpError, resolveKiroProfileArn, } from "./management.js";
15
- export { applyEffortLadder, getCachedModels, isCacheStale, KIRO_MANAGEMENT_CACHE_PATH, KIRO_MODEL_IDS, type KiroModel, kiroModels, loadCachedModelIds, mapKiroCatalogModels, resolveKiroModel, updateKiroModelsCache, } from "./models.js";
16
- export { isApiKey, isExpired, type KiroAuthMethod, type KiroAuthSource, type KiroCredentials, kiroAuthHeaders, loginKiroWithApiKey, refreshKiroToken, resolveKiroAuthSource, resolveKiroCredentials, } from "./oauth.js";
18
+ export { applyKiroProfileArnCacheChanges, applyKiroProfileRegionChanges, fetchKiroModelCatalog, type KiroCatalogModel, type KiroManagementAuth, KiroManagementHttpError, resolveKiroProfileArn, snapshotKiroProfileArnCache, snapshotKiroProfileRegionCache, } from "./management.js";
19
+ export { applyEffortLadder, getCachedModels, isCacheStale, KIRO_MANAGEMENT_CACHE_PATH, KIRO_MODEL_IDS, type KiroModel, kiroModels, loadCachedModelIds, mapKiroCatalogModels, resolveKiroModel, updateKiroModelsCache, updateKiroModelsCacheInProcess, } from "./models.js";
20
+ export { isApiKey, isExpired, KIRO_DESKTOP_REFRESH_ENDPOINT_ENV, KIRO_OIDC_ENDPOINT_ENV, type KiroAuthMethod, type KiroAuthSource, type KiroCredentials, kiroAuthHeaders, loginKiroWithApiKey, refreshKiroToken, resolveKiroAuthSource, resolveKiroCredentials, } from "./oauth.js";
17
21
  export { type BuildKiroRequestParams, type BuiltKiroRequest, buildKiroRequest, type KiroRequest, } from "./request-builder.js";
18
22
  export { type KiroAttemptSummary, type KiroCompletedResponse, KiroResponseAssembler, } from "./response-assembler.js";
19
23
  export { IDLE_TIMEOUT, type KiroEventStreamOptions, type KiroEventStreamOutcome, type KiroEventStreamReader, type KiroWireEventFrame, readKiroEventStream, } from "./response-stream.js";
20
24
  export { CAPACITY_PATTERN, isCapacityError, isNonRetryableBodyError, isTooBigError, KIRO_REASON_CODES, type KiroReasonCode, NON_RETRYABLE_BODY_PATTERNS, TOO_BIG_PATTERNS, } from "./retry.js";
21
- export { type KiroStreamRequest, resetProfileArnCache, streamKiro } from "./stream.js";
25
+ export { type KiroStreamRequest, resetProfileArnCache, streamKiro, streamKiroInProcess } from "./stream.js";
22
26
  export { ThinkingTagParser } from "./thinking-parser.js";
23
27
  export { countTokens } from "./tokenizer.js";
24
28
  export { normalizeKiroToolName } from "./tool-name-aliases.js";
@@ -27,5 +31,5 @@ export { buildHistory, EMPTY_CONTENT_PLACEHOLDER, type KiroHistoryEntry, type Ki
27
31
  export { abortableDelay, createResponseHeaderDeadline, logCapacityEvent, type ResponseHeaderDeadline, } from "./transport.js";
28
32
  export { TRUNCATION_NOTICE, wasPreviousResponseTruncated } from "./truncation.js";
29
33
  export * from "./types.js";
30
- export { fetchKiroUsage, type KiroProviderUsage, type KiroProviderUsageBucket } from "./usage.js";
34
+ export { fetchKiroUsage, fetchKiroUsageInProcess, type KiroProviderUsage, type KiroProviderUsageBucket, } from "./usage.js";
31
35
  export { DEFAULT_ESTIMATED_CACHE_TIMEOUT_MS, DEFAULT_USD_PER_CREDIT, estimateKiroCreditCost, KIRO_USAGE_TRACKING_DISABLED, type KiroUsageTracking, resolveKiroUsageTracking, } from "./usage-tracking.js";
package/dist/index.js CHANGED
@@ -5,16 +5,20 @@ export { applyCacheEstimate, resetCacheEstimatorForTests } from "./cache-estimat
5
5
  export { calculateKiroCost } from "./cost.js";
6
6
  export { debugEnabled, debugLog, formatSafeError, redactSensitiveText } from "./debug.js";
7
7
  export { buildKiroAdditionalModelRequestFields, clampKiroEffort, deriveKiroEffort, fallbackKiroEffort, getKiroEffortConfig, mapEffortToKiroValue, } from "./effort.js";
8
- export { getKiroEndpoints, getKiroRegionFromEndpoint, getKiroRegionFromProfileArn, resolveApiRegion, } from "./endpoints.js";
8
+ export { getKiroEndpoints, getKiroRegionFromEndpoint, getKiroRegionFromProfileArn, KIRO_MANAGEMENT_ENDPOINT_ENV, KIRO_RUNTIME_ENDPOINT_ENV, resolveApiRegion, } from "./endpoints.js";
9
+ export { KIRO_SIDECAR_VENDOR, kiroErrorFromSidecar, SidecarError, selectKiroEngine, streamKiroOnEngine, toKiroSidecarRequest, } from "./engine.js";
10
+ export { runKiroOp } from "./engine-ops.js";
9
11
  export { extractKiroReasonCode, KiroApiError, parseRetryAfterMs, } from "./errors.js";
10
12
  export { isKiroEventKey, KIRO_ERROR_MEMBERS, KIRO_EVENT_KEYS, lookupKiroErrorMember, parseKiroEvent, parseKiroEventByShape, parseKiroExceptionFrame, } from "./event-parser.js";
11
13
  export { isKiroToolStructureRule, KIRO_TOOL_STRUCTURE_RULES, KIRO_VALIDATION_MESSAGES, KiroValidationRule, kiroConversationEntries, repairKiroConversation, SYNTHETIC_FAILED_TOOL_RESULT_TEXT, validateKiroConversation, validateKiroToolStructure, } from "./history-validator.js";
14
+ export { KIRO_NO_SESSION_MESSAGE, loginKiroFromSession, resolveKiroRequestCredentials, } from "./host-auth.js";
15
+ export { toKiroModelForHost } from "./host-model.js";
12
16
  export { parseInvokeToolCalls } from "./invoke-tool-parser.js";
13
17
  export { getKiroCliCredentials, getKiroCliCredentialsAllowExpired, getKiroCliDbPath, getKiroCliModelRates, getKiroCliSocialToken, getKiroCliSocialTokenAllowExpired, refreshViaKiroCli, saveKiroCliCredentials, } from "./kiro-cli.js";
14
18
  export { getKiroIdeCredentials, getKiroIdeCredentialsAllowExpired } from "./kiro-ide.js";
15
- export { fetchKiroModelCatalog, KiroManagementHttpError, resolveKiroProfileArn, } from "./management.js";
16
- export { applyEffortLadder, getCachedModels, isCacheStale, KIRO_MANAGEMENT_CACHE_PATH, KIRO_MODEL_IDS, kiroModels, loadCachedModelIds, mapKiroCatalogModels, resolveKiroModel, updateKiroModelsCache, } from "./models.js";
17
- export { isApiKey, isExpired, kiroAuthHeaders, loginKiroWithApiKey, refreshKiroToken, resolveKiroAuthSource, resolveKiroCredentials, } from "./oauth.js";
19
+ export { applyKiroProfileArnCacheChanges, applyKiroProfileRegionChanges, fetchKiroModelCatalog, KiroManagementHttpError, resolveKiroProfileArn, snapshotKiroProfileArnCache, snapshotKiroProfileRegionCache, } from "./management.js";
20
+ export { applyEffortLadder, getCachedModels, isCacheStale, KIRO_MANAGEMENT_CACHE_PATH, KIRO_MODEL_IDS, kiroModels, loadCachedModelIds, mapKiroCatalogModels, resolveKiroModel, updateKiroModelsCache, updateKiroModelsCacheInProcess, } from "./models.js";
21
+ export { isApiKey, isExpired, KIRO_DESKTOP_REFRESH_ENDPOINT_ENV, KIRO_OIDC_ENDPOINT_ENV, kiroAuthHeaders, loginKiroWithApiKey, refreshKiroToken, resolveKiroAuthSource, resolveKiroCredentials, } from "./oauth.js";
18
22
  // The stages `streamKiro` runs in order. Exported so a caller can drive one on
19
23
  // its own — building a request without sending it, or assembling blocks from
20
24
  // events it sourced elsewhere — which is what splitting them apart was for.
@@ -26,7 +30,7 @@ export { IDLE_TIMEOUT, readKiroEventStream, } from "./response-stream.js";
26
30
  // in hand (a persisted log line, say) instead of hardcoding copies of the
27
31
  // literals, which drift when the service adds a code.
28
32
  export { CAPACITY_PATTERN, isCapacityError, isNonRetryableBodyError, isTooBigError, KIRO_REASON_CODES, NON_RETRYABLE_BODY_PATTERNS, TOO_BIG_PATTERNS, } from "./retry.js";
29
- export { resetProfileArnCache, streamKiro } from "./stream.js";
33
+ export { resetProfileArnCache, streamKiro, streamKiroInProcess } from "./stream.js";
30
34
  export { ThinkingTagParser } from "./thinking-parser.js";
31
35
  export { countTokens } from "./tokenizer.js";
32
36
  export { normalizeKiroToolName } from "./tool-name-aliases.js";
@@ -35,6 +39,6 @@ export { buildHistory, EMPTY_CONTENT_PLACEHOLDER, kiroToolNameAliases, normalize
35
39
  export { abortableDelay, createResponseHeaderDeadline, logCapacityEvent, } from "./transport.js";
36
40
  export { TRUNCATION_NOTICE, wasPreviousResponseTruncated } from "./truncation.js";
37
41
  export * from "./types.js";
38
- export { fetchKiroUsage } from "./usage.js";
42
+ export { fetchKiroUsage, fetchKiroUsageInProcess, } from "./usage.js";
39
43
  export { DEFAULT_ESTIMATED_CACHE_TIMEOUT_MS, DEFAULT_USD_PER_CREDIT, estimateKiroCreditCost, KIRO_USAGE_TRACKING_DISABLED, resolveKiroUsageTracking, } from "./usage-tracking.js";
40
44
  //# sourceMappingURL=index.js.map