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 +4 -0
- package/dist/blocks.js +4 -0
- package/dist/blocks.js.map +1 -1
- package/dist/cache-estimator.d.ts +11 -0
- package/dist/cache-estimator.js +61 -0
- package/dist/cache-estimator.js.map +1 -0
- package/dist/endpoints.d.ts +8 -0
- package/dist/endpoints.js +14 -0
- package/dist/endpoints.js.map +1 -1
- package/dist/errors.d.ts +39 -0
- package/dist/errors.js +82 -0
- package/dist/errors.js.map +1 -0
- package/dist/event-parser.d.ts +127 -26
- package/dist/event-parser.js +256 -48
- package/dist/event-parser.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/models.js +4 -1
- package/dist/models.js.map +1 -1
- package/dist/response-assembler.d.ts +29 -3
- package/dist/response-assembler.js +125 -37
- package/dist/response-assembler.js.map +1 -1
- package/dist/response-stream.d.ts +16 -1
- package/dist/response-stream.js +116 -17
- package/dist/response-stream.js.map +1 -1
- package/dist/stream.d.ts +7 -0
- package/dist/stream.js +249 -19
- package/dist/stream.js.map +1 -1
- package/dist/types.d.ts +13 -0
- package/dist/usage-tracking.d.ts +34 -0
- package/dist/usage-tracking.js +88 -0
- package/dist/usage-tracking.js.map +1 -0
- package/package.json +1 -1
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
|
package/dist/blocks.js.map
CHANGED
|
@@ -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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"}
|
package/dist/endpoints.d.ts
CHANGED
|
@@ -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(".");
|
package/dist/endpoints.js.map
CHANGED
|
@@ -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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -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"}
|
package/dist/event-parser.d.ts
CHANGED
|
@@ -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
|
-
|
|
43
|
-
message?: string;
|
|
138
|
+
key: string;
|
|
44
139
|
};
|
|
45
140
|
};
|
|
46
141
|
/**
|
|
47
|
-
*
|
|
142
|
+
* Route a decoded stream frame by its modeled `:event-type` key.
|
|
48
143
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
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
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
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
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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;
|