ns-kiro-core 0.2.3 → 0.3.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/dist/blocks.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { KiroStreamEvent } from "./types.js";
2
+ type BlockKind = "text" | "thinking" | "toolCall";
2
3
  /**
3
4
  * Allocates block indexes and accumulates their content while emitting the
4
5
  * neutral stream events for each transition.
@@ -21,6 +22,8 @@ export declare class KiroBlockBuffer {
21
22
  /** Reserve an index for a block this buffer does not accumulate (a tool call). */
22
23
  reserve(): number;
23
24
  getText(index: number): string;
25
+ /** Kinds of the live blocks, in allocation order. */
26
+ kinds(): BlockKind[];
24
27
  /**
25
28
  * Rewrite one accumulated block before it is closed. Used by the recovery
26
29
  * passes that lift tool calls out of text and by echo-noise stripping, both
@@ -30,3 +33,4 @@ export declare class KiroBlockBuffer {
30
33
  /** Announce that an internal retry discarded everything emitted so far. */
31
34
  reset(): void;
32
35
  }
36
+ export {};
package/dist/blocks.js CHANGED
@@ -64,6 +64,10 @@ export class KiroBlockBuffer {
64
64
  getText(index) {
65
65
  return this.blocks.get(index)?.text ?? "";
66
66
  }
67
+ /** Kinds of the live blocks, in allocation order. */
68
+ kinds() {
69
+ return [...this.blocks.values()].map((block) => block.kind);
70
+ }
67
71
  /**
68
72
  * Rewrite one accumulated block before it is closed. Used by the recovery
69
73
  * passes that lift tool calls out of text and by echo-noise stripping, both
@@ -1 +1 @@
1
- {"version":3,"file":"blocks.js","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"blocks.js","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { KiroWireUsage } from "./event-parser.js";
2
+ import type { KiroUsage } from "./types.js";
3
+ import type { KiroUsageTracking } from "./usage-tracking.js";
4
+ /**
5
+ * Estimate repeated prompt tokens as cache reads, then record the successful
6
+ * turn as the next baseline. Mutates `usage` only when every conservative guard
7
+ * passes. Real wire cache counters always win.
8
+ */
9
+ export declare function applyCacheEstimate(conversationId: string, usage: KiroUsage, wireUsage: KiroWireUsage | null, config: KiroUsageTracking, now?: number): number;
10
+ /** Clear estimator state between tests. */
11
+ export declare function resetCacheEstimatorForTests(): void;
@@ -0,0 +1,61 @@
1
+ // ABOUTME: Conservative in-memory cache-read estimation for Kiro usage records.
2
+ // ABOUTME: Reclassifies repeated prompt input without changing total tokens or dollar cost.
3
+ const stateByConversation = new Map();
4
+ const MAX_TRACKED_CONVERSATIONS = 128;
5
+ let warnedWireCacheCounters = false;
6
+ /**
7
+ * Estimate repeated prompt tokens as cache reads, then record the successful
8
+ * turn as the next baseline. Mutates `usage` only when every conservative guard
9
+ * passes. Real wire cache counters always win.
10
+ */
11
+ export function applyCacheEstimate(conversationId, usage, wireUsage, config, now = Date.now()) {
12
+ const previous = stateByConversation.get(conversationId);
13
+ const promptTokens = usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0) + usage.output;
14
+ const wireReportedCache = wireUsage?.cacheReadInputTokens !== undefined || wireUsage?.cacheWriteInputTokens !== undefined;
15
+ if (wireReportedCache) {
16
+ if (config.estimateCacheUsage && !warnedWireCacheCounters) {
17
+ warnedWireCacheCounters = true;
18
+ console.warn("[kiro-core] Kiro now reports cache token counters; cache estimation was skipped and may be disabled.");
19
+ }
20
+ noteSuccessfulTurn(conversationId, promptTokens, usage.input, now);
21
+ return 0;
22
+ }
23
+ if (!config.estimateCacheUsage || usage.input <= 0)
24
+ return 0;
25
+ if (!previous) {
26
+ noteSuccessfulTurn(conversationId, promptTokens, usage.input, now);
27
+ return 0;
28
+ }
29
+ const expired = config.estimatedCacheTimeout > 0 && now - previous.turnTimestamp > config.estimatedCacheTimeout;
30
+ const contextShrank = usage.input < previous.promptTokens * 0.6;
31
+ if (expired || contextShrank) {
32
+ noteSuccessfulTurn(conversationId, promptTokens, usage.input, now);
33
+ return 0;
34
+ }
35
+ const estimatedRead = Math.min(previous.promptTokens, usage.input);
36
+ if (estimatedRead > 0) {
37
+ usage.input -= estimatedRead;
38
+ usage.cacheRead = (usage.cacheRead ?? 0) + estimatedRead;
39
+ usage.cacheEstimated = true;
40
+ }
41
+ noteSuccessfulTurn(conversationId, promptTokens, promptTokens, now);
42
+ return estimatedRead;
43
+ }
44
+ function noteSuccessfulTurn(conversationId, promptTokens, input, now) {
45
+ if (input <= 0 || promptTokens <= 0)
46
+ return;
47
+ // Refresh insertion order so the map is a bounded least-recently-used set.
48
+ stateByConversation.delete(conversationId);
49
+ stateByConversation.set(conversationId, { promptTokens, turnTimestamp: now });
50
+ if (stateByConversation.size > MAX_TRACKED_CONVERSATIONS) {
51
+ const oldest = stateByConversation.keys().next().value;
52
+ if (oldest !== undefined)
53
+ stateByConversation.delete(oldest);
54
+ }
55
+ }
56
+ /** Clear estimator state between tests. */
57
+ export function resetCacheEstimatorForTests() {
58
+ stateByConversation.clear();
59
+ warnedWireCacheCounters = false;
60
+ }
61
+ //# sourceMappingURL=cache-estimator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-estimator.js","sourceRoot":"","sources":["../src/cache-estimator.ts"],"names":[],"mappings":"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"}
@@ -5,4 +5,12 @@ export interface KiroEndpoints {
5
5
  }
6
6
  export declare function resolveApiRegion(ssoRegion: string | undefined): string;
7
7
  export declare function getKiroEndpoints(region: string): KiroEndpoints;
8
+ /**
9
+ * A Kiro profile is owned by one region and its ARN carries that region. The
10
+ * runtime API rejects a profile ARN issued in another region with a generic
11
+ * `Improperly formed request.`, so runtime host selection has to follow the
12
+ * profile rather than the SSO-derived region: an Identity Center instance in
13
+ * us-east-1 can own a profile in eu-central-1.
14
+ */
15
+ export declare function getKiroRegionFromProfileArn(profileArn: string | undefined): string | undefined;
8
16
  export declare function getKiroRegionFromEndpoint(endpoint: string): string | undefined;
package/dist/endpoints.js CHANGED
@@ -7,6 +7,7 @@ const API_REGION_MAP = {
7
7
  "ap-southeast-1": "us-east-1",
8
8
  "ap-southeast-2": "us-east-1",
9
9
  "ap-northeast-1": "us-east-1",
10
+ "ap-northeast-2": "us-east-1",
10
11
  "ap-south-1": "us-east-1",
11
12
  "eu-west-1": "eu-central-1",
12
13
  "eu-west-2": "eu-central-1",
@@ -28,6 +29,19 @@ export function getKiroEndpoints(region) {
28
29
  runtime: `https://runtime.${region}.kiro.dev/`,
29
30
  };
30
31
  }
32
+ /**
33
+ * A Kiro profile is owned by one region and its ARN carries that region. The
34
+ * runtime API rejects a profile ARN issued in another region with a generic
35
+ * `Improperly formed request.`, so runtime host selection has to follow the
36
+ * profile rather than the SSO-derived region: an Identity Center instance in
37
+ * us-east-1 can own a profile in eu-central-1.
38
+ */
39
+ export function getKiroRegionFromProfileArn(profileArn) {
40
+ if (!profileArn)
41
+ return undefined;
42
+ const region = profileArn.split(":")[3];
43
+ return region && /^[a-z]{2}(?:-[a-z]+)+-\d$/.test(region) ? region : undefined;
44
+ }
31
45
  export function getKiroRegionFromEndpoint(endpoint) {
32
46
  try {
33
47
  const [service, region, ...suffix] = new URL(endpoint).hostname.split(".");
@@ -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,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,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,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"}
@@ -0,0 +1,39 @@
1
+ export { parseRetryAfterMs } from "./retry.js";
2
+ /** Retries this provider already performed internally before giving up. */
3
+ export interface KiroProviderAttempts {
4
+ /** 403 credential-refresh retries (`exponentialBackoff(n, 500, MAX_RETRY_DELAY)`). */
5
+ credentialRefresh: number;
6
+ /** INSUFFICIENT_MODEL_CAPACITY retries (`capacityRetryConfig`, 5s base / 30s ceiling). */
7
+ capacity: number;
8
+ }
9
+ /**
10
+ * A Kiro runtime HTTP failure with its classification preserved.
11
+ *
12
+ * `message` is deliberately identical to the string this provider has always
13
+ * thrown — downstream consumers match on that text, and the typed fields are
14
+ * strictly additive. Read them instead of re-parsing `message`.
15
+ *
16
+ * Unlike the upstream pi extension, `streamKiro` here is a generator that
17
+ * rejects with this error, so the typed fields reach the host adapter directly
18
+ * on the thrown value rather than through a diagnostics channel.
19
+ */
20
+ export declare class KiroApiError extends Error {
21
+ readonly status: number;
22
+ readonly reasonCode?: string | undefined;
23
+ readonly retryAfterMs?: number | undefined;
24
+ readonly providerAttempts?: KiroProviderAttempts | undefined;
25
+ constructor(message: string, status: number, reasonCode?: string | undefined, retryAfterMs?: number | undefined, providerAttempts?: KiroProviderAttempts | undefined);
26
+ }
27
+ /**
28
+ * Pull Kiro's reason code out of an error body.
29
+ *
30
+ * Prefers the parsed JSON `reason` field, which is what Kiro actually sends
31
+ * (`{"message":"Improperly formed request.","reason":"REQUEST_BODY_INVALID"}`).
32
+ * Falls back to scanning for a known marker so a plain-text or
33
+ * event-stream-wrapped body still classifies.
34
+ *
35
+ * Returns undefined rather than guessing when the body carries no code: a
36
+ * bare 413 or `Input is too long` has no reason code, and inventing one would
37
+ * make an absent classification indistinguishable from a real one.
38
+ */
39
+ export declare function extractKiroReasonCode(errorText: string): string | undefined;
package/dist/errors.js ADDED
@@ -0,0 +1,82 @@
1
+ // ABOUTME: Typed error for Kiro runtime HTTP failures, carrying the class the
2
+ // ABOUTME: throw site already computed so consumers need not re-parse the message.
3
+ import { KIRO_REASON_CODES } from "./retry.js";
4
+ /**
5
+ * Known reason-code markers to scan for when the body is not parseable JSON.
6
+ *
7
+ * Deliberately module-private and deliberately NOT named `KIRO_REASON_CODES`:
8
+ * this is only a fallback marker list for `extractKiroReasonCode`, not a public
9
+ * vocabulary. The literals it shares with `src/retry.ts` (`TOO_BIG_PATTERNS`,
10
+ * `NON_RETRYABLE_BODY_PATTERNS`, `CAPACITY_PATTERN`) are matched there for
11
+ * *classification*, which is a separate concern — `Input is too long` is a
12
+ * classification marker with no reason code, and `REQUEST_BODY_INVALID` is a
13
+ * reason code that must never classify as too-big.
14
+ *
15
+ * Not exhaustive: `reasonCode` is a passthrough of whatever the body carried, so
16
+ * an unrecognized code still reaches the consumer verbatim.
17
+ */
18
+ const REASON_CODE_MARKERS = [
19
+ KIRO_REASON_CODES.CONTENT_LENGTH_EXCEEDS_THRESHOLD,
20
+ KIRO_REASON_CODES.MONTHLY_REQUEST_COUNT,
21
+ KIRO_REASON_CODES.INSUFFICIENT_MODEL_CAPACITY,
22
+ KIRO_REASON_CODES.REQUEST_BODY_INVALID,
23
+ ];
24
+ // Retry-header units and malformed-value handling are owned by retry.ts.
25
+ // Re-export the canonical helper to preserve this module's public surface
26
+ // without maintaining a second parser that can drift from retry behavior.
27
+ export { parseRetryAfterMs } from "./retry.js";
28
+ /**
29
+ * A Kiro runtime HTTP failure with its classification preserved.
30
+ *
31
+ * `message` is deliberately identical to the string this provider has always
32
+ * thrown — downstream consumers match on that text, and the typed fields are
33
+ * strictly additive. Read them instead of re-parsing `message`.
34
+ *
35
+ * Unlike the upstream pi extension, `streamKiro` here is a generator that
36
+ * rejects with this error, so the typed fields reach the host adapter directly
37
+ * on the thrown value rather than through a diagnostics channel.
38
+ */
39
+ export class KiroApiError extends Error {
40
+ status;
41
+ reasonCode;
42
+ retryAfterMs;
43
+ providerAttempts;
44
+ constructor(message, status, reasonCode, retryAfterMs, providerAttempts) {
45
+ super(message);
46
+ this.status = status;
47
+ this.reasonCode = reasonCode;
48
+ this.retryAfterMs = retryAfterMs;
49
+ this.providerAttempts = providerAttempts;
50
+ this.name = "KiroApiError";
51
+ }
52
+ }
53
+ /**
54
+ * Pull Kiro's reason code out of an error body.
55
+ *
56
+ * Prefers the parsed JSON `reason` field, which is what Kiro actually sends
57
+ * (`{"message":"Improperly formed request.","reason":"REQUEST_BODY_INVALID"}`).
58
+ * Falls back to scanning for a known marker so a plain-text or
59
+ * event-stream-wrapped body still classifies.
60
+ *
61
+ * Returns undefined rather than guessing when the body carries no code: a
62
+ * bare 413 or `Input is too long` has no reason code, and inventing one would
63
+ * make an absent classification indistinguishable from a real one.
64
+ */
65
+ export function extractKiroReasonCode(errorText) {
66
+ if (!errorText)
67
+ return undefined;
68
+ const trimmed = errorText.trim();
69
+ if (trimmed.startsWith("{")) {
70
+ try {
71
+ const parsed = JSON.parse(trimmed);
72
+ const reason = parsed.reason ?? parsed.reasonCode;
73
+ if (typeof reason === "string" && reason.length > 0)
74
+ return reason;
75
+ }
76
+ catch {
77
+ // Fall through to marker scan — a truncated or wrapped body is still useful.
78
+ }
79
+ }
80
+ return REASON_CODE_MARKERS.find((code) => errorText.includes(code));
81
+ }
82
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,mFAAmF;AAEnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;;;;;GAaG;AACH,MAAM,mBAAmB,GAAG;IAC1B,iBAAiB,CAAC,gCAAgC;IAClD,iBAAiB,CAAC,qBAAqB;IACvC,iBAAiB,CAAC,2BAA2B;IAC7C,iBAAiB,CAAC,oBAAoB;CAC9B,CAAC;AAEX,yEAAyE;AACzE,0EAA0E;AAC1E,0EAA0E;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAU/C;;;;;;;;;;GAUG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAG1B;IACA;IACA;IACA;IALX,YACE,OAAe,EACN,MAAc,EACd,UAAmB,EACnB,YAAqB,EACrB,gBAAuC;QAEhD,KAAK,CAAC,OAAO,CAAC,CAAC;QALN,WAAM,GAAN,MAAM,CAAQ;QACd,eAAU,GAAV,UAAU,CAAS;QACnB,iBAAY,GAAZ,YAAY,CAAS;QACrB,qBAAgB,GAAhB,gBAAgB,CAAuB;QAGhD,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAiB;IACrD,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA+C,CAAC;YACjF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,CAAC;YAClD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,MAAM,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,6EAA6E;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACtE,CAAC"}
@@ -1,3 +1,85 @@
1
+ /**
2
+ * Members of the `ChatResponseStream` tagged union emitted by
3
+ * `generateAssistantResponse` on `runtime.{region}.kiro.dev`.
4
+ *
5
+ * Source of truth: the generated Smithy client for the same service
6
+ * (`@amzn/kiro-runtime-service-typescript-client`, `ChatResponseStream`).
7
+ * The frame's `:event-type` header carries one of these keys, so routing is a
8
+ * switch on the key rather than a guess based on which fields happen to be set.
9
+ */
10
+ export declare const KIRO_EVENT_KEYS: readonly ["assistantResponseEvent", "codeReferenceEvent", "contextUsageEvent", "documentCitationEvent", "error", "metadataEvent", "meteringEvent", "reasoningContentEvent", "serviceUnavailableError", "throttlingError", "toolResultEvent", "toolUseEvent", "validationError"];
11
+ export type KiroEventKey = (typeof KIRO_EVENT_KEYS)[number];
12
+ export declare function isKiroEventKey(key: string): key is KiroEventKey;
13
+ /**
14
+ * What a `metadataEvent` frame's `tokenUsage` reports.
15
+ *
16
+ * Observed 2026-09-06 against `claude-sonnet-5` in us-east-1: Kiro does not
17
+ * send token counts at all — the billing record arrives on `meteringEvent`
18
+ * instead. Token counts are still parsed because the object form is what the
19
+ * underlying services emit and Kiro may yet expose it.
20
+ *
21
+ * Kiro does cache prompts server-side (a repeated prefix billed 0.0350 against
22
+ * 0.0659 for a fresh one, and a changed prefix went straight back to 0.0659),
23
+ * but it reports no cache token counts and its request schema
24
+ * (`additionalProperties: false`) offers no way to ask for caching. The cache
25
+ * fields below are therefore read defensively, in the spellings the upstream
26
+ * services use, and stay `undefined` when absent rather than becoming `0`.
27
+ */
28
+ export interface KiroWireUsage {
29
+ /** `TokenUsage.uncachedInputTokens` — input tokens billed at full rate. */
30
+ inputTokens?: number;
31
+ outputTokens?: number;
32
+ totalTokens?: number;
33
+ cacheReadInputTokens?: number;
34
+ cacheWriteInputTokens?: number;
35
+ contextUsagePercentage?: number;
36
+ /**
37
+ * `TokenUsage.normalizedTokenUsage` — usage normalized by MPS from credit
38
+ * information. Distinct from `MeteringEvent.usage`, which is a raw credit
39
+ * count; surfaced so it is not dropped at the boundary like the rest of
40
+ * `metadataEvent` was.
41
+ */
42
+ normalizedTokenUsage?: number;
43
+ /** `MetadataEvent.stopReason`, passed through verbatim. */
44
+ rawStopReason?: string;
45
+ /** `MetadataEvent.stopDetails`, passed through verbatim. */
46
+ stopDetails?: Record<string, unknown>;
47
+ }
48
+ /** Which modeled union member produced an error event. */
49
+ export type KiroErrorKind = "internalServer" | "throttling" | "validation" | "serviceUnavailable" | "unknown";
50
+ /**
51
+ * The four error members of `ChatResponseStream` target `@error` shapes, so the
52
+ * service frames them as `:message-type: exception` with the union member name
53
+ * in `:exception-type` — not as ordinary `event` frames. Mapping the member to
54
+ * its exception class here keeps both framings on one table.
55
+ */
56
+ export declare const KIRO_ERROR_MEMBERS: Readonly<Record<string, {
57
+ kind: KiroErrorKind;
58
+ exception: string;
59
+ }>>;
60
+ /**
61
+ * Look up an error member by a token the SERVICE chose.
62
+ *
63
+ * `KIRO_ERROR_TOKENS` is an ordinary object literal, so a bare index would
64
+ * also resolve inherited `Object.prototype` members: an `:exception-type` of
65
+ * `toString` or `constructor` returns a truthy value whose `kind` and
66
+ * `exception` are both undefined, silently discarding the member name this
67
+ * routing exists to preserve. Only own properties count as modeled members.
68
+ */
69
+ export declare function lookupKiroErrorMember(key: string): {
70
+ kind: KiroErrorKind;
71
+ exception: string;
72
+ } | undefined;
73
+ export interface KiroErrorData {
74
+ /** Exception class name, or the legacy free-form `error` string. */
75
+ error: string;
76
+ message?: string;
77
+ kind: KiroErrorKind;
78
+ /** `ThrottlingException.reason` / `ValidationException.reason`, passed through. */
79
+ reason?: string;
80
+ /** `ThrottlingException.retryAfterMilliseconds`. */
81
+ retryAfterMilliseconds?: number;
82
+ }
1
83
  export type KiroWireEvent = {
2
84
  type: "content";
3
85
  data: string;
@@ -36,38 +118,57 @@ export type KiroWireEvent = {
36
118
  } | {
37
119
  type: "usage";
38
120
  data: KiroWireUsage;
121
+ }
122
+ /** `MeteringEvent` — `usage` is a COUNT OF CREDITS, not tokens. */
123
+ | {
124
+ type: "metering";
125
+ data: {
126
+ credits?: number;
127
+ unit?: string;
128
+ unitPlural?: string;
129
+ };
39
130
  } | {
40
131
  type: "error";
132
+ data: KiroErrorData;
133
+ }
134
+ /** A known union member with no consumer yet. Kept distinct from unparseable. */
135
+ | {
136
+ type: "ignored";
41
137
  data: {
42
- error: string;
43
- message?: string;
138
+ key: string;
44
139
  };
45
140
  };
46
141
  /**
47
- * What a `usage` frame reports.
142
+ * Route a decoded stream frame by its modeled `:event-type` key.
48
143
  *
49
- * Observed 2026-09-06 against `claude-sonnet-5` in us-east-1: Kiro does not
50
- * send token counts at all. The frame is a billing record —
51
- * `{unit: "credit", unitPlural: "credits", usage: 0.0659}` — so `usage` is a
52
- * NUMBER, not an object, and reading `inputTokens` off it silently yields
53
- * nothing. Token counts are still parsed because the object form is what the
54
- * underlying services emit and Kiro may yet expose it.
144
+ * `key` is the `ChatResponseStream` union member name from the frame header.
145
+ * An unrecognized key falls back to {@link parseKiroEventByShape} so a member
146
+ * added server-side degrades instead of breaking the stream.
55
147
  *
56
- * Kiro does cache prompts server-side (a repeated prefix billed 0.0350 against
57
- * 0.0659 for a fresh one, and a changed prefix went straight back to 0.0659),
58
- * but it reports no cache token counts and its request schema
59
- * (`additionalProperties: false`) offers no way to ask for caching. The cache
60
- * fields below are therefore read defensively, in the spellings the upstream
61
- * services use, and stay `undefined` when absent rather than becoming `0`.
148
+ * Note: a frame whose `:event-type` is the literal `$unknown` never reaches
149
+ * here. The Smithy marshaller drops any event frame for which the deserializer
150
+ * returns a `$unknown` property, and the deserializer keys its result by the
151
+ * header value, so `$unknown` is discarded one layer up. The fallback below is
152
+ * therefore reached only by a real, unrecognized member name.
62
153
  */
63
- export interface KiroWireUsage {
64
- inputTokens?: number;
65
- outputTokens?: number;
66
- cacheReadTokens?: number;
67
- cacheWriteTokens?: number;
68
- /** Billed amount for the turn — the only usage figure Kiro actually reports. */
69
- credits?: number;
70
- /** Unit the amount is denominated in, e.g. `"credit"`. */
71
- creditUnit?: string;
72
- }
73
- export declare function parseKiroEvent(parsed: Record<string, unknown>): KiroWireEvent | null;
154
+ export declare function parseKiroEvent(key: string, parsed: Record<string, unknown>): KiroWireEvent | null;
155
+ /**
156
+ * Route an `:message-type: exception` frame by its `:exception-type` token.
157
+ *
158
+ * The Smithy marshaller throws whatever the deserializer returns for that key,
159
+ * so this is the only place the modeled exception class, `reason`, and
160
+ * `retryAfterMilliseconds` are still structured. Accepts either token form the
161
+ * service uses (union member name or exception class name). Returns `null` for
162
+ * a token that is not one of the four modeled errors; the caller is responsible
163
+ * for still preserving that name (see `response-stream.ts`), because Smithy's
164
+ * own raw-body fallback only fires for a `$unknown` result this deserializer
165
+ * never produces.
166
+ */
167
+ export declare function parseKiroExceptionFrame(key: string, parsed: Record<string, unknown>): KiroErrorData | null;
168
+ /**
169
+ * Fail-open fallback for frames carrying an unrecognized `:event-type`.
170
+ *
171
+ * Order-dependent field sniffing. Only reachable when the frame's key is not a
172
+ * known `ChatResponseStream` member; modeled frames never reach here.
173
+ */
174
+ export declare function parseKiroEventByShape(parsed: Record<string, unknown>): KiroWireEvent | null;