ns-omp-provider-kiro 0.2.2 → 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/index.js +1535 -1055
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -5,11 +5,20 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __esm = (fn, res) => function __init() {
|
|
9
|
-
|
|
8
|
+
var __esm = (fn, res, err) => function __init() {
|
|
9
|
+
if (err) throw err[0];
|
|
10
|
+
try {
|
|
11
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
12
|
+
} catch (e) {
|
|
13
|
+
throw err = [e], e;
|
|
14
|
+
}
|
|
10
15
|
};
|
|
11
16
|
var __commonJS = (cb, mod) => function __require() {
|
|
12
|
-
|
|
17
|
+
try {
|
|
18
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
19
|
+
} catch (e) {
|
|
20
|
+
throw mod = 0, e;
|
|
21
|
+
}
|
|
13
22
|
};
|
|
14
23
|
var __export = (target, all) => {
|
|
15
24
|
for (var name in all)
|
|
@@ -236,6 +245,12 @@ function getKiroEndpoints(region) {
|
|
|
236
245
|
runtime: `https://runtime.${region}.kiro.dev/`
|
|
237
246
|
};
|
|
238
247
|
}
|
|
248
|
+
function getKiroRegionFromProfileArn(profileArn) {
|
|
249
|
+
if (!profileArn)
|
|
250
|
+
return void 0;
|
|
251
|
+
const region = profileArn.split(":")[3];
|
|
252
|
+
return region && /^[a-z]{2}(?:-[a-z]+)+-\d$/.test(region) ? region : void 0;
|
|
253
|
+
}
|
|
239
254
|
function getKiroRegionFromEndpoint(endpoint) {
|
|
240
255
|
try {
|
|
241
256
|
const [service, region, ...suffix] = new URL(endpoint).hostname.split(".");
|
|
@@ -258,6 +273,7 @@ var init_endpoints = __esm({
|
|
|
258
273
|
"ap-southeast-1": "us-east-1",
|
|
259
274
|
"ap-southeast-2": "us-east-1",
|
|
260
275
|
"ap-northeast-1": "us-east-1",
|
|
276
|
+
"ap-northeast-2": "us-east-1",
|
|
261
277
|
"ap-south-1": "us-east-1",
|
|
262
278
|
"eu-west-1": "eu-central-1",
|
|
263
279
|
"eu-west-2": "eu-central-1",
|
|
@@ -633,779 +649,337 @@ var init_kiro_ide = __esm({
|
|
|
633
649
|
}
|
|
634
650
|
});
|
|
635
651
|
|
|
636
|
-
// ../kiro-core/dist/
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
applyEffortLadder: () => applyEffortLadder,
|
|
644
|
-
getCachedModels: () => getCachedModels,
|
|
645
|
-
isCacheStale: () => isCacheStale,
|
|
646
|
-
kiroModels: () => kiroModels,
|
|
647
|
-
loadCachedModelIds: () => loadCachedModelIds,
|
|
648
|
-
mapKiroCatalogModels: () => mapKiroCatalogModels,
|
|
649
|
-
resolveApiRegion: () => resolveApiRegion,
|
|
650
|
-
resolveKiroModel: () => resolveKiroModel,
|
|
651
|
-
updateKiroModelsCache: () => updateKiroModelsCache
|
|
652
|
-
});
|
|
653
|
-
import { randomUUID } from "node:crypto";
|
|
654
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
655
|
-
import { homedir as homedir4 } from "node:os";
|
|
656
|
-
import { join as join4 } from "node:path";
|
|
657
|
-
function isRecord2(value) {
|
|
658
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
659
|
-
}
|
|
660
|
-
function isPositiveNumber(value) {
|
|
661
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
662
|
-
}
|
|
663
|
-
function isEffortList(value) {
|
|
664
|
-
return Array.isArray(value) && value.length > 0 && value.every((effort) => KIRO_EFFORT_ORDER.includes(effort));
|
|
652
|
+
// ../kiro-core/dist/oauth.js
|
|
653
|
+
function kiroUserAgent(service, sdkVersion) {
|
|
654
|
+
return {
|
|
655
|
+
"User-Agent": `aws-sdk-js/3.714.0 os/macos/24.3.0 lang/js md/nodejs/22.14.0 api/${service}/3.714.0 exec-env/kiro-cli/2.7.0 m/E`,
|
|
656
|
+
"amz-sdk-invocation-id": "00000000-0000-0000-0000-000000000000",
|
|
657
|
+
"amz-sdk-request": `attempt=1; max=${sdkVersion}`
|
|
658
|
+
};
|
|
665
659
|
}
|
|
666
|
-
function
|
|
667
|
-
|
|
660
|
+
function kiroAuthHeaders(token) {
|
|
661
|
+
const headers = { Authorization: `Bearer ${token}` };
|
|
662
|
+
if (isApiKey(token))
|
|
663
|
+
headers.tokentype = "API_KEY";
|
|
664
|
+
return headers;
|
|
668
665
|
}
|
|
669
|
-
function
|
|
670
|
-
|
|
671
|
-
return false;
|
|
672
|
-
const cost = value.cost;
|
|
673
|
-
const input = value.input;
|
|
674
|
-
const schema = value.additionalModelRequestFieldsSchema;
|
|
675
|
-
const tokenLimits = value.tokenLimits;
|
|
676
|
-
return typeof value.id === "string" && value.id.length > 0 && typeof value.kiroModelId === "string" && value.kiroModelId.length > 0 && typeof value.name === "string" && value.name.length > 0 && typeof value.reasoning === "boolean" && Array.isArray(input) && input.length > 0 && input.every((modality) => modality === "text" || modality === "image") && isRecord2(cost) && typeof cost.input === "number" && typeof cost.output === "number" && typeof cost.cacheRead === "number" && typeof cost.cacheWrite === "number" && isPositiveNumber(value.contextWindow) && isPositiveNumber(value.maxTokens) && (value.efforts === void 0 || isEffortList(value.efforts)) && (value.effortMap === void 0 || isEffortMap(value.effortMap)) && (schema === void 0 || isRecord2(schema)) && (tokenLimits === void 0 || isRecord2(tokenLimits)) && (value.firstTokenTimeout === void 0 || isPositiveNumber(value.firstTokenTimeout)) && (value.rateMultiplier === void 0 || isPositiveNumber(value.rateMultiplier)) && (value.rateUnit === void 0 || typeof value.rateUnit === "string");
|
|
666
|
+
function isApiKey(token) {
|
|
667
|
+
return token.startsWith("ksk_");
|
|
677
668
|
}
|
|
678
|
-
function
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
value = JSON.parse(raw);
|
|
682
|
-
} catch {
|
|
683
|
-
return void 0;
|
|
684
|
-
}
|
|
685
|
-
if (!isRecord2(value) || value.version !== KIRO_MANAGEMENT_CACHE_VERSION || value.source !== KIRO_MANAGEMENT_CACHE_SOURCE || !isRecord2(value.regions)) {
|
|
686
|
-
return void 0;
|
|
669
|
+
async function loginKiroWithApiKey(apiKey, onProgress) {
|
|
670
|
+
if (!apiKey.startsWith("ksk_")) {
|
|
671
|
+
throw new Error("Invalid API key format. Kiro API keys start with 'ksk_'.");
|
|
687
672
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
673
|
+
onProgress?.("Validating API key...");
|
|
674
|
+
const region = "us-east-1";
|
|
675
|
+
const managementUrl = `https://management.${resolveApiRegion(region)}.kiro.dev/`;
|
|
676
|
+
const response = await fetch(managementUrl, {
|
|
677
|
+
method: "POST",
|
|
678
|
+
headers: {
|
|
679
|
+
"Content-Type": "application/x-amz-json-1.0",
|
|
680
|
+
"X-Amz-Target": "AmazonCodeWhispererService.GetProfile",
|
|
681
|
+
...kiroAuthHeaders(apiKey),
|
|
682
|
+
...kiroUserAgent("codewhispererruntime", "F,C")
|
|
683
|
+
},
|
|
684
|
+
body: "{}"
|
|
685
|
+
});
|
|
686
|
+
if (!response.ok) {
|
|
687
|
+
let detail = "";
|
|
688
|
+
try {
|
|
689
|
+
detail = await response.text();
|
|
690
|
+
} catch {
|
|
691
|
+
detail = "";
|
|
692
692
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
if (modelIds.has(model.id))
|
|
696
|
-
return void 0;
|
|
697
|
-
modelIds.add(model.id);
|
|
693
|
+
if (response.status === 401 || response.status === 403 || /Invalid token/i.test(detail)) {
|
|
694
|
+
throw new Error("API key was rejected by Kiro. Check that the key is valid and not expired.");
|
|
698
695
|
}
|
|
699
|
-
|
|
696
|
+
throw new Error(`Kiro GetProfile failed: ${response.status} ${response.statusText} ${detail}`.trim());
|
|
700
697
|
}
|
|
698
|
+
const data = await response.json();
|
|
699
|
+
const profileArn = data.profile?.arn;
|
|
701
700
|
return {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
701
|
+
access: apiKey,
|
|
702
|
+
refresh: `${apiKey}|apikey`,
|
|
703
|
+
expires: Date.now() + 365 * 24 * 60 * 60 * 1e3,
|
|
704
|
+
clientId: "",
|
|
705
|
+
clientSecret: "",
|
|
706
|
+
region,
|
|
707
|
+
authMethod: "apikey",
|
|
708
|
+
...profileArn ? { profileArn } : {}
|
|
705
709
|
};
|
|
706
710
|
}
|
|
707
|
-
function
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
711
|
+
async function refreshKiroToken(credentials) {
|
|
712
|
+
const refreshed = await refreshKiroTokenInternal(credentials);
|
|
713
|
+
if (!process.env.VITEST) {
|
|
714
|
+
try {
|
|
715
|
+
const { updateKiroModelsCache: updateKiroModelsCache2 } = await Promise.resolve().then(() => (init_models(), models_exports));
|
|
716
|
+
const region = resolveApiRegion(refreshed.region);
|
|
717
|
+
updateKiroModelsCache2(refreshed.access, region, refreshed.profileArn).catch((error2) => {
|
|
718
|
+
console.warn(`[kiro-core] Failed to refresh Kiro model catalog in ${region}: ${formatSafeError(error2)}`);
|
|
719
|
+
});
|
|
720
|
+
} catch (error2) {
|
|
721
|
+
console.warn(`[kiro-core] Failed to start Kiro model catalog refresh: ${formatSafeError(error2)}`);
|
|
722
|
+
}
|
|
714
723
|
}
|
|
724
|
+
return refreshed;
|
|
715
725
|
}
|
|
716
|
-
function
|
|
717
|
-
const
|
|
726
|
+
async function refreshKiroTokenInternal(credentials) {
|
|
727
|
+
const { getKiroCliCredentials: getKiroCliCredentials2, getKiroCliCredentialsAllowExpired: getKiroCliCredentialsAllowExpired2, saveKiroCliCredentials: saveKiroCliCredentials2, getKiroCliSocialToken: getKiroCliSocialToken2, getKiroCliSocialTokenAllowExpired: getKiroCliSocialTokenAllowExpired2 } = await Promise.resolve().then(() => (init_kiro_cli(), kiro_cli_exports));
|
|
728
|
+
const credentialAuthMethod = credentials.authMethod ?? (credentials.refresh.split("|").at(-1) === "desktop" ? "desktop" : "idc");
|
|
729
|
+
const getValidCliCredentials = () => {
|
|
730
|
+
if (credentialAuthMethod === "desktop")
|
|
731
|
+
return getKiroCliSocialToken2();
|
|
732
|
+
const cliCreds = getKiroCliCredentials2();
|
|
733
|
+
return cliCreds?.authMethod === "idc" ? cliCreds : void 0;
|
|
734
|
+
};
|
|
735
|
+
const getExpiredCliCredentials = () => {
|
|
736
|
+
if (credentialAuthMethod === "desktop")
|
|
737
|
+
return getKiroCliSocialTokenAllowExpired2();
|
|
738
|
+
const cliCreds = getKiroCliCredentialsAllowExpired2();
|
|
739
|
+
return cliCreds?.authMethod === "idc" ? cliCreds : void 0;
|
|
740
|
+
};
|
|
741
|
+
if (credentials.authMethod === "apikey" || isApiKey(credentials.access))
|
|
742
|
+
return credentials;
|
|
743
|
+
if (credentialAuthMethod === "idc") {
|
|
744
|
+
const ideCreds = getKiroIdeCredentials();
|
|
745
|
+
if (ideCreds)
|
|
746
|
+
return ideCreds;
|
|
747
|
+
}
|
|
748
|
+
const preCheckCreds = getValidCliCredentials();
|
|
749
|
+
if (preCheckCreds)
|
|
750
|
+
return preCheckCreds;
|
|
718
751
|
try {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
752
|
+
const refreshed = await refreshKiroTokenDirect(credentials);
|
|
753
|
+
saveKiroCliCredentials2(refreshed);
|
|
754
|
+
return refreshed;
|
|
755
|
+
} catch (refreshError) {
|
|
756
|
+
const retryCreds = getValidCliCredentials();
|
|
757
|
+
if (retryCreds)
|
|
758
|
+
return retryCreds;
|
|
759
|
+
const expiredCliCreds = getExpiredCliCredentials();
|
|
760
|
+
if (expiredCliCreds && expiredCliCreds.refresh !== credentials.refresh) {
|
|
761
|
+
try {
|
|
762
|
+
const refreshedFromCli = await refreshKiroTokenDirect(expiredCliCreds);
|
|
763
|
+
saveKiroCliCredentials2(refreshedFromCli);
|
|
764
|
+
return refreshedFromCli;
|
|
765
|
+
} catch {
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
const actualExpiry = credentials.expires + EXPIRES_BUFFER_MS;
|
|
769
|
+
if (credentials.access && Date.now() < actualExpiry) {
|
|
770
|
+
return { ...credentials, expires: actualExpiry };
|
|
771
|
+
}
|
|
772
|
+
throw refreshError;
|
|
723
773
|
}
|
|
724
774
|
}
|
|
725
|
-
function
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
if (
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
throw new Error(`Kiro management catalog model ${model.modelId} has an invalid request-fields schema`);
|
|
756
|
-
}
|
|
757
|
-
const tokenLimits = model.tokenLimits;
|
|
758
|
-
if (tokenLimits !== void 0 && !isRecord2(tokenLimits)) {
|
|
759
|
-
throw new Error(`Kiro management catalog model ${model.modelId} has invalid token limits`);
|
|
760
|
-
}
|
|
761
|
-
if (tokenLimits && (tokenLimits.maxInputTokens !== void 0 && !isPositiveNumber(tokenLimits.maxInputTokens) || tokenLimits.maxOutputTokens !== void 0 && !isPositiveNumber(tokenLimits.maxOutputTokens))) {
|
|
762
|
-
throw new Error(`Kiro management catalog model ${model.modelId} has invalid token limits`);
|
|
775
|
+
async function refreshKiroTokenDirect(credentials) {
|
|
776
|
+
const parts = credentials.refresh.split("|");
|
|
777
|
+
const refreshToken = parts[0] ?? "";
|
|
778
|
+
const authMethod = parts[parts.length - 1] ?? "idc";
|
|
779
|
+
const region = credentials.region || "us-east-1";
|
|
780
|
+
if (authMethod === "apikey")
|
|
781
|
+
return credentials;
|
|
782
|
+
if (authMethod === "desktop") {
|
|
783
|
+
const url = KIRO_DESKTOP_REFRESH_URL.replace("{region}", region);
|
|
784
|
+
const response2 = await fetch(url, {
|
|
785
|
+
method: "POST",
|
|
786
|
+
headers: { "Content-Type": "application/json", "User-Agent": KIRO_DESKTOP_USER_AGENT },
|
|
787
|
+
body: JSON.stringify({ refreshToken })
|
|
788
|
+
});
|
|
789
|
+
if (!response2.ok)
|
|
790
|
+
throw new Error(`Desktop token refresh failed: ${response2.status}`);
|
|
791
|
+
const data2 = await response2.json();
|
|
792
|
+
if (!data2.accessToken)
|
|
793
|
+
throw new Error("Desktop token refresh: missing accessToken");
|
|
794
|
+
return {
|
|
795
|
+
refresh: `${data2.refreshToken || refreshToken}|desktop`,
|
|
796
|
+
access: data2.accessToken,
|
|
797
|
+
expires: Date.now() + data2.expiresIn * 1e3 - EXPIRES_BUFFER_MS,
|
|
798
|
+
clientId: "",
|
|
799
|
+
clientSecret: "",
|
|
800
|
+
region,
|
|
801
|
+
authMethod: "desktop",
|
|
802
|
+
profileArn: data2.profileArn || credentials.profileArn,
|
|
803
|
+
startUrl: credentials.startUrl
|
|
804
|
+
};
|
|
763
805
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
const
|
|
785
|
-
|
|
806
|
+
if (authMethod === "external-idp") {
|
|
807
|
+
const idpClientId = parts[1] ?? "";
|
|
808
|
+
const tokenEndpoint = parts[2] ?? "";
|
|
809
|
+
if (!tokenEndpoint)
|
|
810
|
+
throw new Error("External IdP token refresh: missing token endpoint");
|
|
811
|
+
const response2 = await fetch(tokenEndpoint, {
|
|
812
|
+
method: "POST",
|
|
813
|
+
headers: {
|
|
814
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
815
|
+
Accept: "application/json",
|
|
816
|
+
"User-Agent": "kiro-core"
|
|
817
|
+
},
|
|
818
|
+
body: new URLSearchParams({
|
|
819
|
+
grant_type: "refresh_token",
|
|
820
|
+
client_id: idpClientId,
|
|
821
|
+
refresh_token: refreshToken
|
|
822
|
+
}).toString()
|
|
823
|
+
});
|
|
824
|
+
if (!response2.ok)
|
|
825
|
+
throw new Error(`External IdP token refresh failed: ${response2.status}`);
|
|
826
|
+
const data2 = await response2.json();
|
|
827
|
+
if (!data2.access_token)
|
|
828
|
+
throw new Error("External IdP token refresh: missing access_token");
|
|
829
|
+
const expiresIn = typeof data2.expires_in === "number" ? data2.expires_in : 3600;
|
|
786
830
|
return {
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
831
|
+
refresh: `${data2.refresh_token || refreshToken}|${idpClientId}|${tokenEndpoint}|external-idp`,
|
|
832
|
+
access: data2.access_token,
|
|
833
|
+
expires: Date.now() + expiresIn * 1e3 - EXPIRES_BUFFER_MS,
|
|
834
|
+
clientId: idpClientId,
|
|
835
|
+
clientSecret: "",
|
|
790
836
|
region,
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
// decides. The fallback tier feeds the ladders, not this flag.
|
|
794
|
-
reasoning: schema !== void 0 && effortConfig !== void 0 || schema === void 0 && hasReasoningFamilyFallback(id),
|
|
795
|
-
...applyEffortLadder(effortConfig),
|
|
796
|
-
input: existing ? [...existing.input] : hasVerifiedImageInput(kiroModelId) ? ["text", "image"] : ["text"],
|
|
797
|
-
...id.startsWith("claude-") ? { recoverTextToolCalls: false } : {},
|
|
798
|
-
cost: ZERO_COST,
|
|
799
|
-
...rate ? { rateMultiplier: rate.multiplier, ...rate.unit ? { rateUnit: rate.unit } : {} } : {},
|
|
800
|
-
contextWindow: tokenLimits?.maxInputTokens ?? DEFAULT_CONTEXT_WINDOW,
|
|
801
|
-
maxTokens: tokenLimits?.maxOutputTokens ?? DEFAULT_MAX_TOKENS,
|
|
802
|
-
...existing?.firstTokenTimeout ? { firstTokenTimeout: existing.firstTokenTimeout } : {},
|
|
803
|
-
...schema ? { additionalModelRequestFieldsSchema: schema } : {},
|
|
804
|
-
...tokenLimits ? { tokenLimits } : {}
|
|
837
|
+
authMethod: "external-idp",
|
|
838
|
+
profileArn: credentials.profileArn
|
|
805
839
|
};
|
|
840
|
+
}
|
|
841
|
+
const clientId = parts[1] ?? "";
|
|
842
|
+
const clientSecret = parts[2] ?? "";
|
|
843
|
+
const ssoEndpoint = `https://oidc.${region}.amazonaws.com`;
|
|
844
|
+
const response = await fetch(`${ssoEndpoint}/token`, {
|
|
845
|
+
method: "POST",
|
|
846
|
+
headers: { "Content-Type": "application/json", ...kiroUserAgent("ssooidc", "E") },
|
|
847
|
+
body: JSON.stringify({ clientId, clientSecret, refreshToken, grantType: "refresh_token" })
|
|
806
848
|
});
|
|
849
|
+
if (!response.ok)
|
|
850
|
+
throw new Error(`Token refresh failed: ${response.status}`);
|
|
851
|
+
const data = await response.json();
|
|
852
|
+
return {
|
|
853
|
+
refresh: `${data.refreshToken}|${clientId}|${clientSecret}|idc`,
|
|
854
|
+
access: data.accessToken,
|
|
855
|
+
expires: Date.now() + data.expiresIn * 1e3 - EXPIRES_BUFFER_MS,
|
|
856
|
+
clientId,
|
|
857
|
+
clientSecret,
|
|
858
|
+
region,
|
|
859
|
+
authMethod: "idc",
|
|
860
|
+
profileArn: credentials.profileArn,
|
|
861
|
+
startUrl: credentials.startUrl,
|
|
862
|
+
isEnterprise: credentials.isEnterprise
|
|
863
|
+
};
|
|
807
864
|
}
|
|
808
|
-
function
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
}
|
|
865
|
+
async function resolveKiroCredentials() {
|
|
866
|
+
const { getKiroCliCredentials: getKiroCliCredentials2, getKiroCliCredentialsAllowExpired: getKiroCliCredentialsAllowExpired2 } = await Promise.resolve().then(() => (init_kiro_cli(), kiro_cli_exports));
|
|
867
|
+
const fresh = getKiroCliCredentials2() ?? getKiroIdeCredentials();
|
|
868
|
+
if (fresh)
|
|
869
|
+
return fresh;
|
|
870
|
+
const stale = getKiroCliCredentialsAllowExpired2();
|
|
871
|
+
if (!stale)
|
|
872
|
+
return void 0;
|
|
873
|
+
return refreshKiroToken(stale);
|
|
818
874
|
}
|
|
819
|
-
|
|
820
|
-
|
|
875
|
+
var KIRO_DESKTOP_REFRESH_URL, EXPIRES_BUFFER_MS, KIRO_DESKTOP_USER_AGENT;
|
|
876
|
+
var init_oauth = __esm({
|
|
877
|
+
"../kiro-core/dist/oauth.js"() {
|
|
878
|
+
"use strict";
|
|
879
|
+
init_debug();
|
|
880
|
+
init_endpoints();
|
|
881
|
+
init_kiro_ide();
|
|
882
|
+
KIRO_DESKTOP_REFRESH_URL = "https://prod.{region}.auth.desktop.kiro.dev/refreshToken";
|
|
883
|
+
EXPIRES_BUFFER_MS = 5 * 60 * 1e3;
|
|
884
|
+
KIRO_DESKTOP_USER_AGENT = "Kiro-Desktop/0.2.13 (darwin; arm64)";
|
|
885
|
+
}
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
// ../kiro-core/dist/token-type.js
|
|
889
|
+
function isExternalIdpAccessToken(accessToken) {
|
|
890
|
+
if (typeof accessToken !== "string")
|
|
891
|
+
return false;
|
|
892
|
+
const segments = accessToken.split(".");
|
|
893
|
+
if (segments.length !== 3)
|
|
894
|
+
return false;
|
|
895
|
+
const payloadSegment = segments[1];
|
|
896
|
+
if (!payloadSegment)
|
|
897
|
+
return false;
|
|
898
|
+
try {
|
|
899
|
+
const payload = JSON.parse(Buffer.from(payloadSegment.replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf-8"));
|
|
900
|
+
return payload.aud === EXTERNAL_IDP_AUDIENCE;
|
|
901
|
+
} catch {
|
|
902
|
+
return false;
|
|
903
|
+
}
|
|
821
904
|
}
|
|
822
|
-
function
|
|
823
|
-
|
|
824
|
-
refreshKnownModelIds(cache);
|
|
825
|
-
const models = cache?.regions[region]?.models ?? kiroModels;
|
|
826
|
-
let changed = false;
|
|
827
|
-
const corrected = models.map((model) => {
|
|
828
|
-
const result = applyVerifiedCapabilities(model);
|
|
829
|
-
if (result !== model)
|
|
830
|
-
changed = true;
|
|
831
|
-
return result;
|
|
832
|
-
});
|
|
833
|
-
return changed ? corrected : models;
|
|
905
|
+
function kiroTokenTypeHeaders(accessToken) {
|
|
906
|
+
return isExternalIdpAccessToken(accessToken) ? { tokentype: "EXTERNAL_IDP" } : {};
|
|
834
907
|
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
908
|
+
var EXTERNAL_IDP_AUDIENCE;
|
|
909
|
+
var init_token_type = __esm({
|
|
910
|
+
"../kiro-core/dist/token-type.js"() {
|
|
911
|
+
"use strict";
|
|
912
|
+
EXTERNAL_IDP_AUDIENCE = "api://kiro";
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
// ../kiro-core/dist/management.js
|
|
917
|
+
import { createHash } from "node:crypto";
|
|
918
|
+
function candidateManagementRegions(primary) {
|
|
919
|
+
const seen = /* @__PURE__ */ new Set([primary]);
|
|
920
|
+
const candidates = [primary];
|
|
921
|
+
for (const region of CANONICAL_MANAGEMENT_REGIONS) {
|
|
922
|
+
if (!seen.has(region)) {
|
|
923
|
+
seen.add(region);
|
|
924
|
+
candidates.push(region);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return candidates;
|
|
838
928
|
}
|
|
839
|
-
async function
|
|
840
|
-
const
|
|
841
|
-
const
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
929
|
+
async function requestManagement(auth, operation, path, method, body) {
|
|
930
|
+
const url = new URL(path, getKiroEndpoints(auth.region).management);
|
|
931
|
+
const request = {
|
|
932
|
+
method,
|
|
933
|
+
headers: {
|
|
934
|
+
Accept: "application/json",
|
|
935
|
+
...kiroAuthHeaders(auth.accessToken),
|
|
936
|
+
...kiroTokenTypeHeaders(auth.accessToken)
|
|
937
|
+
}
|
|
846
938
|
};
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
939
|
+
if (method === "GET") {
|
|
940
|
+
for (const [name, value] of Object.entries(body)) {
|
|
941
|
+
if (value !== void 0)
|
|
942
|
+
url.searchParams.set(name, String(value));
|
|
943
|
+
}
|
|
944
|
+
} else {
|
|
945
|
+
request.headers = { ...request.headers, "Content-Type": "application/json" };
|
|
946
|
+
request.body = JSON.stringify(body);
|
|
947
|
+
}
|
|
948
|
+
let response;
|
|
949
|
+
try {
|
|
950
|
+
response = await fetch(url.toString(), request);
|
|
951
|
+
} catch (error2) {
|
|
952
|
+
throw new Error(`Kiro management ${operation} request failed in ${auth.region}`, { cause: error2 });
|
|
953
|
+
}
|
|
954
|
+
return parseManagementResponse(response, operation, auth.region);
|
|
850
955
|
}
|
|
851
|
-
function
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
956
|
+
function profileCacheKey(auth) {
|
|
957
|
+
const tokenHash = createHash("sha256").update(auth.accessToken).digest("base64url");
|
|
958
|
+
return `${auth.region}:${tokenHash}`;
|
|
959
|
+
}
|
|
960
|
+
async function getApiKeyProfileArn(accessToken) {
|
|
961
|
+
const operation = "GetProfile";
|
|
962
|
+
let response;
|
|
963
|
+
try {
|
|
964
|
+
response = await fetch(getKiroEndpoints(API_KEY_REGION).management, {
|
|
965
|
+
method: "POST",
|
|
966
|
+
headers: {
|
|
967
|
+
"Content-Type": "application/x-amz-json-1.0",
|
|
968
|
+
"X-Amz-Target": GET_PROFILE_TARGET,
|
|
969
|
+
...kiroAuthHeaders(accessToken),
|
|
970
|
+
...kiroUserAgent("codewhispererruntime", "F,C")
|
|
971
|
+
},
|
|
972
|
+
body: "{}"
|
|
973
|
+
});
|
|
974
|
+
} catch (error2) {
|
|
975
|
+
throw new Error(`Kiro management ${operation} request failed in ${API_KEY_REGION}`, { cause: error2 });
|
|
858
976
|
}
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
loadCachedModelIds();
|
|
864
|
-
if (!KIRO_MODEL_IDS.has(normalizedId)) {
|
|
865
|
-
throw new Error(`Unknown Kiro model ID: ${modelId}`);
|
|
977
|
+
const parsed = await parseManagementResponse(response, operation, API_KEY_REGION);
|
|
978
|
+
const arn = parsed.profile?.arn;
|
|
979
|
+
if (!arn) {
|
|
980
|
+
throw new Error(`Kiro management ${operation} returned no profile in ${API_KEY_REGION}`);
|
|
866
981
|
}
|
|
867
|
-
return
|
|
868
|
-
}
|
|
869
|
-
var KIRO_MANAGEMENT_CACHE_VERSION, KIRO_MANAGEMENT_CACHE_SOURCE, KIRO_MANAGEMENT_CACHE_PATH, CACHE_MAX_AGE_MS, DEFAULT_CONTEXT_WINDOW, DEFAULT_MAX_TOKENS, ZERO_COST, REASONING_FAMILY_MARKERS, VERIFIED_IMAGE_MODEL_IDS, bootstrapKiroModels, kiroModels, BOOTSTRAP_KIRO_MODEL_IDS, KIRO_MODEL_IDS;
|
|
870
|
-
var init_models = __esm({
|
|
871
|
-
"../kiro-core/dist/models.js"() {
|
|
872
|
-
"use strict";
|
|
873
|
-
init_effort();
|
|
874
|
-
init_kiro_cli();
|
|
875
|
-
init_management();
|
|
876
|
-
init_types();
|
|
877
|
-
init_endpoints();
|
|
878
|
-
KIRO_MANAGEMENT_CACHE_VERSION = 1;
|
|
879
|
-
KIRO_MANAGEMENT_CACHE_SOURCE = "ns-kiro-provider-management";
|
|
880
|
-
KIRO_MANAGEMENT_CACHE_PATH = join4(homedir4(), ".ns-kiro-provider-models-cache.json");
|
|
881
|
-
CACHE_MAX_AGE_MS = 36e5;
|
|
882
|
-
DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
883
|
-
DEFAULT_MAX_TOKENS = 8192;
|
|
884
|
-
ZERO_COST = Object.freeze({ input: 0, output: 0, cacheRead: 0, cacheWrite: 0 });
|
|
885
|
-
REASONING_FAMILY_MARKERS = ["opus", "sonnet", "fable", "coder", "deepseek", "gpt", "glm", "qwen"];
|
|
886
|
-
VERIFIED_IMAGE_MODEL_IDS = /* @__PURE__ */ new Set(["gpt-5.6-luna"]);
|
|
887
|
-
bootstrapKiroModels = [
|
|
888
|
-
{
|
|
889
|
-
id: "claude-opus-5",
|
|
890
|
-
kiroModelId: "claude-opus-5",
|
|
891
|
-
name: "Claude Opus 5",
|
|
892
|
-
reasoning: true,
|
|
893
|
-
input: ["text", "image"],
|
|
894
|
-
cost: ZERO_COST,
|
|
895
|
-
contextWindow: 1e6,
|
|
896
|
-
maxTokens: 128e3,
|
|
897
|
-
firstTokenTimeout: 18e4
|
|
898
|
-
},
|
|
899
|
-
{
|
|
900
|
-
id: "claude-opus-4-8",
|
|
901
|
-
kiroModelId: "claude-opus-4.8",
|
|
902
|
-
name: "Claude Opus 4.8",
|
|
903
|
-
reasoning: true,
|
|
904
|
-
input: ["text", "image"],
|
|
905
|
-
cost: ZERO_COST,
|
|
906
|
-
contextWindow: 1e6,
|
|
907
|
-
maxTokens: 128e3,
|
|
908
|
-
firstTokenTimeout: 18e4
|
|
909
|
-
},
|
|
910
|
-
{
|
|
911
|
-
id: "claude-opus-4-7",
|
|
912
|
-
kiroModelId: "claude-opus-4.7",
|
|
913
|
-
name: "Claude Opus 4.7",
|
|
914
|
-
reasoning: true,
|
|
915
|
-
input: ["text", "image"],
|
|
916
|
-
cost: ZERO_COST,
|
|
917
|
-
contextWindow: 1e6,
|
|
918
|
-
maxTokens: 128e3,
|
|
919
|
-
firstTokenTimeout: 18e4
|
|
920
|
-
},
|
|
921
|
-
{
|
|
922
|
-
id: "claude-opus-4-6",
|
|
923
|
-
kiroModelId: "claude-opus-4.6",
|
|
924
|
-
name: "Claude Opus 4.6",
|
|
925
|
-
reasoning: true,
|
|
926
|
-
input: ["text", "image"],
|
|
927
|
-
cost: ZERO_COST,
|
|
928
|
-
contextWindow: 1e6,
|
|
929
|
-
maxTokens: 32768
|
|
930
|
-
},
|
|
931
|
-
{
|
|
932
|
-
id: "claude-opus-4-5",
|
|
933
|
-
kiroModelId: "claude-opus-4.5",
|
|
934
|
-
name: "Claude Opus 4.5",
|
|
935
|
-
reasoning: true,
|
|
936
|
-
input: ["text", "image"],
|
|
937
|
-
cost: ZERO_COST,
|
|
938
|
-
contextWindow: 2e5,
|
|
939
|
-
maxTokens: 64e3
|
|
940
|
-
},
|
|
941
|
-
{
|
|
942
|
-
id: "claude-sonnet-5",
|
|
943
|
-
kiroModelId: "claude-sonnet-5",
|
|
944
|
-
name: "Claude Sonnet 5",
|
|
945
|
-
reasoning: true,
|
|
946
|
-
input: ["text", "image"],
|
|
947
|
-
cost: ZERO_COST,
|
|
948
|
-
contextWindow: 1e6,
|
|
949
|
-
maxTokens: 65536
|
|
950
|
-
},
|
|
951
|
-
{
|
|
952
|
-
id: "claude-sonnet-4-6",
|
|
953
|
-
kiroModelId: "claude-sonnet-4.6",
|
|
954
|
-
name: "Claude Sonnet 4.6",
|
|
955
|
-
reasoning: true,
|
|
956
|
-
input: ["text", "image"],
|
|
957
|
-
cost: ZERO_COST,
|
|
958
|
-
contextWindow: 1e6,
|
|
959
|
-
maxTokens: 65536
|
|
960
|
-
},
|
|
961
|
-
{
|
|
962
|
-
id: "claude-sonnet-4-5",
|
|
963
|
-
kiroModelId: "claude-sonnet-4.5",
|
|
964
|
-
name: "Claude Sonnet 4.5",
|
|
965
|
-
reasoning: true,
|
|
966
|
-
input: ["text", "image"],
|
|
967
|
-
cost: ZERO_COST,
|
|
968
|
-
contextWindow: 2e5,
|
|
969
|
-
maxTokens: 65536
|
|
970
|
-
},
|
|
971
|
-
{
|
|
972
|
-
id: "claude-sonnet-4",
|
|
973
|
-
kiroModelId: "claude-sonnet-4",
|
|
974
|
-
name: "Claude Sonnet 4",
|
|
975
|
-
reasoning: true,
|
|
976
|
-
input: ["text", "image"],
|
|
977
|
-
cost: ZERO_COST,
|
|
978
|
-
contextWindow: 2e5,
|
|
979
|
-
maxTokens: 65536
|
|
980
|
-
},
|
|
981
|
-
{
|
|
982
|
-
id: "claude-haiku-4-5",
|
|
983
|
-
kiroModelId: "claude-haiku-4.5",
|
|
984
|
-
name: "Claude Haiku 4.5",
|
|
985
|
-
reasoning: false,
|
|
986
|
-
input: ["text", "image"],
|
|
987
|
-
cost: ZERO_COST,
|
|
988
|
-
contextWindow: 2e5,
|
|
989
|
-
maxTokens: 65536
|
|
990
|
-
},
|
|
991
|
-
{
|
|
992
|
-
id: "claude-fable-5",
|
|
993
|
-
kiroModelId: "claude-fable-5",
|
|
994
|
-
name: "Claude Fable 5",
|
|
995
|
-
reasoning: true,
|
|
996
|
-
input: ["text", "image"],
|
|
997
|
-
cost: ZERO_COST,
|
|
998
|
-
contextWindow: 1e6,
|
|
999
|
-
maxTokens: 65536
|
|
1000
|
-
},
|
|
1001
|
-
{
|
|
1002
|
-
id: "gpt-5-6-luna",
|
|
1003
|
-
kiroModelId: "gpt-5.6-luna",
|
|
1004
|
-
name: "GPT-5.6 Luna",
|
|
1005
|
-
reasoning: true,
|
|
1006
|
-
input: ["text", "image"],
|
|
1007
|
-
cost: ZERO_COST,
|
|
1008
|
-
contextWindow: 272e3,
|
|
1009
|
-
maxTokens: 128e3
|
|
1010
|
-
},
|
|
1011
|
-
{
|
|
1012
|
-
id: "gpt-5-6-sol",
|
|
1013
|
-
kiroModelId: "gpt-5.6-sol",
|
|
1014
|
-
name: "GPT-5.6 Sol",
|
|
1015
|
-
reasoning: true,
|
|
1016
|
-
input: ["text"],
|
|
1017
|
-
cost: ZERO_COST,
|
|
1018
|
-
contextWindow: 272e3,
|
|
1019
|
-
maxTokens: 128e3
|
|
1020
|
-
},
|
|
1021
|
-
{
|
|
1022
|
-
id: "gpt-5-6-terra",
|
|
1023
|
-
kiroModelId: "gpt-5.6-terra",
|
|
1024
|
-
name: "GPT-5.6 Terra",
|
|
1025
|
-
reasoning: true,
|
|
1026
|
-
input: ["text"],
|
|
1027
|
-
cost: ZERO_COST,
|
|
1028
|
-
contextWindow: 272e3,
|
|
1029
|
-
maxTokens: 128e3
|
|
1030
|
-
},
|
|
1031
|
-
{
|
|
1032
|
-
id: "deepseek-3-2",
|
|
1033
|
-
kiroModelId: "deepseek-3.2",
|
|
1034
|
-
name: "DeepSeek 3.2",
|
|
1035
|
-
reasoning: true,
|
|
1036
|
-
input: ["text"],
|
|
1037
|
-
cost: ZERO_COST,
|
|
1038
|
-
contextWindow: 164e3,
|
|
1039
|
-
maxTokens: 8192
|
|
1040
|
-
},
|
|
1041
|
-
{
|
|
1042
|
-
id: "minimax-m2-5",
|
|
1043
|
-
kiroModelId: "minimax-m2.5",
|
|
1044
|
-
name: "MiniMax M2.5",
|
|
1045
|
-
reasoning: false,
|
|
1046
|
-
input: ["text"],
|
|
1047
|
-
cost: ZERO_COST,
|
|
1048
|
-
contextWindow: 196e3,
|
|
1049
|
-
maxTokens: 8192
|
|
1050
|
-
},
|
|
1051
|
-
{
|
|
1052
|
-
id: "minimax-m2-1",
|
|
1053
|
-
kiroModelId: "minimax-m2.1",
|
|
1054
|
-
name: "MiniMax M2.1",
|
|
1055
|
-
reasoning: false,
|
|
1056
|
-
input: ["text"],
|
|
1057
|
-
cost: ZERO_COST,
|
|
1058
|
-
contextWindow: 196e3,
|
|
1059
|
-
maxTokens: 8192
|
|
1060
|
-
},
|
|
1061
|
-
{
|
|
1062
|
-
id: "glm-5",
|
|
1063
|
-
kiroModelId: "glm-5",
|
|
1064
|
-
name: "GLM 5",
|
|
1065
|
-
reasoning: true,
|
|
1066
|
-
input: ["text"],
|
|
1067
|
-
cost: ZERO_COST,
|
|
1068
|
-
contextWindow: 2e5,
|
|
1069
|
-
maxTokens: 8192
|
|
1070
|
-
},
|
|
1071
|
-
{
|
|
1072
|
-
id: "qwen3-coder-next",
|
|
1073
|
-
kiroModelId: "qwen3-coder-next",
|
|
1074
|
-
name: "Qwen3 Coder Next",
|
|
1075
|
-
reasoning: true,
|
|
1076
|
-
input: ["text"],
|
|
1077
|
-
cost: ZERO_COST,
|
|
1078
|
-
contextWindow: 256e3,
|
|
1079
|
-
maxTokens: 8192
|
|
1080
|
-
},
|
|
1081
|
-
{
|
|
1082
|
-
id: "auto",
|
|
1083
|
-
kiroModelId: "auto",
|
|
1084
|
-
name: "Auto",
|
|
1085
|
-
reasoning: true,
|
|
1086
|
-
input: ["text", "image"],
|
|
1087
|
-
cost: ZERO_COST,
|
|
1088
|
-
contextWindow: 1e6,
|
|
1089
|
-
maxTokens: 65536
|
|
1090
|
-
}
|
|
1091
|
-
];
|
|
1092
|
-
kiroModels = bootstrapKiroModels.map((model) => ({
|
|
1093
|
-
...model,
|
|
1094
|
-
...applyEffortLadder(model.reasoning ? getKiroEffortConfig(model.additionalModelRequestFieldsSchema, model.kiroModelId) : void 0),
|
|
1095
|
-
...model.id.startsWith("claude-") ? { recoverTextToolCalls: false } : {}
|
|
1096
|
-
}));
|
|
1097
|
-
BOOTSTRAP_KIRO_MODEL_IDS = kiroModels.map((model) => model.kiroModelId);
|
|
1098
|
-
KIRO_MODEL_IDS = new Set(BOOTSTRAP_KIRO_MODEL_IDS);
|
|
1099
|
-
}
|
|
1100
|
-
});
|
|
1101
|
-
|
|
1102
|
-
// ../kiro-core/dist/oauth.js
|
|
1103
|
-
function kiroUserAgent(service, sdkVersion) {
|
|
1104
|
-
return {
|
|
1105
|
-
"User-Agent": `aws-sdk-js/3.714.0 os/macos/24.3.0 lang/js md/nodejs/22.14.0 api/${service}/3.714.0 exec-env/kiro-cli/2.7.0 m/E`,
|
|
1106
|
-
"amz-sdk-invocation-id": "00000000-0000-0000-0000-000000000000",
|
|
1107
|
-
"amz-sdk-request": `attempt=1; max=${sdkVersion}`
|
|
1108
|
-
};
|
|
1109
|
-
}
|
|
1110
|
-
function kiroAuthHeaders(token) {
|
|
1111
|
-
const headers = { Authorization: `Bearer ${token}` };
|
|
1112
|
-
if (isApiKey(token))
|
|
1113
|
-
headers.tokentype = "API_KEY";
|
|
1114
|
-
return headers;
|
|
1115
|
-
}
|
|
1116
|
-
function isApiKey(token) {
|
|
1117
|
-
return token.startsWith("ksk_");
|
|
1118
|
-
}
|
|
1119
|
-
async function loginKiroWithApiKey(apiKey, onProgress) {
|
|
1120
|
-
if (!apiKey.startsWith("ksk_")) {
|
|
1121
|
-
throw new Error("Invalid API key format. Kiro API keys start with 'ksk_'.");
|
|
1122
|
-
}
|
|
1123
|
-
onProgress?.("Validating API key...");
|
|
1124
|
-
const region = "us-east-1";
|
|
1125
|
-
const managementUrl = `https://management.${resolveApiRegion(region)}.kiro.dev/`;
|
|
1126
|
-
const response = await fetch(managementUrl, {
|
|
1127
|
-
method: "POST",
|
|
1128
|
-
headers: {
|
|
1129
|
-
"Content-Type": "application/x-amz-json-1.0",
|
|
1130
|
-
"X-Amz-Target": "AmazonCodeWhispererService.GetProfile",
|
|
1131
|
-
...kiroAuthHeaders(apiKey),
|
|
1132
|
-
...kiroUserAgent("codewhispererruntime", "F,C")
|
|
1133
|
-
},
|
|
1134
|
-
body: "{}"
|
|
1135
|
-
});
|
|
1136
|
-
if (!response.ok) {
|
|
1137
|
-
let detail = "";
|
|
1138
|
-
try {
|
|
1139
|
-
detail = await response.text();
|
|
1140
|
-
} catch {
|
|
1141
|
-
detail = "";
|
|
1142
|
-
}
|
|
1143
|
-
if (response.status === 401 || response.status === 403 || /Invalid token/i.test(detail)) {
|
|
1144
|
-
throw new Error("API key was rejected by Kiro. Check that the key is valid and not expired.");
|
|
1145
|
-
}
|
|
1146
|
-
throw new Error(`Kiro GetProfile failed: ${response.status} ${response.statusText} ${detail}`.trim());
|
|
1147
|
-
}
|
|
1148
|
-
const data = await response.json();
|
|
1149
|
-
const profileArn = data.profile?.arn;
|
|
1150
|
-
return {
|
|
1151
|
-
access: apiKey,
|
|
1152
|
-
refresh: `${apiKey}|apikey`,
|
|
1153
|
-
expires: Date.now() + 365 * 24 * 60 * 60 * 1e3,
|
|
1154
|
-
clientId: "",
|
|
1155
|
-
clientSecret: "",
|
|
1156
|
-
region,
|
|
1157
|
-
authMethod: "apikey",
|
|
1158
|
-
...profileArn ? { profileArn } : {}
|
|
1159
|
-
};
|
|
1160
|
-
}
|
|
1161
|
-
async function refreshKiroToken(credentials) {
|
|
1162
|
-
const refreshed = await refreshKiroTokenInternal(credentials);
|
|
1163
|
-
if (!process.env.VITEST) {
|
|
1164
|
-
try {
|
|
1165
|
-
const { updateKiroModelsCache: updateKiroModelsCache2 } = await Promise.resolve().then(() => (init_models(), models_exports));
|
|
1166
|
-
const region = resolveApiRegion(refreshed.region);
|
|
1167
|
-
updateKiroModelsCache2(refreshed.access, region, refreshed.profileArn).catch((error2) => {
|
|
1168
|
-
console.warn(`[kiro-core] Failed to refresh Kiro model catalog in ${region}: ${formatSafeError(error2)}`);
|
|
1169
|
-
});
|
|
1170
|
-
} catch (error2) {
|
|
1171
|
-
console.warn(`[kiro-core] Failed to start Kiro model catalog refresh: ${formatSafeError(error2)}`);
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
return refreshed;
|
|
1175
|
-
}
|
|
1176
|
-
async function refreshKiroTokenInternal(credentials) {
|
|
1177
|
-
const { getKiroCliCredentials: getKiroCliCredentials2, getKiroCliCredentialsAllowExpired: getKiroCliCredentialsAllowExpired2, saveKiroCliCredentials: saveKiroCliCredentials2, getKiroCliSocialToken: getKiroCliSocialToken2, getKiroCliSocialTokenAllowExpired: getKiroCliSocialTokenAllowExpired2 } = await Promise.resolve().then(() => (init_kiro_cli(), kiro_cli_exports));
|
|
1178
|
-
const credentialAuthMethod = credentials.authMethod ?? (credentials.refresh.split("|").at(-1) === "desktop" ? "desktop" : "idc");
|
|
1179
|
-
const getValidCliCredentials = () => {
|
|
1180
|
-
if (credentialAuthMethod === "desktop")
|
|
1181
|
-
return getKiroCliSocialToken2();
|
|
1182
|
-
const cliCreds = getKiroCliCredentials2();
|
|
1183
|
-
return cliCreds?.authMethod === "idc" ? cliCreds : void 0;
|
|
1184
|
-
};
|
|
1185
|
-
const getExpiredCliCredentials = () => {
|
|
1186
|
-
if (credentialAuthMethod === "desktop")
|
|
1187
|
-
return getKiroCliSocialTokenAllowExpired2();
|
|
1188
|
-
const cliCreds = getKiroCliCredentialsAllowExpired2();
|
|
1189
|
-
return cliCreds?.authMethod === "idc" ? cliCreds : void 0;
|
|
1190
|
-
};
|
|
1191
|
-
if (credentials.authMethod === "apikey" || isApiKey(credentials.access))
|
|
1192
|
-
return credentials;
|
|
1193
|
-
if (credentialAuthMethod === "idc") {
|
|
1194
|
-
const ideCreds = getKiroIdeCredentials();
|
|
1195
|
-
if (ideCreds)
|
|
1196
|
-
return ideCreds;
|
|
1197
|
-
}
|
|
1198
|
-
const preCheckCreds = getValidCliCredentials();
|
|
1199
|
-
if (preCheckCreds)
|
|
1200
|
-
return preCheckCreds;
|
|
1201
|
-
try {
|
|
1202
|
-
const refreshed = await refreshKiroTokenDirect(credentials);
|
|
1203
|
-
saveKiroCliCredentials2(refreshed);
|
|
1204
|
-
return refreshed;
|
|
1205
|
-
} catch (refreshError) {
|
|
1206
|
-
const retryCreds = getValidCliCredentials();
|
|
1207
|
-
if (retryCreds)
|
|
1208
|
-
return retryCreds;
|
|
1209
|
-
const expiredCliCreds = getExpiredCliCredentials();
|
|
1210
|
-
if (expiredCliCreds && expiredCliCreds.refresh !== credentials.refresh) {
|
|
1211
|
-
try {
|
|
1212
|
-
const refreshedFromCli = await refreshKiroTokenDirect(expiredCliCreds);
|
|
1213
|
-
saveKiroCliCredentials2(refreshedFromCli);
|
|
1214
|
-
return refreshedFromCli;
|
|
1215
|
-
} catch {
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
const actualExpiry = credentials.expires + EXPIRES_BUFFER_MS;
|
|
1219
|
-
if (credentials.access && Date.now() < actualExpiry) {
|
|
1220
|
-
return { ...credentials, expires: actualExpiry };
|
|
1221
|
-
}
|
|
1222
|
-
throw refreshError;
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
async function refreshKiroTokenDirect(credentials) {
|
|
1226
|
-
const parts = credentials.refresh.split("|");
|
|
1227
|
-
const refreshToken = parts[0] ?? "";
|
|
1228
|
-
const authMethod = parts[parts.length - 1] ?? "idc";
|
|
1229
|
-
const region = credentials.region || "us-east-1";
|
|
1230
|
-
if (authMethod === "apikey")
|
|
1231
|
-
return credentials;
|
|
1232
|
-
if (authMethod === "desktop") {
|
|
1233
|
-
const url = KIRO_DESKTOP_REFRESH_URL.replace("{region}", region);
|
|
1234
|
-
const response2 = await fetch(url, {
|
|
1235
|
-
method: "POST",
|
|
1236
|
-
headers: { "Content-Type": "application/json", "User-Agent": KIRO_DESKTOP_USER_AGENT },
|
|
1237
|
-
body: JSON.stringify({ refreshToken })
|
|
1238
|
-
});
|
|
1239
|
-
if (!response2.ok)
|
|
1240
|
-
throw new Error(`Desktop token refresh failed: ${response2.status}`);
|
|
1241
|
-
const data2 = await response2.json();
|
|
1242
|
-
if (!data2.accessToken)
|
|
1243
|
-
throw new Error("Desktop token refresh: missing accessToken");
|
|
1244
|
-
return {
|
|
1245
|
-
refresh: `${data2.refreshToken || refreshToken}|desktop`,
|
|
1246
|
-
access: data2.accessToken,
|
|
1247
|
-
expires: Date.now() + data2.expiresIn * 1e3 - EXPIRES_BUFFER_MS,
|
|
1248
|
-
clientId: "",
|
|
1249
|
-
clientSecret: "",
|
|
1250
|
-
region,
|
|
1251
|
-
authMethod: "desktop",
|
|
1252
|
-
profileArn: data2.profileArn || credentials.profileArn,
|
|
1253
|
-
startUrl: credentials.startUrl
|
|
1254
|
-
};
|
|
1255
|
-
}
|
|
1256
|
-
if (authMethod === "external-idp") {
|
|
1257
|
-
const idpClientId = parts[1] ?? "";
|
|
1258
|
-
const tokenEndpoint = parts[2] ?? "";
|
|
1259
|
-
if (!tokenEndpoint)
|
|
1260
|
-
throw new Error("External IdP token refresh: missing token endpoint");
|
|
1261
|
-
const response2 = await fetch(tokenEndpoint, {
|
|
1262
|
-
method: "POST",
|
|
1263
|
-
headers: {
|
|
1264
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
1265
|
-
Accept: "application/json",
|
|
1266
|
-
"User-Agent": "kiro-core"
|
|
1267
|
-
},
|
|
1268
|
-
body: new URLSearchParams({
|
|
1269
|
-
grant_type: "refresh_token",
|
|
1270
|
-
client_id: idpClientId,
|
|
1271
|
-
refresh_token: refreshToken
|
|
1272
|
-
}).toString()
|
|
1273
|
-
});
|
|
1274
|
-
if (!response2.ok)
|
|
1275
|
-
throw new Error(`External IdP token refresh failed: ${response2.status}`);
|
|
1276
|
-
const data2 = await response2.json();
|
|
1277
|
-
if (!data2.access_token)
|
|
1278
|
-
throw new Error("External IdP token refresh: missing access_token");
|
|
1279
|
-
const expiresIn = typeof data2.expires_in === "number" ? data2.expires_in : 3600;
|
|
1280
|
-
return {
|
|
1281
|
-
refresh: `${data2.refresh_token || refreshToken}|${idpClientId}|${tokenEndpoint}|external-idp`,
|
|
1282
|
-
access: data2.access_token,
|
|
1283
|
-
expires: Date.now() + expiresIn * 1e3 - EXPIRES_BUFFER_MS,
|
|
1284
|
-
clientId: idpClientId,
|
|
1285
|
-
clientSecret: "",
|
|
1286
|
-
region,
|
|
1287
|
-
authMethod: "external-idp",
|
|
1288
|
-
profileArn: credentials.profileArn
|
|
1289
|
-
};
|
|
1290
|
-
}
|
|
1291
|
-
const clientId = parts[1] ?? "";
|
|
1292
|
-
const clientSecret = parts[2] ?? "";
|
|
1293
|
-
const ssoEndpoint = `https://oidc.${region}.amazonaws.com`;
|
|
1294
|
-
const response = await fetch(`${ssoEndpoint}/token`, {
|
|
1295
|
-
method: "POST",
|
|
1296
|
-
headers: { "Content-Type": "application/json", ...kiroUserAgent("ssooidc", "E") },
|
|
1297
|
-
body: JSON.stringify({ clientId, clientSecret, refreshToken, grantType: "refresh_token" })
|
|
1298
|
-
});
|
|
1299
|
-
if (!response.ok)
|
|
1300
|
-
throw new Error(`Token refresh failed: ${response.status}`);
|
|
1301
|
-
const data = await response.json();
|
|
1302
|
-
return {
|
|
1303
|
-
refresh: `${data.refreshToken}|${clientId}|${clientSecret}|idc`,
|
|
1304
|
-
access: data.accessToken,
|
|
1305
|
-
expires: Date.now() + data.expiresIn * 1e3 - EXPIRES_BUFFER_MS,
|
|
1306
|
-
clientId,
|
|
1307
|
-
clientSecret,
|
|
1308
|
-
region,
|
|
1309
|
-
authMethod: "idc",
|
|
1310
|
-
profileArn: credentials.profileArn,
|
|
1311
|
-
startUrl: credentials.startUrl,
|
|
1312
|
-
isEnterprise: credentials.isEnterprise
|
|
1313
|
-
};
|
|
1314
|
-
}
|
|
1315
|
-
async function resolveKiroCredentials() {
|
|
1316
|
-
const { getKiroCliCredentials: getKiroCliCredentials2, getKiroCliCredentialsAllowExpired: getKiroCliCredentialsAllowExpired2 } = await Promise.resolve().then(() => (init_kiro_cli(), kiro_cli_exports));
|
|
1317
|
-
const fresh = getKiroCliCredentials2() ?? getKiroIdeCredentials();
|
|
1318
|
-
if (fresh)
|
|
1319
|
-
return fresh;
|
|
1320
|
-
const stale = getKiroCliCredentialsAllowExpired2();
|
|
1321
|
-
if (!stale)
|
|
1322
|
-
return void 0;
|
|
1323
|
-
return refreshKiroToken(stale);
|
|
1324
|
-
}
|
|
1325
|
-
var KIRO_DESKTOP_REFRESH_URL, EXPIRES_BUFFER_MS, KIRO_DESKTOP_USER_AGENT;
|
|
1326
|
-
var init_oauth = __esm({
|
|
1327
|
-
"../kiro-core/dist/oauth.js"() {
|
|
1328
|
-
"use strict";
|
|
1329
|
-
init_debug();
|
|
1330
|
-
init_endpoints();
|
|
1331
|
-
init_kiro_ide();
|
|
1332
|
-
KIRO_DESKTOP_REFRESH_URL = "https://prod.{region}.auth.desktop.kiro.dev/refreshToken";
|
|
1333
|
-
EXPIRES_BUFFER_MS = 5 * 60 * 1e3;
|
|
1334
|
-
KIRO_DESKTOP_USER_AGENT = "Kiro-Desktop/0.2.13 (darwin; arm64)";
|
|
1335
|
-
}
|
|
1336
|
-
});
|
|
1337
|
-
|
|
1338
|
-
// ../kiro-core/dist/token-type.js
|
|
1339
|
-
function isExternalIdpAccessToken(accessToken) {
|
|
1340
|
-
if (typeof accessToken !== "string")
|
|
1341
|
-
return false;
|
|
1342
|
-
const segments = accessToken.split(".");
|
|
1343
|
-
if (segments.length !== 3)
|
|
1344
|
-
return false;
|
|
1345
|
-
const payloadSegment = segments[1];
|
|
1346
|
-
if (!payloadSegment)
|
|
1347
|
-
return false;
|
|
1348
|
-
try {
|
|
1349
|
-
const payload = JSON.parse(Buffer.from(payloadSegment.replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf-8"));
|
|
1350
|
-
return payload.aud === EXTERNAL_IDP_AUDIENCE;
|
|
1351
|
-
} catch {
|
|
1352
|
-
return false;
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
function kiroTokenTypeHeaders(accessToken) {
|
|
1356
|
-
return isExternalIdpAccessToken(accessToken) ? { tokentype: "EXTERNAL_IDP" } : {};
|
|
1357
|
-
}
|
|
1358
|
-
var EXTERNAL_IDP_AUDIENCE;
|
|
1359
|
-
var init_token_type = __esm({
|
|
1360
|
-
"../kiro-core/dist/token-type.js"() {
|
|
1361
|
-
"use strict";
|
|
1362
|
-
EXTERNAL_IDP_AUDIENCE = "api://kiro";
|
|
1363
|
-
}
|
|
1364
|
-
});
|
|
1365
|
-
|
|
1366
|
-
// ../kiro-core/dist/management.js
|
|
1367
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
1368
|
-
function candidateManagementRegions(primary) {
|
|
1369
|
-
const seen = /* @__PURE__ */ new Set([primary]);
|
|
1370
|
-
const candidates = [primary];
|
|
1371
|
-
for (const region of CANONICAL_MANAGEMENT_REGIONS) {
|
|
1372
|
-
if (!seen.has(region)) {
|
|
1373
|
-
seen.add(region);
|
|
1374
|
-
candidates.push(region);
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
return candidates;
|
|
1378
|
-
}
|
|
1379
|
-
async function requestManagement(auth, operation, path, method, body) {
|
|
1380
|
-
const url = new URL(path, getKiroEndpoints(auth.region).management);
|
|
1381
|
-
const request = {
|
|
1382
|
-
method,
|
|
1383
|
-
headers: {
|
|
1384
|
-
Accept: "application/json",
|
|
1385
|
-
...kiroAuthHeaders(auth.accessToken),
|
|
1386
|
-
...kiroTokenTypeHeaders(auth.accessToken)
|
|
1387
|
-
}
|
|
1388
|
-
};
|
|
1389
|
-
if (method === "GET") {
|
|
1390
|
-
for (const [name, value] of Object.entries(body)) {
|
|
1391
|
-
if (value !== void 0)
|
|
1392
|
-
url.searchParams.set(name, String(value));
|
|
1393
|
-
}
|
|
1394
|
-
} else {
|
|
1395
|
-
request.headers = { ...request.headers, "Content-Type": "application/json" };
|
|
1396
|
-
request.body = JSON.stringify(body);
|
|
1397
|
-
}
|
|
1398
|
-
let response;
|
|
1399
|
-
try {
|
|
1400
|
-
response = await fetch(url.toString(), request);
|
|
1401
|
-
} catch (error2) {
|
|
1402
|
-
throw new Error(`Kiro management ${operation} request failed in ${auth.region}`, { cause: error2 });
|
|
1403
|
-
}
|
|
1404
|
-
return parseManagementResponse(response, operation, auth.region);
|
|
1405
|
-
}
|
|
1406
|
-
function profileCacheKey(auth) {
|
|
1407
|
-
const tokenHash = createHash2("sha256").update(auth.accessToken).digest("base64url");
|
|
1408
|
-
return `${auth.region}:${tokenHash}`;
|
|
982
|
+
return arn;
|
|
1409
983
|
}
|
|
1410
984
|
async function parseManagementResponse(response, operation, region) {
|
|
1411
985
|
if (!response.ok) {
|
|
@@ -1442,6 +1016,13 @@ async function resolveKiroProfileArn(auth, providedArn) {
|
|
|
1442
1016
|
if (pending)
|
|
1443
1017
|
return pending;
|
|
1444
1018
|
const request = (async () => {
|
|
1019
|
+
if (isApiKey(auth.accessToken)) {
|
|
1020
|
+
const arn = await getApiKeyProfileArn(auth.accessToken);
|
|
1021
|
+
profileArnCache.set(key, arn);
|
|
1022
|
+
profileRegionCache.set(key, API_KEY_REGION);
|
|
1023
|
+
debugLog("profile.resolve", { source: "api-key", region: API_KEY_REGION, arn });
|
|
1024
|
+
return arn;
|
|
1025
|
+
}
|
|
1445
1026
|
let lastResponse;
|
|
1446
1027
|
let lastHttpError;
|
|
1447
1028
|
for (const region of candidateManagementRegions(auth.region)) {
|
|
@@ -1477,73 +1058,544 @@ async function resolveKiroProfileArn(auth, providedArn) {
|
|
|
1477
1058
|
pendingProfileRequests.delete(key);
|
|
1478
1059
|
}
|
|
1479
1060
|
}
|
|
1480
|
-
async function listAvailableModels(auth, profileArn) {
|
|
1481
|
-
const response = await requestManagement(auth, "ListAvailableModels", LIST_MODELS_PATH, "GET", {
|
|
1482
|
-
origin: "KIRO_CLI",
|
|
1483
|
-
profileArn
|
|
1484
|
-
});
|
|
1485
|
-
if (!Array.isArray(response.models) || response.models.length === 0) {
|
|
1486
|
-
throw new Error(`Kiro management ListAvailableModels returned no models in ${auth.region}`);
|
|
1061
|
+
async function listAvailableModels(auth, profileArn) {
|
|
1062
|
+
const response = await requestManagement(auth, "ListAvailableModels", LIST_MODELS_PATH, "GET", {
|
|
1063
|
+
origin: "KIRO_CLI",
|
|
1064
|
+
profileArn
|
|
1065
|
+
});
|
|
1066
|
+
if (!Array.isArray(response.models) || response.models.length === 0) {
|
|
1067
|
+
throw new Error(`Kiro management ListAvailableModels returned no models in ${auth.region}`);
|
|
1068
|
+
}
|
|
1069
|
+
if (response.models.some((model) => !model || typeof model.modelId !== "string" || !model.modelId)) {
|
|
1070
|
+
throw new Error(`Kiro management ListAvailableModels returned an invalid catalog in ${auth.region}`);
|
|
1071
|
+
}
|
|
1072
|
+
return response;
|
|
1073
|
+
}
|
|
1074
|
+
async function fetchKiroModelCatalog(auth, providedProfileArn) {
|
|
1075
|
+
const profileArn = await resolveKiroProfileArn(auth, providedProfileArn);
|
|
1076
|
+
const region = isApiKey(auth.accessToken) ? API_KEY_REGION : profileRegionCache.get(profileCacheKey(auth)) ?? auth.region;
|
|
1077
|
+
if (region !== auth.region) {
|
|
1078
|
+
return listAvailableModels({ ...auth, region }, profileArn);
|
|
1079
|
+
}
|
|
1080
|
+
return listAvailableModels(auth, profileArn);
|
|
1081
|
+
}
|
|
1082
|
+
async function getUsageLimits(auth, request) {
|
|
1083
|
+
const operation = "GetUsageLimits";
|
|
1084
|
+
const url = new URL("Get-Usage-Limits", getKiroEndpoints(auth.region).management);
|
|
1085
|
+
for (const [name, value] of Object.entries(request)) {
|
|
1086
|
+
if (value !== void 0)
|
|
1087
|
+
url.searchParams.set(name, String(value));
|
|
1088
|
+
}
|
|
1089
|
+
let response;
|
|
1090
|
+
try {
|
|
1091
|
+
response = await fetch(url.toString(), {
|
|
1092
|
+
method: "GET",
|
|
1093
|
+
headers: {
|
|
1094
|
+
Accept: "application/json",
|
|
1095
|
+
...kiroAuthHeaders(auth.accessToken),
|
|
1096
|
+
...kiroTokenTypeHeaders(auth.accessToken),
|
|
1097
|
+
"User-Agent": "ns-kiro-provider"
|
|
1098
|
+
}
|
|
1099
|
+
});
|
|
1100
|
+
} catch (error2) {
|
|
1101
|
+
throw new Error(`Kiro management ${operation} request failed in ${auth.region}`, { cause: error2 });
|
|
1102
|
+
}
|
|
1103
|
+
return parseManagementResponse(response, operation, auth.region);
|
|
1104
|
+
}
|
|
1105
|
+
var LIST_PROFILES_PATH, LIST_MODELS_PATH, GET_PROFILE_TARGET, API_KEY_REGION, profileArnCache, pendingProfileRequests, profileRegionCache, CANONICAL_MANAGEMENT_REGIONS, ENV_PROFILE_ARN, KiroManagementHttpError;
|
|
1106
|
+
var init_management = __esm({
|
|
1107
|
+
"../kiro-core/dist/management.js"() {
|
|
1108
|
+
"use strict";
|
|
1109
|
+
init_debug();
|
|
1110
|
+
init_endpoints();
|
|
1111
|
+
init_oauth();
|
|
1112
|
+
init_token_type();
|
|
1113
|
+
LIST_PROFILES_PATH = "List-Available-Profiles";
|
|
1114
|
+
LIST_MODELS_PATH = "List-Available-Models";
|
|
1115
|
+
GET_PROFILE_TARGET = "AmazonCodeWhispererService.GetProfile";
|
|
1116
|
+
API_KEY_REGION = "us-east-1";
|
|
1117
|
+
profileArnCache = /* @__PURE__ */ new Map();
|
|
1118
|
+
pendingProfileRequests = /* @__PURE__ */ new Map();
|
|
1119
|
+
profileRegionCache = /* @__PURE__ */ new Map();
|
|
1120
|
+
CANONICAL_MANAGEMENT_REGIONS = ["us-east-1", "eu-central-1"];
|
|
1121
|
+
ENV_PROFILE_ARN = "KIRO_PROFILE_ARN";
|
|
1122
|
+
KiroManagementHttpError = class extends Error {
|
|
1123
|
+
status;
|
|
1124
|
+
constructor(message, status) {
|
|
1125
|
+
super(message);
|
|
1126
|
+
this.status = status;
|
|
1127
|
+
this.name = "KiroManagementHttpError";
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
|
|
1133
|
+
// ../kiro-core/dist/models.js
|
|
1134
|
+
var models_exports = {};
|
|
1135
|
+
__export(models_exports, {
|
|
1136
|
+
KIRO_MANAGEMENT_CACHE_PATH: () => KIRO_MANAGEMENT_CACHE_PATH,
|
|
1137
|
+
KIRO_MANAGEMENT_CACHE_SOURCE: () => KIRO_MANAGEMENT_CACHE_SOURCE,
|
|
1138
|
+
KIRO_MANAGEMENT_CACHE_VERSION: () => KIRO_MANAGEMENT_CACHE_VERSION,
|
|
1139
|
+
KIRO_MODEL_IDS: () => KIRO_MODEL_IDS,
|
|
1140
|
+
applyEffortLadder: () => applyEffortLadder,
|
|
1141
|
+
getCachedModels: () => getCachedModels,
|
|
1142
|
+
isCacheStale: () => isCacheStale,
|
|
1143
|
+
kiroModels: () => kiroModels,
|
|
1144
|
+
loadCachedModelIds: () => loadCachedModelIds,
|
|
1145
|
+
mapKiroCatalogModels: () => mapKiroCatalogModels,
|
|
1146
|
+
resolveApiRegion: () => resolveApiRegion,
|
|
1147
|
+
resolveKiroModel: () => resolveKiroModel,
|
|
1148
|
+
updateKiroModelsCache: () => updateKiroModelsCache
|
|
1149
|
+
});
|
|
1150
|
+
import { randomUUID } from "node:crypto";
|
|
1151
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
1152
|
+
import { homedir as homedir4 } from "node:os";
|
|
1153
|
+
import { join as join4 } from "node:path";
|
|
1154
|
+
function isRecord2(value) {
|
|
1155
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1156
|
+
}
|
|
1157
|
+
function isPositiveNumber(value) {
|
|
1158
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
1159
|
+
}
|
|
1160
|
+
function isEffortList(value) {
|
|
1161
|
+
return Array.isArray(value) && value.length > 0 && value.every((effort) => KIRO_EFFORT_ORDER.includes(effort));
|
|
1162
|
+
}
|
|
1163
|
+
function isEffortMap(value) {
|
|
1164
|
+
return isRecord2(value) && Object.values(value).every((mapped) => typeof mapped === "string");
|
|
1165
|
+
}
|
|
1166
|
+
function isCachedKiroModel(value) {
|
|
1167
|
+
if (!isRecord2(value))
|
|
1168
|
+
return false;
|
|
1169
|
+
const cost = value.cost;
|
|
1170
|
+
const input = value.input;
|
|
1171
|
+
const schema = value.additionalModelRequestFieldsSchema;
|
|
1172
|
+
const tokenLimits = value.tokenLimits;
|
|
1173
|
+
return typeof value.id === "string" && value.id.length > 0 && typeof value.kiroModelId === "string" && value.kiroModelId.length > 0 && typeof value.name === "string" && value.name.length > 0 && typeof value.reasoning === "boolean" && Array.isArray(input) && input.length > 0 && input.every((modality) => modality === "text" || modality === "image") && isRecord2(cost) && typeof cost.input === "number" && typeof cost.output === "number" && typeof cost.cacheRead === "number" && typeof cost.cacheWrite === "number" && isPositiveNumber(value.contextWindow) && isPositiveNumber(value.maxTokens) && (value.efforts === void 0 || isEffortList(value.efforts)) && (value.effortMap === void 0 || isEffortMap(value.effortMap)) && (schema === void 0 || isRecord2(schema)) && (tokenLimits === void 0 || isRecord2(tokenLimits)) && (value.firstTokenTimeout === void 0 || isPositiveNumber(value.firstTokenTimeout)) && (value.rateMultiplier === void 0 || isPositiveNumber(value.rateMultiplier)) && (value.rateUnit === void 0 || typeof value.rateUnit === "string");
|
|
1174
|
+
}
|
|
1175
|
+
function parseManagementCache(raw) {
|
|
1176
|
+
let value;
|
|
1177
|
+
try {
|
|
1178
|
+
value = JSON.parse(raw);
|
|
1179
|
+
} catch {
|
|
1180
|
+
return void 0;
|
|
1181
|
+
}
|
|
1182
|
+
if (!isRecord2(value) || value.version !== KIRO_MANAGEMENT_CACHE_VERSION || value.source !== KIRO_MANAGEMENT_CACHE_SOURCE || !isRecord2(value.regions)) {
|
|
1183
|
+
return void 0;
|
|
1184
|
+
}
|
|
1185
|
+
const regions = {};
|
|
1186
|
+
for (const [region, rawEntry] of Object.entries(value.regions)) {
|
|
1187
|
+
if (!isRecord2(rawEntry) || rawEntry.region !== region || !isPositiveNumber(rawEntry.fetchedAt) || !Array.isArray(rawEntry.models) || rawEntry.models.length === 0 || !rawEntry.models.every(isCachedKiroModel)) {
|
|
1188
|
+
return void 0;
|
|
1189
|
+
}
|
|
1190
|
+
const modelIds = /* @__PURE__ */ new Set();
|
|
1191
|
+
for (const model of rawEntry.models) {
|
|
1192
|
+
if (modelIds.has(model.id))
|
|
1193
|
+
return void 0;
|
|
1194
|
+
modelIds.add(model.id);
|
|
1195
|
+
}
|
|
1196
|
+
regions[region] = rawEntry;
|
|
1197
|
+
}
|
|
1198
|
+
return {
|
|
1199
|
+
version: KIRO_MANAGEMENT_CACHE_VERSION,
|
|
1200
|
+
source: KIRO_MANAGEMENT_CACHE_SOURCE,
|
|
1201
|
+
regions
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
function readManagementCache() {
|
|
1205
|
+
if (!existsSync3(KIRO_MANAGEMENT_CACHE_PATH))
|
|
1206
|
+
return void 0;
|
|
1207
|
+
try {
|
|
1208
|
+
return parseManagementCache(readFileSync2(KIRO_MANAGEMENT_CACHE_PATH, "utf-8"));
|
|
1209
|
+
} catch {
|
|
1210
|
+
return void 0;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
function writeManagementCache(cache) {
|
|
1214
|
+
const temporaryPath = `${KIRO_MANAGEMENT_CACHE_PATH}.${process.pid}.${randomUUID()}.tmp`;
|
|
1215
|
+
try {
|
|
1216
|
+
writeFileSync(temporaryPath, JSON.stringify(cache, null, 2), "utf-8");
|
|
1217
|
+
renameSync(temporaryPath, KIRO_MANAGEMENT_CACHE_PATH);
|
|
1218
|
+
} finally {
|
|
1219
|
+
rmSync(temporaryPath, { force: true });
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
function toLocalModelId(kiroModelId) {
|
|
1223
|
+
return kiroModelId.replace(/(\d)\.(\d)/g, "$1-$2");
|
|
1224
|
+
}
|
|
1225
|
+
function humanizeModelId(modelId) {
|
|
1226
|
+
return modelId.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
1227
|
+
}
|
|
1228
|
+
function applyEffortLadder(config) {
|
|
1229
|
+
if (!config || config.values.length === 0)
|
|
1230
|
+
return {};
|
|
1231
|
+
const efforts = KIRO_EFFORT_ORDER.filter((effort) => config.values.includes(effort));
|
|
1232
|
+
if (efforts.length === 0)
|
|
1233
|
+
return {};
|
|
1234
|
+
return { efforts, ...config.summarizedThinking ? { supportsSummarizedThinking: true } : {} };
|
|
1235
|
+
}
|
|
1236
|
+
function hasReasoningFamilyFallback(modelId) {
|
|
1237
|
+
const normalizedId = modelId.toLowerCase();
|
|
1238
|
+
return normalizedId === "auto" || REASONING_FAMILY_MARKERS.some((marker) => normalizedId.includes(marker));
|
|
1239
|
+
}
|
|
1240
|
+
function hasVerifiedImageInput(kiroModelId) {
|
|
1241
|
+
return kiroModelId.startsWith("claude-") || VERIFIED_IMAGE_MODEL_IDS.has(kiroModelId.toLowerCase());
|
|
1242
|
+
}
|
|
1243
|
+
function applyVerifiedCapabilities(model) {
|
|
1244
|
+
if (!hasVerifiedImageInput(model.kiroModelId) || model.input.includes("image"))
|
|
1245
|
+
return model;
|
|
1246
|
+
return { ...model, input: ["text", "image"] };
|
|
1247
|
+
}
|
|
1248
|
+
function validateCatalogMetadata(model) {
|
|
1249
|
+
const rawSchema = model.additionalModelRequestFieldsSchema;
|
|
1250
|
+
const schema = rawSchema ?? void 0;
|
|
1251
|
+
if (schema !== void 0 && !isRecord2(schema)) {
|
|
1252
|
+
throw new Error(`Kiro management catalog model ${model.modelId} has an invalid request-fields schema`);
|
|
1487
1253
|
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1254
|
+
const tokenLimits = model.tokenLimits;
|
|
1255
|
+
if (tokenLimits !== void 0 && !isRecord2(tokenLimits)) {
|
|
1256
|
+
throw new Error(`Kiro management catalog model ${model.modelId} has invalid token limits`);
|
|
1490
1257
|
}
|
|
1491
|
-
|
|
1258
|
+
if (tokenLimits && (tokenLimits.maxInputTokens !== void 0 && !isPositiveNumber(tokenLimits.maxInputTokens) || tokenLimits.maxOutputTokens !== void 0 && !isPositiveNumber(tokenLimits.maxOutputTokens))) {
|
|
1259
|
+
throw new Error(`Kiro management catalog model ${model.modelId} has invalid token limits`);
|
|
1260
|
+
}
|
|
1261
|
+
return { schema, tokenLimits };
|
|
1492
1262
|
}
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
if (region !== auth.region) {
|
|
1497
|
-
return listAvailableModels({ ...auth, region }, profileArn);
|
|
1263
|
+
function mapKiroCatalogModels(catalogModels, region, rates) {
|
|
1264
|
+
if (catalogModels.length === 0) {
|
|
1265
|
+
throw new Error(`Kiro management catalog returned no models in ${region}`);
|
|
1498
1266
|
}
|
|
1499
|
-
|
|
1267
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
1268
|
+
return catalogModels.map((catalogModel) => {
|
|
1269
|
+
const kiroModelId = catalogModel.modelId;
|
|
1270
|
+
if (!kiroModelId || kiroModelId.trim() !== kiroModelId) {
|
|
1271
|
+
throw new Error(`Kiro management catalog returned an invalid model ID in ${region}`);
|
|
1272
|
+
}
|
|
1273
|
+
const id = toLocalModelId(kiroModelId);
|
|
1274
|
+
if (seenIds.has(id)) {
|
|
1275
|
+
throw new Error(`Kiro management catalog contains conflicting model ID ${id} in ${region}`);
|
|
1276
|
+
}
|
|
1277
|
+
seenIds.add(id);
|
|
1278
|
+
const existing = kiroModels.find((model) => model.id === id);
|
|
1279
|
+
const rate = rates?.get(kiroModelId);
|
|
1280
|
+
const { schema, tokenLimits } = validateCatalogMetadata(catalogModel);
|
|
1281
|
+
const effortConfig = getKiroEffortConfig(schema, kiroModelId);
|
|
1282
|
+
const catalogName = typeof catalogModel.displayName === "string" && catalogModel.displayName.length > 0 ? catalogModel.displayName : void 0;
|
|
1283
|
+
return {
|
|
1284
|
+
id,
|
|
1285
|
+
kiroModelId,
|
|
1286
|
+
// Humanize the wire id, not the local one: `toLocalModelId` rewrites
|
|
1287
|
+
// `5.1` as `5-1`, and a display name derived from it loses the dot —
|
|
1288
|
+
// "Claude Fable 5 1" instead of "Claude Fable 5.1".
|
|
1289
|
+
name: catalogName ?? existing?.name ?? humanizeModelId(kiroModelId),
|
|
1290
|
+
region,
|
|
1291
|
+
// Deliberately schema-only: when a schema exists the resolver returns
|
|
1292
|
+
// `deriveKiroEffort(schema)`, and when it does not the family-marker guess
|
|
1293
|
+
// decides. The fallback tier feeds the ladders, not this flag.
|
|
1294
|
+
reasoning: schema !== void 0 && effortConfig !== void 0 || schema === void 0 && hasReasoningFamilyFallback(id),
|
|
1295
|
+
...applyEffortLadder(effortConfig),
|
|
1296
|
+
input: existing ? [...existing.input] : hasVerifiedImageInput(kiroModelId) ? ["text", "image"] : ["text"],
|
|
1297
|
+
...id.startsWith("claude-") ? { recoverTextToolCalls: false } : {},
|
|
1298
|
+
cost: ZERO_COST,
|
|
1299
|
+
...rate ? { rateMultiplier: rate.multiplier, ...rate.unit ? { rateUnit: rate.unit } : {} } : {},
|
|
1300
|
+
contextWindow: tokenLimits?.maxInputTokens ?? DEFAULT_CONTEXT_WINDOW,
|
|
1301
|
+
maxTokens: tokenLimits?.maxOutputTokens ?? DEFAULT_MAX_TOKENS,
|
|
1302
|
+
...existing?.firstTokenTimeout ? { firstTokenTimeout: existing.firstTokenTimeout } : {},
|
|
1303
|
+
...schema ? { additionalModelRequestFieldsSchema: schema } : {},
|
|
1304
|
+
...tokenLimits ? { tokenLimits } : {}
|
|
1305
|
+
};
|
|
1306
|
+
});
|
|
1500
1307
|
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
const
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1308
|
+
function refreshKnownModelIds(cache) {
|
|
1309
|
+
KIRO_MODEL_IDS.clear();
|
|
1310
|
+
for (const modelId of BOOTSTRAP_KIRO_MODEL_IDS)
|
|
1311
|
+
KIRO_MODEL_IDS.add(modelId);
|
|
1312
|
+
if (!cache)
|
|
1313
|
+
return;
|
|
1314
|
+
for (const entry of Object.values(cache.regions)) {
|
|
1315
|
+
for (const model of entry.models)
|
|
1316
|
+
KIRO_MODEL_IDS.add(model.kiroModelId);
|
|
1507
1317
|
}
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1318
|
+
}
|
|
1319
|
+
function loadCachedModelIds() {
|
|
1320
|
+
refreshKnownModelIds(readManagementCache());
|
|
1321
|
+
}
|
|
1322
|
+
function getCachedModels(region) {
|
|
1323
|
+
const cache = readManagementCache();
|
|
1324
|
+
refreshKnownModelIds(cache);
|
|
1325
|
+
const models = cache?.regions[region]?.models ?? kiroModels;
|
|
1326
|
+
let changed = false;
|
|
1327
|
+
const corrected = models.map((model) => {
|
|
1328
|
+
const result = applyVerifiedCapabilities(model);
|
|
1329
|
+
if (result !== model)
|
|
1330
|
+
changed = true;
|
|
1331
|
+
return result;
|
|
1332
|
+
});
|
|
1333
|
+
return changed ? corrected : models;
|
|
1334
|
+
}
|
|
1335
|
+
function isCacheStale(region) {
|
|
1336
|
+
const entry = readManagementCache()?.regions[region];
|
|
1337
|
+
return !entry || Date.now() - entry.fetchedAt > CACHE_MAX_AGE_MS;
|
|
1338
|
+
}
|
|
1339
|
+
async function updateKiroModelsCache(accessToken, region, profileArn) {
|
|
1340
|
+
const response = await fetchKiroModelCatalog({ accessToken, region }, profileArn);
|
|
1341
|
+
const models = mapKiroCatalogModels(response.models, region, getKiroCliModelRates());
|
|
1342
|
+
const cache = readManagementCache() ?? {
|
|
1343
|
+
version: KIRO_MANAGEMENT_CACHE_VERSION,
|
|
1344
|
+
source: KIRO_MANAGEMENT_CACHE_SOURCE,
|
|
1345
|
+
regions: {}
|
|
1346
|
+
};
|
|
1347
|
+
cache.regions[region] = { region, fetchedAt: Date.now(), models };
|
|
1348
|
+
writeManagementCache(cache);
|
|
1349
|
+
refreshKnownModelIds(cache);
|
|
1350
|
+
}
|
|
1351
|
+
function resolveKiroModel(modelId, exactKiroModelId) {
|
|
1352
|
+
if (exactKiroModelId)
|
|
1353
|
+
return exactKiroModelId;
|
|
1354
|
+
const cachedModel = Object.values(readManagementCache()?.regions ?? {}).flatMap((entry) => entry.models).find((model) => model.id === modelId);
|
|
1355
|
+
if (cachedModel) {
|
|
1356
|
+
KIRO_MODEL_IDS.add(cachedModel.kiroModelId);
|
|
1357
|
+
return cachedModel.kiroModelId;
|
|
1521
1358
|
}
|
|
1522
|
-
|
|
1359
|
+
const bootstrapModel = kiroModels.find((model) => model.id === modelId);
|
|
1360
|
+
if (bootstrapModel)
|
|
1361
|
+
return bootstrapModel.kiroModelId;
|
|
1362
|
+
const normalizedId = modelId.replace(/(\d)-(\d)/g, "$1.$2");
|
|
1363
|
+
loadCachedModelIds();
|
|
1364
|
+
if (!KIRO_MODEL_IDS.has(normalizedId)) {
|
|
1365
|
+
throw new Error(`Unknown Kiro model ID: ${modelId}`);
|
|
1366
|
+
}
|
|
1367
|
+
return normalizedId;
|
|
1523
1368
|
}
|
|
1524
|
-
var
|
|
1525
|
-
var
|
|
1526
|
-
"../kiro-core/dist/
|
|
1369
|
+
var KIRO_MANAGEMENT_CACHE_VERSION, KIRO_MANAGEMENT_CACHE_SOURCE, KIRO_MANAGEMENT_CACHE_PATH, CACHE_MAX_AGE_MS, DEFAULT_CONTEXT_WINDOW, DEFAULT_MAX_TOKENS, ZERO_COST, REASONING_FAMILY_MARKERS, VERIFIED_IMAGE_MODEL_IDS, bootstrapKiroModels, kiroModels, BOOTSTRAP_KIRO_MODEL_IDS, KIRO_MODEL_IDS;
|
|
1370
|
+
var init_models = __esm({
|
|
1371
|
+
"../kiro-core/dist/models.js"() {
|
|
1527
1372
|
"use strict";
|
|
1528
|
-
|
|
1373
|
+
init_effort();
|
|
1374
|
+
init_kiro_cli();
|
|
1375
|
+
init_management();
|
|
1376
|
+
init_types();
|
|
1529
1377
|
init_endpoints();
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1378
|
+
KIRO_MANAGEMENT_CACHE_VERSION = 1;
|
|
1379
|
+
KIRO_MANAGEMENT_CACHE_SOURCE = "ns-kiro-provider-management";
|
|
1380
|
+
KIRO_MANAGEMENT_CACHE_PATH = join4(homedir4(), ".ns-kiro-provider-models-cache.json");
|
|
1381
|
+
CACHE_MAX_AGE_MS = 36e5;
|
|
1382
|
+
DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
1383
|
+
DEFAULT_MAX_TOKENS = 8192;
|
|
1384
|
+
ZERO_COST = Object.freeze({ input: 0, output: 0, cacheRead: 0, cacheWrite: 0 });
|
|
1385
|
+
REASONING_FAMILY_MARKERS = ["opus", "sonnet", "fable", "coder", "deepseek", "gpt", "glm", "qwen"];
|
|
1386
|
+
VERIFIED_IMAGE_MODEL_IDS = /* @__PURE__ */ new Set(["gpt-5.6-luna"]);
|
|
1387
|
+
bootstrapKiroModels = [
|
|
1388
|
+
{
|
|
1389
|
+
id: "claude-opus-5",
|
|
1390
|
+
kiroModelId: "claude-opus-5",
|
|
1391
|
+
name: "Claude Opus 5",
|
|
1392
|
+
reasoning: true,
|
|
1393
|
+
input: ["text", "image"],
|
|
1394
|
+
cost: ZERO_COST,
|
|
1395
|
+
contextWindow: 1e6,
|
|
1396
|
+
maxTokens: 128e3,
|
|
1397
|
+
firstTokenTimeout: 18e4
|
|
1398
|
+
},
|
|
1399
|
+
{
|
|
1400
|
+
id: "claude-opus-4-8",
|
|
1401
|
+
kiroModelId: "claude-opus-4.8",
|
|
1402
|
+
name: "Claude Opus 4.8",
|
|
1403
|
+
reasoning: true,
|
|
1404
|
+
input: ["text", "image"],
|
|
1405
|
+
cost: ZERO_COST,
|
|
1406
|
+
contextWindow: 1e6,
|
|
1407
|
+
maxTokens: 128e3,
|
|
1408
|
+
firstTokenTimeout: 18e4
|
|
1409
|
+
},
|
|
1410
|
+
{
|
|
1411
|
+
id: "claude-opus-4-7",
|
|
1412
|
+
kiroModelId: "claude-opus-4.7",
|
|
1413
|
+
name: "Claude Opus 4.7",
|
|
1414
|
+
reasoning: true,
|
|
1415
|
+
input: ["text", "image"],
|
|
1416
|
+
cost: ZERO_COST,
|
|
1417
|
+
contextWindow: 1e6,
|
|
1418
|
+
maxTokens: 128e3,
|
|
1419
|
+
firstTokenTimeout: 18e4
|
|
1420
|
+
},
|
|
1421
|
+
{
|
|
1422
|
+
id: "claude-opus-4-6",
|
|
1423
|
+
kiroModelId: "claude-opus-4.6",
|
|
1424
|
+
name: "Claude Opus 4.6",
|
|
1425
|
+
reasoning: true,
|
|
1426
|
+
input: ["text", "image"],
|
|
1427
|
+
cost: ZERO_COST,
|
|
1428
|
+
contextWindow: 1e6,
|
|
1429
|
+
maxTokens: 32768
|
|
1430
|
+
},
|
|
1431
|
+
{
|
|
1432
|
+
id: "claude-opus-4-5",
|
|
1433
|
+
kiroModelId: "claude-opus-4.5",
|
|
1434
|
+
name: "Claude Opus 4.5",
|
|
1435
|
+
reasoning: true,
|
|
1436
|
+
input: ["text", "image"],
|
|
1437
|
+
cost: ZERO_COST,
|
|
1438
|
+
contextWindow: 2e5,
|
|
1439
|
+
maxTokens: 64e3
|
|
1440
|
+
},
|
|
1441
|
+
{
|
|
1442
|
+
id: "claude-sonnet-5",
|
|
1443
|
+
kiroModelId: "claude-sonnet-5",
|
|
1444
|
+
name: "Claude Sonnet 5",
|
|
1445
|
+
reasoning: true,
|
|
1446
|
+
input: ["text", "image"],
|
|
1447
|
+
cost: ZERO_COST,
|
|
1448
|
+
contextWindow: 1e6,
|
|
1449
|
+
maxTokens: 65536
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
id: "claude-sonnet-4-6",
|
|
1453
|
+
kiroModelId: "claude-sonnet-4.6",
|
|
1454
|
+
name: "Claude Sonnet 4.6",
|
|
1455
|
+
reasoning: true,
|
|
1456
|
+
input: ["text", "image"],
|
|
1457
|
+
cost: ZERO_COST,
|
|
1458
|
+
contextWindow: 1e6,
|
|
1459
|
+
maxTokens: 65536
|
|
1460
|
+
},
|
|
1461
|
+
{
|
|
1462
|
+
id: "claude-sonnet-4-5",
|
|
1463
|
+
kiroModelId: "claude-sonnet-4.5",
|
|
1464
|
+
name: "Claude Sonnet 4.5",
|
|
1465
|
+
reasoning: true,
|
|
1466
|
+
input: ["text", "image"],
|
|
1467
|
+
cost: ZERO_COST,
|
|
1468
|
+
contextWindow: 2e5,
|
|
1469
|
+
maxTokens: 65536
|
|
1470
|
+
},
|
|
1471
|
+
{
|
|
1472
|
+
id: "claude-sonnet-4",
|
|
1473
|
+
kiroModelId: "claude-sonnet-4",
|
|
1474
|
+
name: "Claude Sonnet 4",
|
|
1475
|
+
reasoning: true,
|
|
1476
|
+
input: ["text", "image"],
|
|
1477
|
+
cost: ZERO_COST,
|
|
1478
|
+
contextWindow: 2e5,
|
|
1479
|
+
maxTokens: 65536
|
|
1480
|
+
},
|
|
1481
|
+
{
|
|
1482
|
+
id: "claude-haiku-4-5",
|
|
1483
|
+
kiroModelId: "claude-haiku-4.5",
|
|
1484
|
+
name: "Claude Haiku 4.5",
|
|
1485
|
+
reasoning: false,
|
|
1486
|
+
input: ["text", "image"],
|
|
1487
|
+
cost: ZERO_COST,
|
|
1488
|
+
contextWindow: 2e5,
|
|
1489
|
+
maxTokens: 65536
|
|
1490
|
+
},
|
|
1491
|
+
{
|
|
1492
|
+
id: "claude-fable-5",
|
|
1493
|
+
kiroModelId: "claude-fable-5",
|
|
1494
|
+
name: "Claude Fable 5",
|
|
1495
|
+
reasoning: true,
|
|
1496
|
+
input: ["text", "image"],
|
|
1497
|
+
cost: ZERO_COST,
|
|
1498
|
+
contextWindow: 1e6,
|
|
1499
|
+
maxTokens: 65536
|
|
1500
|
+
},
|
|
1501
|
+
{
|
|
1502
|
+
id: "gpt-5-6-luna",
|
|
1503
|
+
kiroModelId: "gpt-5.6-luna",
|
|
1504
|
+
name: "GPT-5.6 Luna",
|
|
1505
|
+
reasoning: true,
|
|
1506
|
+
input: ["text", "image"],
|
|
1507
|
+
cost: ZERO_COST,
|
|
1508
|
+
contextWindow: 272e3,
|
|
1509
|
+
maxTokens: 128e3
|
|
1510
|
+
},
|
|
1511
|
+
{
|
|
1512
|
+
id: "gpt-5-6-sol",
|
|
1513
|
+
kiroModelId: "gpt-5.6-sol",
|
|
1514
|
+
name: "GPT-5.6 Sol",
|
|
1515
|
+
reasoning: true,
|
|
1516
|
+
input: ["text"],
|
|
1517
|
+
cost: ZERO_COST,
|
|
1518
|
+
contextWindow: 272e3,
|
|
1519
|
+
maxTokens: 128e3
|
|
1520
|
+
},
|
|
1521
|
+
{
|
|
1522
|
+
id: "gpt-5-6-terra",
|
|
1523
|
+
kiroModelId: "gpt-5.6-terra",
|
|
1524
|
+
name: "GPT-5.6 Terra",
|
|
1525
|
+
reasoning: true,
|
|
1526
|
+
input: ["text"],
|
|
1527
|
+
cost: ZERO_COST,
|
|
1528
|
+
contextWindow: 272e3,
|
|
1529
|
+
maxTokens: 128e3
|
|
1530
|
+
},
|
|
1531
|
+
{
|
|
1532
|
+
id: "deepseek-3-2",
|
|
1533
|
+
kiroModelId: "deepseek-3.2",
|
|
1534
|
+
name: "DeepSeek 3.2",
|
|
1535
|
+
reasoning: true,
|
|
1536
|
+
input: ["text"],
|
|
1537
|
+
cost: ZERO_COST,
|
|
1538
|
+
contextWindow: 164e3,
|
|
1539
|
+
maxTokens: 8192
|
|
1540
|
+
},
|
|
1541
|
+
{
|
|
1542
|
+
id: "minimax-m2-5",
|
|
1543
|
+
kiroModelId: "minimax-m2.5",
|
|
1544
|
+
name: "MiniMax M2.5",
|
|
1545
|
+
reasoning: false,
|
|
1546
|
+
input: ["text"],
|
|
1547
|
+
cost: ZERO_COST,
|
|
1548
|
+
contextWindow: 196e3,
|
|
1549
|
+
maxTokens: 8192
|
|
1550
|
+
},
|
|
1551
|
+
{
|
|
1552
|
+
id: "minimax-m2-1",
|
|
1553
|
+
kiroModelId: "minimax-m2.1",
|
|
1554
|
+
name: "MiniMax M2.1",
|
|
1555
|
+
reasoning: false,
|
|
1556
|
+
input: ["text"],
|
|
1557
|
+
cost: ZERO_COST,
|
|
1558
|
+
contextWindow: 196e3,
|
|
1559
|
+
maxTokens: 8192
|
|
1560
|
+
},
|
|
1561
|
+
{
|
|
1562
|
+
id: "glm-5",
|
|
1563
|
+
kiroModelId: "glm-5",
|
|
1564
|
+
name: "GLM 5",
|
|
1565
|
+
reasoning: true,
|
|
1566
|
+
input: ["text"],
|
|
1567
|
+
cost: ZERO_COST,
|
|
1568
|
+
contextWindow: 2e5,
|
|
1569
|
+
maxTokens: 8192
|
|
1570
|
+
},
|
|
1571
|
+
{
|
|
1572
|
+
id: "qwen3-coder-next",
|
|
1573
|
+
kiroModelId: "qwen3-coder-next",
|
|
1574
|
+
name: "Qwen3 Coder Next",
|
|
1575
|
+
reasoning: true,
|
|
1576
|
+
input: ["text"],
|
|
1577
|
+
cost: ZERO_COST,
|
|
1578
|
+
contextWindow: 256e3,
|
|
1579
|
+
maxTokens: 8192
|
|
1580
|
+
},
|
|
1581
|
+
{
|
|
1582
|
+
id: "auto",
|
|
1583
|
+
kiroModelId: "auto",
|
|
1584
|
+
name: "Auto",
|
|
1585
|
+
reasoning: true,
|
|
1586
|
+
input: ["text", "image"],
|
|
1587
|
+
cost: ZERO_COST,
|
|
1588
|
+
contextWindow: 1e6,
|
|
1589
|
+
maxTokens: 65536
|
|
1545
1590
|
}
|
|
1546
|
-
|
|
1591
|
+
];
|
|
1592
|
+
kiroModels = bootstrapKiroModels.map((model) => ({
|
|
1593
|
+
...model,
|
|
1594
|
+
...applyEffortLadder(model.reasoning ? getKiroEffortConfig(model.additionalModelRequestFieldsSchema, model.kiroModelId) : void 0),
|
|
1595
|
+
...model.id.startsWith("claude-") ? { recoverTextToolCalls: false } : {}
|
|
1596
|
+
}));
|
|
1597
|
+
BOOTSTRAP_KIRO_MODEL_IDS = kiroModels.map((model) => model.kiroModelId);
|
|
1598
|
+
KIRO_MODEL_IDS = new Set(BOOTSTRAP_KIRO_MODEL_IDS);
|
|
1547
1599
|
}
|
|
1548
1600
|
});
|
|
1549
1601
|
|
|
@@ -1611,8 +1663,8 @@ var require_base64_js = __commonJS({
|
|
|
1611
1663
|
}
|
|
1612
1664
|
return arr;
|
|
1613
1665
|
}
|
|
1614
|
-
function tripletToBase64(
|
|
1615
|
-
return lookup[
|
|
1666
|
+
function tripletToBase64(num2) {
|
|
1667
|
+
return lookup[num2 >> 18 & 63] + lookup[num2 >> 12 & 63] + lookup[num2 >> 6 & 63] + lookup[num2 & 63];
|
|
1616
1668
|
}
|
|
1617
1669
|
function encodeChunk(uint8, start, end) {
|
|
1618
1670
|
var tmp;
|
|
@@ -1705,6 +1757,10 @@ var KiroBlockBuffer = class {
|
|
|
1705
1757
|
getText(index) {
|
|
1706
1758
|
return this.blocks.get(index)?.text ?? "";
|
|
1707
1759
|
}
|
|
1760
|
+
/** Kinds of the live blocks, in allocation order. */
|
|
1761
|
+
kinds() {
|
|
1762
|
+
return [...this.blocks.values()].map((block) => block.kind);
|
|
1763
|
+
}
|
|
1708
1764
|
/**
|
|
1709
1765
|
* Rewrite one accumulated block before it is closed. Used by the recovery
|
|
1710
1766
|
* passes that lift tool calls out of text and by echo-noise stripping, both
|
|
@@ -1794,23 +1850,262 @@ function parseBracketToolCalls(text) {
|
|
|
1794
1850
|
}
|
|
1795
1851
|
return { toolCalls, cleanedText };
|
|
1796
1852
|
}
|
|
1797
|
-
|
|
1798
|
-
// ../kiro-core/dist/
|
|
1799
|
-
var
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
const
|
|
1804
|
-
const
|
|
1805
|
-
|
|
1853
|
+
|
|
1854
|
+
// ../kiro-core/dist/cache-estimator.js
|
|
1855
|
+
var stateByConversation = /* @__PURE__ */ new Map();
|
|
1856
|
+
var MAX_TRACKED_CONVERSATIONS = 128;
|
|
1857
|
+
var warnedWireCacheCounters = false;
|
|
1858
|
+
function applyCacheEstimate(conversationId, usage, wireUsage, config, now = Date.now()) {
|
|
1859
|
+
const previous = stateByConversation.get(conversationId);
|
|
1860
|
+
const promptTokens = usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0) + usage.output;
|
|
1861
|
+
const wireReportedCache = wireUsage?.cacheReadInputTokens !== void 0 || wireUsage?.cacheWriteInputTokens !== void 0;
|
|
1862
|
+
if (wireReportedCache) {
|
|
1863
|
+
if (config.estimateCacheUsage && !warnedWireCacheCounters) {
|
|
1864
|
+
warnedWireCacheCounters = true;
|
|
1865
|
+
console.warn("[kiro-core] Kiro now reports cache token counters; cache estimation was skipped and may be disabled.");
|
|
1866
|
+
}
|
|
1867
|
+
noteSuccessfulTurn(conversationId, promptTokens, usage.input, now);
|
|
1868
|
+
return 0;
|
|
1869
|
+
}
|
|
1870
|
+
if (!config.estimateCacheUsage || usage.input <= 0)
|
|
1871
|
+
return 0;
|
|
1872
|
+
if (!previous) {
|
|
1873
|
+
noteSuccessfulTurn(conversationId, promptTokens, usage.input, now);
|
|
1874
|
+
return 0;
|
|
1875
|
+
}
|
|
1876
|
+
const expired = config.estimatedCacheTimeout > 0 && now - previous.turnTimestamp > config.estimatedCacheTimeout;
|
|
1877
|
+
const contextShrank = usage.input < previous.promptTokens * 0.6;
|
|
1878
|
+
if (expired || contextShrank) {
|
|
1879
|
+
noteSuccessfulTurn(conversationId, promptTokens, usage.input, now);
|
|
1880
|
+
return 0;
|
|
1881
|
+
}
|
|
1882
|
+
const estimatedRead = Math.min(previous.promptTokens, usage.input);
|
|
1883
|
+
if (estimatedRead > 0) {
|
|
1884
|
+
usage.input -= estimatedRead;
|
|
1885
|
+
usage.cacheRead = (usage.cacheRead ?? 0) + estimatedRead;
|
|
1886
|
+
usage.cacheEstimated = true;
|
|
1887
|
+
}
|
|
1888
|
+
noteSuccessfulTurn(conversationId, promptTokens, promptTokens, now);
|
|
1889
|
+
return estimatedRead;
|
|
1890
|
+
}
|
|
1891
|
+
function noteSuccessfulTurn(conversationId, promptTokens, input, now) {
|
|
1892
|
+
if (input <= 0 || promptTokens <= 0)
|
|
1893
|
+
return;
|
|
1894
|
+
stateByConversation.delete(conversationId);
|
|
1895
|
+
stateByConversation.set(conversationId, { promptTokens, turnTimestamp: now });
|
|
1896
|
+
if (stateByConversation.size > MAX_TRACKED_CONVERSATIONS) {
|
|
1897
|
+
const oldest = stateByConversation.keys().next().value;
|
|
1898
|
+
if (oldest !== void 0)
|
|
1899
|
+
stateByConversation.delete(oldest);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
// ../kiro-core/dist/cost.js
|
|
1904
|
+
var PER_MILLION = 1e6;
|
|
1905
|
+
function calculateKiroCost(cost, usage) {
|
|
1906
|
+
const input = usage.input * cost.input / PER_MILLION;
|
|
1907
|
+
const output = usage.output * cost.output / PER_MILLION;
|
|
1908
|
+
const cacheRead = (usage.cacheRead ?? 0) * cost.cacheRead / PER_MILLION;
|
|
1909
|
+
const cacheWrite = (usage.cacheWrite ?? 0) * cost.cacheWrite / PER_MILLION;
|
|
1910
|
+
return { input, output, cacheRead, cacheWrite, total: input + output + cacheRead + cacheWrite };
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
// ../kiro-core/dist/index.js
|
|
1914
|
+
init_debug();
|
|
1915
|
+
init_effort();
|
|
1916
|
+
init_endpoints();
|
|
1917
|
+
|
|
1918
|
+
// ../kiro-core/dist/retry.js
|
|
1919
|
+
init_models();
|
|
1920
|
+
var FIRST_TOKEN_TIMEOUT = 9e4;
|
|
1921
|
+
var REQUEST_HEADER_TIMEOUT = 9e4;
|
|
1922
|
+
function firstTokenTimeoutForModel(modelId) {
|
|
1923
|
+
if (retryConfig.firstTokenTimeoutMs !== FIRST_TOKEN_TIMEOUT) {
|
|
1924
|
+
return retryConfig.firstTokenTimeoutMs;
|
|
1925
|
+
}
|
|
1926
|
+
const model = kiroModels.find((m) => m.id === modelId);
|
|
1927
|
+
return model?.firstTokenTimeout ?? FIRST_TOKEN_TIMEOUT;
|
|
1928
|
+
}
|
|
1929
|
+
var retryConfig = {
|
|
1930
|
+
firstTokenTimeoutMs: FIRST_TOKEN_TIMEOUT,
|
|
1931
|
+
requestHeaderTimeoutMs: REQUEST_HEADER_TIMEOUT
|
|
1932
|
+
};
|
|
1933
|
+
function exponentialBackoff(attempt, baseMs, maxMs) {
|
|
1934
|
+
return Math.min(baseMs * 2 ** attempt, maxMs);
|
|
1935
|
+
}
|
|
1936
|
+
var MAX_RETRY_DELAY = 1e4;
|
|
1937
|
+
var REQUEST_RATE_FALLBACK_DELAY_MS = 1e4;
|
|
1938
|
+
function extractKiroReason(errorText) {
|
|
1939
|
+
if (!errorText)
|
|
1940
|
+
return void 0;
|
|
1941
|
+
try {
|
|
1942
|
+
const parsed = JSON.parse(errorText);
|
|
1943
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
1944
|
+
return void 0;
|
|
1945
|
+
const reason = parsed.reason;
|
|
1946
|
+
return typeof reason === "string" && reason.length > 0 ? reason : void 0;
|
|
1947
|
+
} catch {
|
|
1948
|
+
return void 0;
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
function parseRetryAfterMs(headers, nowMs = Date.now()) {
|
|
1952
|
+
const get = headers?.get?.bind(headers);
|
|
1953
|
+
if (!get)
|
|
1954
|
+
return void 0;
|
|
1955
|
+
const milliseconds = nonNegativeNumber(get("retry-after-ms"));
|
|
1956
|
+
if (milliseconds !== void 0)
|
|
1957
|
+
return Math.round(milliseconds);
|
|
1958
|
+
const retryAfter = get("retry-after");
|
|
1959
|
+
if (retryAfter !== null && retryAfter.trim() !== "") {
|
|
1960
|
+
const seconds = Number(retryAfter);
|
|
1961
|
+
if (Number.isFinite(seconds)) {
|
|
1962
|
+
if (seconds >= 0) {
|
|
1963
|
+
const delayMs = seconds * 1e3;
|
|
1964
|
+
if (Number.isFinite(delayMs))
|
|
1965
|
+
return Math.round(delayMs);
|
|
1966
|
+
}
|
|
1967
|
+
} else {
|
|
1968
|
+
const dateMs = Date.parse(retryAfter);
|
|
1969
|
+
if (!Number.isNaN(dateMs))
|
|
1970
|
+
return Math.max(0, dateMs - nowMs);
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
const resetAfterSeconds = nonNegativeNumber(get("x-ratelimit-reset-after"));
|
|
1974
|
+
if (resetAfterSeconds !== void 0) {
|
|
1975
|
+
const delayMs = resetAfterSeconds * 1e3;
|
|
1976
|
+
if (Number.isFinite(delayMs))
|
|
1977
|
+
return Math.round(delayMs);
|
|
1978
|
+
}
|
|
1979
|
+
return void 0;
|
|
1980
|
+
}
|
|
1981
|
+
function resolveRequestRateRetryDelay(headers, nowMs = Date.now()) {
|
|
1982
|
+
const advertisedDelayMs = parseRetryAfterMs(headers, nowMs);
|
|
1983
|
+
const requestedDelayMs = advertisedDelayMs ?? REQUEST_RATE_FALLBACK_DELAY_MS;
|
|
1984
|
+
return {
|
|
1985
|
+
delayMs: Math.min(requestedDelayMs, MAX_RETRY_DELAY),
|
|
1986
|
+
...advertisedDelayMs !== void 0 ? { advertisedDelayMs } : {},
|
|
1987
|
+
capped: requestedDelayMs > MAX_RETRY_DELAY
|
|
1988
|
+
};
|
|
1989
|
+
}
|
|
1990
|
+
function nonNegativeNumber(value) {
|
|
1991
|
+
if (value === null || value.trim() === "")
|
|
1992
|
+
return void 0;
|
|
1993
|
+
const parsed = Number(value);
|
|
1994
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
|
|
1995
|
+
}
|
|
1996
|
+
var KIRO_REASON_CODES = Object.freeze({
|
|
1997
|
+
/** Request body exceeded the service's size threshold. */
|
|
1998
|
+
CONTENT_LENGTH_EXCEEDS_THRESHOLD: "CONTENT_LENGTH_EXCEEDS_THRESHOLD",
|
|
1999
|
+
/** Prose-only size rejection; the service sends no reason code for this one. */
|
|
2000
|
+
INPUT_TOO_LONG: "Input is too long",
|
|
2001
|
+
/** Monthly request quota exhausted — hard limit, not transient. */
|
|
2002
|
+
MONTHLY_REQUEST_COUNT: "MONTHLY_REQUEST_COUNT",
|
|
2003
|
+
/** Model capacity temporarily unavailable — transient, worth retrying. */
|
|
2004
|
+
INSUFFICIENT_MODEL_CAPACITY: "INSUFFICIENT_MODEL_CAPACITY",
|
|
2005
|
+
/** Short-window request throttle — retry only within the provider budget. */
|
|
2006
|
+
USER_REQUEST_RATE_EXCEEDED: "USER_REQUEST_RATE_EXCEEDED",
|
|
2007
|
+
/**
|
|
2008
|
+
* Generic request-validation rejection, returned for a malformed body of any
|
|
2009
|
+
* size (empty `content`, history referencing tools absent from the catalog).
|
|
2010
|
+
* Not a size signal: classifying it as "too big" makes the caller compact a
|
|
2011
|
+
* history that was never the problem, a loop it can never satisfy.
|
|
2012
|
+
*/
|
|
2013
|
+
REQUEST_BODY_INVALID: "REQUEST_BODY_INVALID"
|
|
2014
|
+
});
|
|
2015
|
+
var TOO_BIG_PATTERNS = Object.freeze([
|
|
2016
|
+
KIRO_REASON_CODES.CONTENT_LENGTH_EXCEEDS_THRESHOLD,
|
|
2017
|
+
KIRO_REASON_CODES.INPUT_TOO_LONG
|
|
2018
|
+
]);
|
|
2019
|
+
var NON_RETRYABLE_BODY_PATTERNS = Object.freeze([KIRO_REASON_CODES.MONTHLY_REQUEST_COUNT]);
|
|
2020
|
+
var CAPACITY_PATTERN = KIRO_REASON_CODES.INSUFFICIENT_MODEL_CAPACITY;
|
|
2021
|
+
var CAPACITY_MAX_RETRIES = 3;
|
|
2022
|
+
var CAPACITY_BASE_DELAY_MS = 5e3;
|
|
2023
|
+
var capacityRetryConfig = {
|
|
2024
|
+
maxRetries: CAPACITY_MAX_RETRIES,
|
|
2025
|
+
baseDelayMs: CAPACITY_BASE_DELAY_MS
|
|
2026
|
+
};
|
|
2027
|
+
function isTooBigError(status, errorText) {
|
|
2028
|
+
return status === 413 || status === 400 && TOO_BIG_PATTERNS.some((p) => errorText.includes(p));
|
|
2029
|
+
}
|
|
2030
|
+
function isNonRetryableBodyError(errorText) {
|
|
2031
|
+
return NON_RETRYABLE_BODY_PATTERNS.some((p) => errorText.includes(p));
|
|
2032
|
+
}
|
|
2033
|
+
function isCapacityError(errorText) {
|
|
2034
|
+
return errorText.includes(CAPACITY_PATTERN);
|
|
1806
2035
|
}
|
|
1807
2036
|
|
|
1808
|
-
// ../kiro-core/dist/
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
2037
|
+
// ../kiro-core/dist/errors.js
|
|
2038
|
+
var REASON_CODE_MARKERS = [
|
|
2039
|
+
KIRO_REASON_CODES.CONTENT_LENGTH_EXCEEDS_THRESHOLD,
|
|
2040
|
+
KIRO_REASON_CODES.MONTHLY_REQUEST_COUNT,
|
|
2041
|
+
KIRO_REASON_CODES.INSUFFICIENT_MODEL_CAPACITY,
|
|
2042
|
+
KIRO_REASON_CODES.REQUEST_BODY_INVALID
|
|
2043
|
+
];
|
|
2044
|
+
var KiroApiError = class extends Error {
|
|
2045
|
+
status;
|
|
2046
|
+
reasonCode;
|
|
2047
|
+
retryAfterMs;
|
|
2048
|
+
providerAttempts;
|
|
2049
|
+
constructor(message, status, reasonCode, retryAfterMs, providerAttempts) {
|
|
2050
|
+
super(message);
|
|
2051
|
+
this.status = status;
|
|
2052
|
+
this.reasonCode = reasonCode;
|
|
2053
|
+
this.retryAfterMs = retryAfterMs;
|
|
2054
|
+
this.providerAttempts = providerAttempts;
|
|
2055
|
+
this.name = "KiroApiError";
|
|
2056
|
+
}
|
|
2057
|
+
};
|
|
2058
|
+
function extractKiroReasonCode(errorText) {
|
|
2059
|
+
if (!errorText)
|
|
2060
|
+
return void 0;
|
|
2061
|
+
const trimmed = errorText.trim();
|
|
2062
|
+
if (trimmed.startsWith("{")) {
|
|
2063
|
+
try {
|
|
2064
|
+
const parsed = JSON.parse(trimmed);
|
|
2065
|
+
const reason = parsed.reason ?? parsed.reasonCode;
|
|
2066
|
+
if (typeof reason === "string" && reason.length > 0)
|
|
2067
|
+
return reason;
|
|
2068
|
+
} catch {
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
return REASON_CODE_MARKERS.find((code) => errorText.includes(code));
|
|
2072
|
+
}
|
|
1812
2073
|
|
|
1813
2074
|
// ../kiro-core/dist/event-parser.js
|
|
2075
|
+
var KIRO_EVENT_KEYS = [
|
|
2076
|
+
"assistantResponseEvent",
|
|
2077
|
+
"codeReferenceEvent",
|
|
2078
|
+
"contextUsageEvent",
|
|
2079
|
+
"documentCitationEvent",
|
|
2080
|
+
"error",
|
|
2081
|
+
"metadataEvent",
|
|
2082
|
+
"meteringEvent",
|
|
2083
|
+
"reasoningContentEvent",
|
|
2084
|
+
"serviceUnavailableError",
|
|
2085
|
+
"throttlingError",
|
|
2086
|
+
"toolResultEvent",
|
|
2087
|
+
"toolUseEvent",
|
|
2088
|
+
"validationError"
|
|
2089
|
+
];
|
|
2090
|
+
var KIRO_EVENT_KEY_SET = new Set(KIRO_EVENT_KEYS);
|
|
2091
|
+
var KIRO_ERROR_MEMBERS = {
|
|
2092
|
+
error: { kind: "internalServer", exception: "InternalServerException" },
|
|
2093
|
+
throttlingError: { kind: "throttling", exception: "ThrottlingException" },
|
|
2094
|
+
validationError: { kind: "validation", exception: "ValidationException" },
|
|
2095
|
+
serviceUnavailableError: { kind: "serviceUnavailable", exception: "ServiceUnavailableException" }
|
|
2096
|
+
};
|
|
2097
|
+
var KIRO_ERROR_TOKENS = {
|
|
2098
|
+
...KIRO_ERROR_MEMBERS,
|
|
2099
|
+
InternalServerException: KIRO_ERROR_MEMBERS.error,
|
|
2100
|
+
ThrottlingException: KIRO_ERROR_MEMBERS.throttlingError,
|
|
2101
|
+
ValidationException: KIRO_ERROR_MEMBERS.validationError,
|
|
2102
|
+
ServiceUnavailableException: KIRO_ERROR_MEMBERS.serviceUnavailableError
|
|
2103
|
+
};
|
|
2104
|
+
function lookupKiroErrorMember(key) {
|
|
2105
|
+
return Object.hasOwn(KIRO_ERROR_TOKENS, key) ? KIRO_ERROR_TOKENS[key] : void 0;
|
|
2106
|
+
}
|
|
2107
|
+
var num = (v) => typeof v === "number" ? v : void 0;
|
|
2108
|
+
var str = (v) => typeof v === "string" ? v : void 0;
|
|
1814
2109
|
function tokenCount(value) {
|
|
1815
2110
|
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
1816
2111
|
}
|
|
@@ -1829,30 +2124,136 @@ var CACHE_WRITE_KEYS = [
|
|
|
1829
2124
|
"cacheCreationInputTokens",
|
|
1830
2125
|
"cacheWriteTokens"
|
|
1831
2126
|
];
|
|
1832
|
-
function
|
|
1833
|
-
if (
|
|
1834
|
-
return
|
|
1835
|
-
if (typeof
|
|
1836
|
-
return
|
|
1837
|
-
|
|
1838
|
-
|
|
2127
|
+
function toolInput(raw) {
|
|
2128
|
+
if (typeof raw === "string")
|
|
2129
|
+
return raw;
|
|
2130
|
+
if (raw && typeof raw === "object" && Object.keys(raw).length > 0) {
|
|
2131
|
+
return JSON.stringify(raw);
|
|
2132
|
+
}
|
|
2133
|
+
return "";
|
|
2134
|
+
}
|
|
2135
|
+
function parseToolUse(parsed) {
|
|
1839
2136
|
if (parsed.name && parsed.toolUseId) {
|
|
1840
|
-
const input = typeof parsed.input === "string" ? parsed.input : parsed.input && typeof parsed.input === "object" && Object.keys(parsed.input).length > 0 ? JSON.stringify(parsed.input) : "";
|
|
1841
2137
|
return {
|
|
1842
2138
|
type: "toolUse",
|
|
1843
2139
|
data: {
|
|
1844
2140
|
name: parsed.name,
|
|
1845
2141
|
toolUseId: parsed.toolUseId,
|
|
1846
|
-
input,
|
|
2142
|
+
input: toolInput(parsed.input),
|
|
1847
2143
|
stop: parsed.stop
|
|
1848
2144
|
}
|
|
1849
2145
|
};
|
|
1850
2146
|
}
|
|
2147
|
+
if (parsed.input !== void 0) {
|
|
2148
|
+
return { type: "toolUseInput", data: { input: toolInput(parsed.input) } };
|
|
2149
|
+
}
|
|
2150
|
+
if (parsed.stop !== void 0)
|
|
2151
|
+
return { type: "toolUseStop", data: { stop: parsed.stop } };
|
|
2152
|
+
return null;
|
|
2153
|
+
}
|
|
2154
|
+
function parseMetadata(parsed) {
|
|
2155
|
+
const tu = parsed.tokenUsage ?? {};
|
|
2156
|
+
const data = {
|
|
2157
|
+
inputTokens: tokenCount(tu.uncachedInputTokens) ?? tokenCount(tu.inputTokens),
|
|
2158
|
+
outputTokens: tokenCount(tu.outputTokens),
|
|
2159
|
+
totalTokens: tokenCount(tu.totalTokens),
|
|
2160
|
+
cacheReadInputTokens: firstTokenCount(tu, CACHE_READ_KEYS),
|
|
2161
|
+
cacheWriteInputTokens: firstTokenCount(tu, CACHE_WRITE_KEYS),
|
|
2162
|
+
contextUsagePercentage: num(tu.contextUsagePercentage),
|
|
2163
|
+
normalizedTokenUsage: num(tu.normalizedTokenUsage),
|
|
2164
|
+
rawStopReason: str(parsed.stopReason),
|
|
2165
|
+
stopDetails: parsed.stopDetails && typeof parsed.stopDetails === "object" ? parsed.stopDetails : void 0
|
|
2166
|
+
};
|
|
2167
|
+
for (const k of Object.keys(data)) {
|
|
2168
|
+
if (data[k] === void 0)
|
|
2169
|
+
delete data[k];
|
|
2170
|
+
}
|
|
2171
|
+
return Object.keys(data).length > 0 ? { type: "usage", data } : null;
|
|
2172
|
+
}
|
|
2173
|
+
function parseError(parsed, kind, fallbackName) {
|
|
2174
|
+
const rawError = parsed.error ?? parsed.Error;
|
|
2175
|
+
const error2 = typeof rawError === "string" ? rawError : rawError !== void 0 ? JSON.stringify(rawError) : str(parsed.name) ?? fallbackName;
|
|
2176
|
+
const message = parsed.message ?? parsed.Message ?? parsed.reason;
|
|
2177
|
+
const data = { error: error2, kind };
|
|
2178
|
+
if (typeof message === "string")
|
|
2179
|
+
data.message = message;
|
|
2180
|
+
const reason = str(parsed.reason);
|
|
2181
|
+
if (reason !== void 0)
|
|
2182
|
+
data.reason = reason;
|
|
2183
|
+
const retryAfterMilliseconds = num(parsed.retryAfterMilliseconds);
|
|
2184
|
+
if (retryAfterMilliseconds !== void 0)
|
|
2185
|
+
data.retryAfterMilliseconds = retryAfterMilliseconds;
|
|
2186
|
+
return { type: "error", data };
|
|
2187
|
+
}
|
|
2188
|
+
function parseKiroEvent(key, parsed) {
|
|
2189
|
+
switch (key) {
|
|
2190
|
+
case "assistantResponseEvent": {
|
|
2191
|
+
const content = str(parsed.content);
|
|
2192
|
+
return content !== void 0 ? { type: "content", data: content } : null;
|
|
2193
|
+
}
|
|
2194
|
+
case "reasoningContentEvent": {
|
|
2195
|
+
const text = str(parsed.text);
|
|
2196
|
+
if (text !== void 0)
|
|
2197
|
+
return { type: "thinkingText", data: text };
|
|
2198
|
+
const signature = str(parsed.signature);
|
|
2199
|
+
if (signature !== void 0)
|
|
2200
|
+
return { type: "thinkingSignature", data: signature };
|
|
2201
|
+
return { type: "ignored", data: { key } };
|
|
2202
|
+
}
|
|
2203
|
+
case "toolUseEvent":
|
|
2204
|
+
return parseToolUse(parsed);
|
|
2205
|
+
case "contextUsageEvent": {
|
|
2206
|
+
const pct = num(parsed.contextUsagePercentage);
|
|
2207
|
+
return pct !== void 0 ? { type: "contextUsage", data: { contextUsagePercentage: pct } } : null;
|
|
2208
|
+
}
|
|
2209
|
+
case "metadataEvent":
|
|
2210
|
+
return parseMetadata(parsed);
|
|
2211
|
+
case "meteringEvent":
|
|
2212
|
+
return {
|
|
2213
|
+
type: "metering",
|
|
2214
|
+
data: { credits: tokenCount(parsed.usage), unit: str(parsed.unit), unitPlural: str(parsed.unitPlural) }
|
|
2215
|
+
};
|
|
2216
|
+
// Reachable when a member that models an exception is delivered as an
|
|
2217
|
+
// ordinary event frame. The real wire uses exception framing, handled by
|
|
2218
|
+
// parseKiroExceptionFrame, but both routes must agree.
|
|
2219
|
+
case "error":
|
|
2220
|
+
case "throttlingError":
|
|
2221
|
+
case "validationError":
|
|
2222
|
+
case "serviceUnavailableError": {
|
|
2223
|
+
const member = lookupKiroErrorMember(key);
|
|
2224
|
+
return parseError(parsed, member.kind, member.exception);
|
|
2225
|
+
}
|
|
2226
|
+
// Known members with no consumer yet: explicitly ignored, not unparseable.
|
|
2227
|
+
case "codeReferenceEvent":
|
|
2228
|
+
case "documentCitationEvent":
|
|
2229
|
+
case "toolResultEvent":
|
|
2230
|
+
return { type: "ignored", data: { key } };
|
|
2231
|
+
default: {
|
|
2232
|
+
const member = lookupKiroErrorMember(key);
|
|
2233
|
+
if (member)
|
|
2234
|
+
return parseError(parsed, member.kind, member.exception);
|
|
2235
|
+
return parseKiroEventByShape(parsed);
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
function parseKiroExceptionFrame(key, parsed) {
|
|
2240
|
+
const member = lookupKiroErrorMember(key);
|
|
2241
|
+
if (!member)
|
|
2242
|
+
return null;
|
|
2243
|
+
const event = parseError(parsed, member.kind, member.exception);
|
|
2244
|
+
return event.data;
|
|
2245
|
+
}
|
|
2246
|
+
function parseKiroEventByShape(parsed) {
|
|
2247
|
+
if (parsed.content !== void 0)
|
|
2248
|
+
return { type: "content", data: parsed.content };
|
|
2249
|
+
if (typeof parsed.text === "string")
|
|
2250
|
+
return { type: "thinkingText", data: parsed.text };
|
|
2251
|
+
if (typeof parsed.signature === "string")
|
|
2252
|
+
return { type: "thinkingSignature", data: parsed.signature };
|
|
2253
|
+
if (parsed.name && parsed.toolUseId)
|
|
2254
|
+
return parseToolUse(parsed);
|
|
1851
2255
|
if (parsed.input !== void 0 && !parsed.name) {
|
|
1852
|
-
return {
|
|
1853
|
-
type: "toolUseInput",
|
|
1854
|
-
data: { input: typeof parsed.input === "string" ? parsed.input : JSON.stringify(parsed.input) }
|
|
1855
|
-
};
|
|
2256
|
+
return { type: "toolUseInput", data: { input: toolInput(parsed.input) } };
|
|
1856
2257
|
}
|
|
1857
2258
|
if (parsed.stop !== void 0 && parsed.contextUsagePercentage === void 0)
|
|
1858
2259
|
return { type: "toolUseStop", data: { stop: parsed.stop } };
|
|
@@ -1860,42 +2261,23 @@ function parseKiroEvent(parsed) {
|
|
|
1860
2261
|
return { type: "contextUsage", data: { contextUsagePercentage: parsed.contextUsagePercentage } };
|
|
1861
2262
|
if (parsed.followupPrompt !== void 0)
|
|
1862
2263
|
return { type: "followupPrompt", data: parsed.followupPrompt };
|
|
2264
|
+
if (parsed.tokenUsage !== void 0 || parsed.stopReason !== void 0 || parsed.stopDetails !== void 0) {
|
|
2265
|
+
return parseMetadata(parsed);
|
|
2266
|
+
}
|
|
1863
2267
|
if (parsed.error !== void 0 || parsed.Error !== void 0) {
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
}
|
|
1868
|
-
if (parsed.usage !== void 0) {
|
|
1869
|
-
if (typeof parsed.usage === "number") {
|
|
1870
|
-
const credits = tokenCount(parsed.usage);
|
|
1871
|
-
if (credits === void 0)
|
|
1872
|
-
return null;
|
|
1873
|
-
return {
|
|
1874
|
-
type: "usage",
|
|
1875
|
-
data: {
|
|
1876
|
-
credits,
|
|
1877
|
-
...typeof parsed.unit === "string" && parsed.unit ? { creditUnit: parsed.unit } : {}
|
|
1878
|
-
}
|
|
1879
|
-
};
|
|
1880
|
-
}
|
|
1881
|
-
const u = parsed.usage;
|
|
1882
|
-
const cacheReadTokens = firstTokenCount(u, CACHE_READ_KEYS);
|
|
1883
|
-
const cacheWriteTokens = firstTokenCount(u, CACHE_WRITE_KEYS);
|
|
2268
|
+
return parseError(parsed, "unknown", "unknown");
|
|
2269
|
+
}
|
|
2270
|
+
if (typeof parsed.usage === "number") {
|
|
1884
2271
|
return {
|
|
1885
|
-
type: "
|
|
1886
|
-
data: {
|
|
1887
|
-
inputTokens: tokenCount(u.inputTokens),
|
|
1888
|
-
outputTokens: tokenCount(u.outputTokens),
|
|
1889
|
-
...cacheReadTokens !== void 0 ? { cacheReadTokens } : {},
|
|
1890
|
-
...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {}
|
|
1891
|
-
}
|
|
2272
|
+
type: "metering",
|
|
2273
|
+
data: { credits: tokenCount(parsed.usage), unit: str(parsed.unit), unitPlural: str(parsed.unitPlural) }
|
|
1892
2274
|
};
|
|
1893
2275
|
}
|
|
1894
2276
|
return null;
|
|
1895
2277
|
}
|
|
1896
2278
|
|
|
1897
2279
|
// ../kiro-core/dist/transform.js
|
|
1898
|
-
import { createHash } from "node:crypto";
|
|
2280
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
1899
2281
|
var TOOL_RESULT_LIMIT = 25e4;
|
|
1900
2282
|
var EMPTY_CONTENT_PLACEHOLDER = "Please proceed with the task.";
|
|
1901
2283
|
function sanitizeSurrogates(text) {
|
|
@@ -1913,7 +2295,7 @@ var KIRO_TOOL_USE_ID_PATTERN = /^[a-zA-Z0-9_.:-]{1,64}$/;
|
|
|
1913
2295
|
function toKiroToolUseId(toolUseId) {
|
|
1914
2296
|
if (KIRO_TOOL_USE_ID_PATTERN.test(toolUseId))
|
|
1915
2297
|
return toolUseId;
|
|
1916
|
-
const digest =
|
|
2298
|
+
const digest = createHash2("sha256").update(toolUseId).digest("base64url").slice(0, 32);
|
|
1917
2299
|
return `pi_${digest}`;
|
|
1918
2300
|
}
|
|
1919
2301
|
function normalizeMessages(messages) {
|
|
@@ -2927,8 +3309,8 @@ function bytePairEncode(piece, ranks) {
|
|
|
2927
3309
|
return [ranks.get(piece.join(","))];
|
|
2928
3310
|
return bytePairMerge(piece, ranks).map((p) => ranks.get(piece.slice(p.start, p.end).join(","))).filter((x) => x != null);
|
|
2929
3311
|
}
|
|
2930
|
-
function escapeRegex(
|
|
2931
|
-
return
|
|
3312
|
+
function escapeRegex(str2) {
|
|
3313
|
+
return str2.replace(/[\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
2932
3314
|
}
|
|
2933
3315
|
var _Tiktoken = class {
|
|
2934
3316
|
/** @internal */
|
|
@@ -3075,6 +3457,7 @@ var KiroResponseAssembler = class {
|
|
|
3075
3457
|
totalContent = "";
|
|
3076
3458
|
lastContentData = "";
|
|
3077
3459
|
usageEvent = null;
|
|
3460
|
+
meteringEvent = null;
|
|
3078
3461
|
receivedContextUsage = false;
|
|
3079
3462
|
thinkingParser = null;
|
|
3080
3463
|
nativeThinkingBlockIndex = null;
|
|
@@ -3082,16 +3465,19 @@ var KiroResponseAssembler = class {
|
|
|
3082
3465
|
textBlockIndex = null;
|
|
3083
3466
|
emittedToolCalls = 0;
|
|
3084
3467
|
sawAnyToolCalls = false;
|
|
3468
|
+
droppedToolCalls = [];
|
|
3085
3469
|
currentToolCall = null;
|
|
3470
|
+
stopReason = "stop";
|
|
3086
3471
|
constructor(model, thinkingEnabled) {
|
|
3087
3472
|
this.model = model;
|
|
3088
3473
|
this.thinkingEnabled = thinkingEnabled;
|
|
3089
3474
|
}
|
|
3090
|
-
/** Clear per-attempt state.
|
|
3475
|
+
/** Clear per-attempt state. Only block indexes are kept. */
|
|
3091
3476
|
beginAttempt() {
|
|
3092
3477
|
this.totalContent = "";
|
|
3093
3478
|
this.lastContentData = "";
|
|
3094
3479
|
this.usageEvent = null;
|
|
3480
|
+
this.meteringEvent = null;
|
|
3095
3481
|
this.receivedContextUsage = false;
|
|
3096
3482
|
this.thinkingParser = this.thinkingEnabled ? new ThinkingTagParser(this.blocks) : null;
|
|
3097
3483
|
this.nativeThinkingBlockIndex = null;
|
|
@@ -3099,7 +3485,17 @@ var KiroResponseAssembler = class {
|
|
|
3099
3485
|
this.textBlockIndex = null;
|
|
3100
3486
|
this.emittedToolCalls = 0;
|
|
3101
3487
|
this.sawAnyToolCalls = false;
|
|
3488
|
+
this.droppedToolCalls = [];
|
|
3102
3489
|
this.currentToolCall = null;
|
|
3490
|
+
this.usage.input = 0;
|
|
3491
|
+
this.usage.output = 0;
|
|
3492
|
+
this.usage.totalTokens = 0;
|
|
3493
|
+
this.usage.cost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 };
|
|
3494
|
+
delete this.usage.cacheRead;
|
|
3495
|
+
delete this.usage.cacheWrite;
|
|
3496
|
+
delete this.usage.contextPercent;
|
|
3497
|
+
delete this.usage.credits;
|
|
3498
|
+
delete this.usage.creditUnit;
|
|
3103
3499
|
}
|
|
3104
3500
|
/** Hand over the events buffered so far. */
|
|
3105
3501
|
takeEvents() {
|
|
@@ -3176,11 +3572,17 @@ var KiroResponseAssembler = class {
|
|
|
3176
3572
|
break;
|
|
3177
3573
|
}
|
|
3178
3574
|
case "usage": {
|
|
3179
|
-
this.usageEvent = event.data;
|
|
3575
|
+
this.usageEvent = { ...this.usageEvent ?? {}, ...event.data };
|
|
3180
3576
|
if (debugEnabled())
|
|
3181
3577
|
debugLog("response.usageRaw", payload);
|
|
3182
3578
|
break;
|
|
3183
3579
|
}
|
|
3580
|
+
case "metering": {
|
|
3581
|
+
this.meteringEvent = event.data;
|
|
3582
|
+
if (debugEnabled())
|
|
3583
|
+
debugLog("stream.metering", [event.data]);
|
|
3584
|
+
break;
|
|
3585
|
+
}
|
|
3184
3586
|
}
|
|
3185
3587
|
}
|
|
3186
3588
|
/**
|
|
@@ -3188,8 +3590,12 @@ var KiroResponseAssembler = class {
|
|
|
3188
3590
|
* text-dialect recovery and echo-stripping passes.
|
|
3189
3591
|
*/
|
|
3190
3592
|
endTurn() {
|
|
3191
|
-
if (this.currentToolCall
|
|
3192
|
-
this.
|
|
3593
|
+
if (this.currentToolCall) {
|
|
3594
|
+
if (this.emitToolCall(this.currentToolCall))
|
|
3595
|
+
this.emittedToolCalls++;
|
|
3596
|
+
else
|
|
3597
|
+
this.droppedToolCalls.push(this.currentToolCall.name);
|
|
3598
|
+
}
|
|
3193
3599
|
this.currentToolCall = null;
|
|
3194
3600
|
this.endNativeThinking();
|
|
3195
3601
|
if (this.thinkingParser) {
|
|
@@ -3200,13 +3606,16 @@ var KiroResponseAssembler = class {
|
|
|
3200
3606
|
this.stripEchoNoise();
|
|
3201
3607
|
const responseText = this.textBlockIndex === null ? "" : this.blocks.getText(this.textBlockIndex);
|
|
3202
3608
|
const hasText2 = responseText.length > 0;
|
|
3609
|
+
this.stopReason = !this.receivedContextUsage && this.emittedToolCalls === 0 ? "length" : this.emittedToolCalls > 0 ? "toolUse" : "stop";
|
|
3203
3610
|
return {
|
|
3204
3611
|
responseText,
|
|
3205
3612
|
hasText: hasText2,
|
|
3206
3613
|
sawAnyToolCalls: this.sawAnyToolCalls,
|
|
3207
3614
|
emittedToolCalls: this.emittedToolCalls,
|
|
3208
3615
|
isEchoLoop: hasText2 && !this.sawAnyToolCalls && ECHO_NOISE_PATTERN.test(responseText),
|
|
3209
|
-
isEmpty: !hasText2 && !this.sawAnyToolCalls
|
|
3616
|
+
isEmpty: !hasText2 && !this.sawAnyToolCalls,
|
|
3617
|
+
stopReason: this.stopReason,
|
|
3618
|
+
droppedToolCalls: this.droppedToolCalls
|
|
3210
3619
|
};
|
|
3211
3620
|
}
|
|
3212
3621
|
/** Drop an echo the caller decided not to retry, so it is not read as a continuation signal. */
|
|
@@ -3214,6 +3623,10 @@ var KiroResponseAssembler = class {
|
|
|
3214
3623
|
if (this.textBlockIndex !== null)
|
|
3215
3624
|
this.blocks.setText(this.textBlockIndex, "");
|
|
3216
3625
|
}
|
|
3626
|
+
/** Kinds of the blocks this attempt produced, for the exhaustion diagnostic. */
|
|
3627
|
+
contentKinds() {
|
|
3628
|
+
return this.blocks.kinds();
|
|
3629
|
+
}
|
|
3217
3630
|
/** Close the text block and settle usage and the stop reason. */
|
|
3218
3631
|
complete() {
|
|
3219
3632
|
if (this.textBlockIndex !== null)
|
|
@@ -3221,17 +3634,17 @@ var KiroResponseAssembler = class {
|
|
|
3221
3634
|
if (this.usageEvent?.inputTokens !== void 0)
|
|
3222
3635
|
this.usage.input = this.usageEvent.inputTokens;
|
|
3223
3636
|
this.usage.output = this.usageEvent?.outputTokens ?? countTokens(this.totalContent);
|
|
3224
|
-
this.usage.totalTokens = this.usage.input + this.usage.output;
|
|
3225
|
-
if (this.usageEvent?.
|
|
3226
|
-
this.usage.cacheRead = this.usageEvent.
|
|
3227
|
-
if (this.usageEvent?.
|
|
3228
|
-
this.usage.cacheWrite = this.usageEvent.
|
|
3229
|
-
if (this.
|
|
3230
|
-
this.usage.credits = this.
|
|
3231
|
-
if (this.
|
|
3232
|
-
this.usage.creditUnit = this.
|
|
3637
|
+
this.usage.totalTokens = this.usageEvent?.totalTokens ?? this.usage.input + (this.usageEvent?.cacheReadInputTokens ?? 0) + (this.usageEvent?.cacheWriteInputTokens ?? 0) + this.usage.output;
|
|
3638
|
+
if (this.usageEvent?.cacheReadInputTokens !== void 0)
|
|
3639
|
+
this.usage.cacheRead = this.usageEvent.cacheReadInputTokens;
|
|
3640
|
+
if (this.usageEvent?.cacheWriteInputTokens !== void 0)
|
|
3641
|
+
this.usage.cacheWrite = this.usageEvent.cacheWriteInputTokens;
|
|
3642
|
+
if (this.meteringEvent?.credits !== void 0)
|
|
3643
|
+
this.usage.credits = this.meteringEvent.credits;
|
|
3644
|
+
if (this.meteringEvent?.unit !== void 0)
|
|
3645
|
+
this.usage.creditUnit = this.meteringEvent.unit;
|
|
3233
3646
|
this.usage.cost = calculateKiroCost(this.model.cost, this.usage);
|
|
3234
|
-
const stopReason =
|
|
3647
|
+
const stopReason = this.stopReason;
|
|
3235
3648
|
debugLog("response.done", {
|
|
3236
3649
|
stopReason,
|
|
3237
3650
|
receivedContextUsage: this.receivedContextUsage,
|
|
@@ -3240,7 +3653,12 @@ var KiroResponseAssembler = class {
|
|
|
3240
3653
|
textLen: this.textBlockIndex === null ? 0 : this.blocks.getText(this.textBlockIndex).length,
|
|
3241
3654
|
usage: this.usage
|
|
3242
3655
|
});
|
|
3243
|
-
return {
|
|
3656
|
+
return {
|
|
3657
|
+
stopReason,
|
|
3658
|
+
usage: this.usage,
|
|
3659
|
+
wireUsage: this.usageEvent,
|
|
3660
|
+
metering: this.meteringEvent
|
|
3661
|
+
};
|
|
3244
3662
|
}
|
|
3245
3663
|
ensureNativeThinkingBlock() {
|
|
3246
3664
|
if (this.nativeThinkingBlockIndex === null)
|
|
@@ -3275,6 +3693,8 @@ var KiroResponseAssembler = class {
|
|
|
3275
3693
|
return;
|
|
3276
3694
|
if (this.emitToolCall(this.currentToolCall))
|
|
3277
3695
|
this.emittedToolCalls++;
|
|
3696
|
+
else
|
|
3697
|
+
this.droppedToolCalls.push(this.currentToolCall.name);
|
|
3278
3698
|
this.currentToolCall = null;
|
|
3279
3699
|
}
|
|
3280
3700
|
/**
|
|
@@ -3316,6 +3736,8 @@ var KiroResponseAssembler = class {
|
|
|
3316
3736
|
for (const call of recovered) {
|
|
3317
3737
|
if (this.emitToolCall({ toolUseId: call.toolUseId, name: call.name, input: JSON.stringify(call.arguments) })) {
|
|
3318
3738
|
this.emittedToolCalls++;
|
|
3739
|
+
} else {
|
|
3740
|
+
this.droppedToolCalls.push(call.name);
|
|
3319
3741
|
}
|
|
3320
3742
|
}
|
|
3321
3743
|
}
|
|
@@ -3334,13 +3756,13 @@ var KiroResponseAssembler = class {
|
|
|
3334
3756
|
}
|
|
3335
3757
|
};
|
|
3336
3758
|
|
|
3337
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3759
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/index.js
|
|
3338
3760
|
import { getRandomValues } from "node:crypto";
|
|
3339
3761
|
|
|
3340
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3762
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/is-array-buffer/is-array-buffer.js
|
|
3341
3763
|
var isArrayBuffer = (arg) => typeof ArrayBuffer === "function" && arg instanceof ArrayBuffer || Object.prototype.toString.call(arg) === "[object ArrayBuffer]";
|
|
3342
3764
|
|
|
3343
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3765
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/util-buffer-from/buffer-from.js
|
|
3344
3766
|
var fromArrayBuffer = (input, offset = 0, length = input.byteLength - offset) => {
|
|
3345
3767
|
if (!isArrayBuffer(input)) {
|
|
3346
3768
|
throw new TypeError(`The "input" argument must be ArrayBuffer. Received type ${typeof input} (${input})`);
|
|
@@ -3354,7 +3776,7 @@ var fromString = (input, encoding) => {
|
|
|
3354
3776
|
return encoding ? Buffer.from(input, encoding) : Buffer.from(input);
|
|
3355
3777
|
};
|
|
3356
3778
|
|
|
3357
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3779
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/util-base64/fromBase64.js
|
|
3358
3780
|
var BASE64_REGEX = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
3359
3781
|
var fromBase64 = (input) => {
|
|
3360
3782
|
if (input.length * 3 % 4 !== 0) {
|
|
@@ -3367,13 +3789,13 @@ var fromBase64 = (input) => {
|
|
|
3367
3789
|
return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
3368
3790
|
};
|
|
3369
3791
|
|
|
3370
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3792
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/util-utf8/fromUtf8.js
|
|
3371
3793
|
var fromUtf8 = (input) => {
|
|
3372
3794
|
const buf = fromString(input, "utf8");
|
|
3373
3795
|
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength / Uint8Array.BYTES_PER_ELEMENT);
|
|
3374
3796
|
};
|
|
3375
3797
|
|
|
3376
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3798
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/util-base64/toBase64.js
|
|
3377
3799
|
var toBase64 = (_input) => {
|
|
3378
3800
|
let input;
|
|
3379
3801
|
if (typeof _input === "string") {
|
|
@@ -3387,7 +3809,7 @@ var toBase64 = (_input) => {
|
|
|
3387
3809
|
return fromArrayBuffer(input.buffer, input.byteOffset, input.byteLength).toString("base64");
|
|
3388
3810
|
};
|
|
3389
3811
|
|
|
3390
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3812
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/util-stream/blob/Uint8ArrayBlobAdapter.js
|
|
3391
3813
|
function bindUint8ArrayBlobAdapter(toUtf82, fromUtf82, toBase642, fromBase642) {
|
|
3392
3814
|
return class Uint8ArrayBlobAdapter2 extends Uint8Array {
|
|
3393
3815
|
static fromString(source, encoding = "utf-8") {
|
|
@@ -3412,7 +3834,7 @@ function bindUint8ArrayBlobAdapter(toUtf82, fromUtf82, toBase642, fromBase642) {
|
|
|
3412
3834
|
};
|
|
3413
3835
|
}
|
|
3414
3836
|
|
|
3415
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3837
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/util-utf8/toUtf8.js
|
|
3416
3838
|
var toUtf8 = (input) => {
|
|
3417
3839
|
if (typeof input === "string") {
|
|
3418
3840
|
return input;
|
|
@@ -3423,7 +3845,7 @@ var toUtf8 = (input) => {
|
|
|
3423
3845
|
return fromArrayBuffer(input.buffer, input.byteOffset, input.byteLength).toString("utf8");
|
|
3424
3846
|
};
|
|
3425
3847
|
|
|
3426
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3848
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/uuid/v4.js
|
|
3427
3849
|
var decimalToHex = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
3428
3850
|
function bindV4(getRandomValues2) {
|
|
3429
3851
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
@@ -3438,12 +3860,12 @@ function bindV4(getRandomValues2) {
|
|
|
3438
3860
|
};
|
|
3439
3861
|
}
|
|
3440
3862
|
|
|
3441
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3863
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/transport/hasOwn.js
|
|
3442
3864
|
function hasOwn(o, k) {
|
|
3443
3865
|
return Object.prototype.hasOwnProperty.call(o, k);
|
|
3444
3866
|
}
|
|
3445
3867
|
|
|
3446
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3868
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/util-hex-encoding/hex-encoding.js
|
|
3447
3869
|
var SHORT_TO_HEX = {};
|
|
3448
3870
|
var HEX_TO_SHORT = {};
|
|
3449
3871
|
for (let i = 0; i < 256; i++) {
|
|
@@ -3477,13 +3899,13 @@ function toHex(bytes) {
|
|
|
3477
3899
|
return out;
|
|
3478
3900
|
}
|
|
3479
3901
|
|
|
3480
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3902
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/serde/index.js
|
|
3481
3903
|
var Uint8ArrayBlobAdapter = class extends bindUint8ArrayBlobAdapter(toUtf8, fromUtf8, toBase64, fromBase64) {
|
|
3482
3904
|
};
|
|
3483
3905
|
var _getRandomValues = getRandomValues;
|
|
3484
3906
|
var v4 = bindV4(_getRandomValues);
|
|
3485
3907
|
|
|
3486
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3908
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/checksum/crc32/Crc32Js.js
|
|
3487
3909
|
var CRC32_TABLE = new Uint32Array(256);
|
|
3488
3910
|
for (let i = 0; i < 256; ++i) {
|
|
3489
3911
|
let c = i;
|
|
@@ -3515,7 +3937,7 @@ var Crc32Js = class {
|
|
|
3515
3937
|
}
|
|
3516
3938
|
};
|
|
3517
3939
|
|
|
3518
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3940
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/checksum/crc32/Crc32Node.js
|
|
3519
3941
|
import * as zlib from "node:zlib";
|
|
3520
3942
|
var zlibCrc32 = typeof zlib.crc32 === "function" ? zlib.crc32 : void 0;
|
|
3521
3943
|
var Crc32Node = zlibCrc32 ? buildNativeClass(zlibCrc32) : Crc32Js;
|
|
@@ -3540,7 +3962,7 @@ function buildNativeClass(nativeCrc32) {
|
|
|
3540
3962
|
};
|
|
3541
3963
|
}
|
|
3542
3964
|
|
|
3543
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
3965
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-codec/Int64.js
|
|
3544
3966
|
var Int64 = class _Int64 {
|
|
3545
3967
|
bytes;
|
|
3546
3968
|
constructor(bytes) {
|
|
@@ -3585,7 +4007,7 @@ function negate(bytes) {
|
|
|
3585
4007
|
}
|
|
3586
4008
|
}
|
|
3587
4009
|
|
|
3588
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
4010
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-codec/HeaderMarshaller.js
|
|
3589
4011
|
var HeaderMarshaller = class {
|
|
3590
4012
|
toUtf8;
|
|
3591
4013
|
fromUtf8;
|
|
@@ -3771,7 +4193,7 @@ var TIMESTAMP_TAG = "timestamp";
|
|
|
3771
4193
|
var UUID_TAG = "uuid";
|
|
3772
4194
|
var UUID_PATTERN = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
|
|
3773
4195
|
|
|
3774
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
4196
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-codec/splitMessage.js
|
|
3775
4197
|
var PRELUDE_MEMBER_LENGTH = 4;
|
|
3776
4198
|
var PRELUDE_LENGTH = PRELUDE_MEMBER_LENGTH * 2;
|
|
3777
4199
|
var CHECKSUM_LENGTH = 4;
|
|
@@ -3803,7 +4225,7 @@ function splitMessage({ byteLength, byteOffset, buffer }) {
|
|
|
3803
4225
|
};
|
|
3804
4226
|
}
|
|
3805
4227
|
|
|
3806
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
4228
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-codec/EventStreamCodec.js
|
|
3807
4229
|
var EventStreamCodec = class {
|
|
3808
4230
|
headerMarshaller;
|
|
3809
4231
|
messageBuffer;
|
|
@@ -3869,7 +4291,7 @@ var EventStreamCodec = class {
|
|
|
3869
4291
|
}
|
|
3870
4292
|
};
|
|
3871
4293
|
|
|
3872
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
4294
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-codec/MessageDecoderStream.js
|
|
3873
4295
|
var MessageDecoderStream = class {
|
|
3874
4296
|
options;
|
|
3875
4297
|
constructor(options) {
|
|
@@ -3886,7 +4308,7 @@ var MessageDecoderStream = class {
|
|
|
3886
4308
|
}
|
|
3887
4309
|
};
|
|
3888
4310
|
|
|
3889
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
4311
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-codec/MessageEncoderStream.js
|
|
3890
4312
|
var MessageEncoderStream = class {
|
|
3891
4313
|
options;
|
|
3892
4314
|
constructor(options) {
|
|
@@ -3906,7 +4328,7 @@ var MessageEncoderStream = class {
|
|
|
3906
4328
|
}
|
|
3907
4329
|
};
|
|
3908
4330
|
|
|
3909
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
4331
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-codec/SmithyMessageDecoderStream.js
|
|
3910
4332
|
var SmithyMessageDecoderStream = class {
|
|
3911
4333
|
options;
|
|
3912
4334
|
constructor(options) {
|
|
@@ -3925,7 +4347,7 @@ var SmithyMessageDecoderStream = class {
|
|
|
3925
4347
|
}
|
|
3926
4348
|
};
|
|
3927
4349
|
|
|
3928
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
4350
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-codec/SmithyMessageEncoderStream.js
|
|
3929
4351
|
var SmithyMessageEncoderStream = class {
|
|
3930
4352
|
options;
|
|
3931
4353
|
constructor(options) {
|
|
@@ -3942,7 +4364,7 @@ var SmithyMessageEncoderStream = class {
|
|
|
3942
4364
|
}
|
|
3943
4365
|
};
|
|
3944
4366
|
|
|
3945
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
4367
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-serde-universal/getChunkedStream.js
|
|
3946
4368
|
function getChunkedStream(source) {
|
|
3947
4369
|
let currentMessageTotalLength = 0;
|
|
3948
4370
|
let currentMessagePendingLength = 0;
|
|
@@ -4008,7 +4430,7 @@ function getChunkedStream(source) {
|
|
|
4008
4430
|
};
|
|
4009
4431
|
}
|
|
4010
4432
|
|
|
4011
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
4433
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-serde-universal/getUnmarshalledStream.js
|
|
4012
4434
|
function getMessageUnmarshaller(deserializer, toUtf82) {
|
|
4013
4435
|
return async function(message) {
|
|
4014
4436
|
const { value: messageType } = message.headers[":message-type"];
|
|
@@ -4040,7 +4462,7 @@ function getMessageUnmarshaller(deserializer, toUtf82) {
|
|
|
4040
4462
|
};
|
|
4041
4463
|
}
|
|
4042
4464
|
|
|
4043
|
-
// ../../node_modules/.pnpm/@smithy+core@3.
|
|
4465
|
+
// ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-serde-universal/EventStreamMarshaller.js
|
|
4044
4466
|
var EventStreamMarshaller = class {
|
|
4045
4467
|
eventStreamCodec;
|
|
4046
4468
|
utfEncoder;
|
|
@@ -4075,6 +4497,7 @@ function readKiroEventStream(body, options) {
|
|
|
4075
4497
|
const outcome = { firstTokenTimedOut: false, idleTimedOut: false, error: null };
|
|
4076
4498
|
const idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT;
|
|
4077
4499
|
const bodyReader = body.getReader();
|
|
4500
|
+
const callerSignal = options.signal;
|
|
4078
4501
|
async function* frames() {
|
|
4079
4502
|
let idleTimer = null;
|
|
4080
4503
|
const resetIdle = () => {
|
|
@@ -4086,6 +4509,14 @@ function readKiroEventStream(body, options) {
|
|
|
4086
4509
|
});
|
|
4087
4510
|
}, idleTimeoutMs);
|
|
4088
4511
|
};
|
|
4512
|
+
const onCallerStreamAbort = () => {
|
|
4513
|
+
void bodyReader.cancel().catch(() => {
|
|
4514
|
+
});
|
|
4515
|
+
};
|
|
4516
|
+
if (callerSignal?.aborted)
|
|
4517
|
+
onCallerStreamAbort();
|
|
4518
|
+
else
|
|
4519
|
+
callerSignal?.addEventListener("abort", onCallerStreamAbort, { once: true });
|
|
4089
4520
|
const bodyIterable = {
|
|
4090
4521
|
async *[Symbol.asyncIterator]() {
|
|
4091
4522
|
try {
|
|
@@ -4106,37 +4537,71 @@ function readKiroEventStream(body, options) {
|
|
|
4106
4537
|
if (!entry)
|
|
4107
4538
|
throw new Error("Received an empty event stream message");
|
|
4108
4539
|
const [key, msg] = entry;
|
|
4540
|
+
if (msg.headers[":message-type"]?.value === "exception") {
|
|
4541
|
+
let parsedException = {};
|
|
4542
|
+
try {
|
|
4543
|
+
const decoded = JSON.parse(utf8Decoder.decode(msg.body));
|
|
4544
|
+
if (decoded && typeof decoded === "object")
|
|
4545
|
+
parsedException = decoded;
|
|
4546
|
+
} catch {
|
|
4547
|
+
}
|
|
4548
|
+
const data = parseKiroExceptionFrame(key, parsedException) ?? {
|
|
4549
|
+
error: key,
|
|
4550
|
+
kind: "unknown",
|
|
4551
|
+
...typeof parsedException.message === "string" ? { message: parsedException.message } : {},
|
|
4552
|
+
...typeof parsedException.reason === "string" ? { reason: parsedException.reason } : {},
|
|
4553
|
+
...typeof parsedException.retryAfterMilliseconds === "number" ? { retryAfterMilliseconds: parsedException.retryAfterMilliseconds } : {}
|
|
4554
|
+
};
|
|
4555
|
+
const error2 = new Error(data.message ? `${data.error}: ${data.message}` : data.error);
|
|
4556
|
+
error2.name = data.error;
|
|
4557
|
+
error2.kiroError = data;
|
|
4558
|
+
return { [key]: error2 };
|
|
4559
|
+
}
|
|
4109
4560
|
const parsed = JSON.parse(utf8Decoder.decode(msg.body));
|
|
4110
4561
|
return { [key]: parsed };
|
|
4111
4562
|
});
|
|
4112
4563
|
const iterator = eventStream[Symbol.asyncIterator]();
|
|
4113
4564
|
let gotFirstToken = false;
|
|
4114
|
-
const FIRST_TOKEN_SENTINEL = Symbol("firstTokenTimeout");
|
|
4565
|
+
const FIRST_TOKEN_SENTINEL = /* @__PURE__ */ Symbol("firstTokenTimeout");
|
|
4115
4566
|
try {
|
|
4116
4567
|
while (true) {
|
|
4568
|
+
if (callerSignal?.aborted) {
|
|
4569
|
+
throw callerSignal.reason ?? new Error("Request aborted");
|
|
4570
|
+
}
|
|
4117
4571
|
let iterResult;
|
|
4118
4572
|
try {
|
|
4119
4573
|
if (!gotFirstToken) {
|
|
4120
4574
|
const readPromise = iterator.next();
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4575
|
+
let firstTokenTimer;
|
|
4576
|
+
try {
|
|
4577
|
+
const result = await Promise.race([
|
|
4578
|
+
readPromise,
|
|
4579
|
+
new Promise((resolve) => {
|
|
4580
|
+
firstTokenTimer = setTimeout(() => resolve(FIRST_TOKEN_SENTINEL), options.firstTokenTimeoutMs);
|
|
4581
|
+
})
|
|
4582
|
+
]);
|
|
4583
|
+
if (result === FIRST_TOKEN_SENTINEL) {
|
|
4584
|
+
readPromise.catch(() => {
|
|
4585
|
+
});
|
|
4586
|
+
void bodyReader.cancel().catch(() => {
|
|
4587
|
+
});
|
|
4588
|
+
outcome.firstTokenTimedOut = true;
|
|
4589
|
+
return;
|
|
4590
|
+
}
|
|
4591
|
+
iterResult = result;
|
|
4592
|
+
gotFirstToken = true;
|
|
4593
|
+
resetIdle();
|
|
4594
|
+
} finally {
|
|
4595
|
+
if (firstTokenTimer !== void 0)
|
|
4596
|
+
clearTimeout(firstTokenTimer);
|
|
4132
4597
|
}
|
|
4133
|
-
iterResult = result;
|
|
4134
|
-
gotFirstToken = true;
|
|
4135
|
-
resetIdle();
|
|
4136
4598
|
} else {
|
|
4137
4599
|
iterResult = await iterator.next();
|
|
4138
4600
|
}
|
|
4139
4601
|
} catch (e) {
|
|
4602
|
+
const kiroError = e?.kiroError;
|
|
4603
|
+
if (kiroError)
|
|
4604
|
+
outcome.errorData = kiroError;
|
|
4140
4605
|
outcome.error = e instanceof Error ? e.message : (typeof e === "object" && e !== null ? JSON.stringify(e) : String(e)) || "Unknown stream error";
|
|
4141
4606
|
return;
|
|
4142
4607
|
}
|
|
@@ -4144,148 +4609,40 @@ function readKiroEventStream(body, options) {
|
|
|
4144
4609
|
if (done)
|
|
4145
4610
|
return;
|
|
4146
4611
|
resetIdle();
|
|
4147
|
-
const
|
|
4148
|
-
|
|
4612
|
+
const frameEntry = Object.entries(value)[0];
|
|
4613
|
+
if (!frameEntry)
|
|
4614
|
+
continue;
|
|
4615
|
+
const [frameKey, framePayload] = frameEntry;
|
|
4616
|
+
const event = parseKiroEvent(frameKey, framePayload ?? {});
|
|
4149
4617
|
if (!event)
|
|
4150
4618
|
continue;
|
|
4619
|
+
if (event.type === "ignored") {
|
|
4620
|
+
if (debugEnabled())
|
|
4621
|
+
debugLog("stream.events.ignored", [event.data.key]);
|
|
4622
|
+
continue;
|
|
4623
|
+
}
|
|
4151
4624
|
if (debugEnabled())
|
|
4152
4625
|
debugLog("stream.events", [event]);
|
|
4153
4626
|
if (event.type === "error") {
|
|
4154
4627
|
outcome.error = event.data.message ? `${event.data.error}: ${event.data.message}` : event.data.error;
|
|
4628
|
+
outcome.errorData = event.data;
|
|
4155
4629
|
void bodyReader.cancel().catch(() => {
|
|
4156
4630
|
});
|
|
4157
4631
|
return;
|
|
4158
4632
|
}
|
|
4159
|
-
yield { event, payload };
|
|
4633
|
+
yield { event, payload: framePayload };
|
|
4160
4634
|
}
|
|
4161
4635
|
} finally {
|
|
4162
4636
|
if (idleTimer)
|
|
4163
4637
|
clearTimeout(idleTimer);
|
|
4638
|
+
callerSignal?.removeEventListener("abort", onCallerStreamAbort);
|
|
4164
4639
|
}
|
|
4165
4640
|
}
|
|
4166
4641
|
return { frames: frames(), outcome };
|
|
4167
4642
|
}
|
|
4168
4643
|
|
|
4169
|
-
// ../kiro-core/dist/retry.js
|
|
4170
|
-
init_models();
|
|
4171
|
-
var FIRST_TOKEN_TIMEOUT = 9e4;
|
|
4172
|
-
var REQUEST_HEADER_TIMEOUT = 9e4;
|
|
4173
|
-
function firstTokenTimeoutForModel(modelId) {
|
|
4174
|
-
if (retryConfig.firstTokenTimeoutMs !== FIRST_TOKEN_TIMEOUT) {
|
|
4175
|
-
return retryConfig.firstTokenTimeoutMs;
|
|
4176
|
-
}
|
|
4177
|
-
const model = kiroModels.find((m) => m.id === modelId);
|
|
4178
|
-
return model?.firstTokenTimeout ?? FIRST_TOKEN_TIMEOUT;
|
|
4179
|
-
}
|
|
4180
|
-
var retryConfig = {
|
|
4181
|
-
firstTokenTimeoutMs: FIRST_TOKEN_TIMEOUT,
|
|
4182
|
-
requestHeaderTimeoutMs: REQUEST_HEADER_TIMEOUT
|
|
4183
|
-
};
|
|
4184
|
-
function exponentialBackoff(attempt, baseMs, maxMs) {
|
|
4185
|
-
return Math.min(baseMs * 2 ** attempt, maxMs);
|
|
4186
|
-
}
|
|
4187
|
-
var MAX_RETRY_DELAY = 1e4;
|
|
4188
|
-
var REQUEST_RATE_FALLBACK_DELAY_MS = 1e4;
|
|
4189
|
-
function extractKiroReason(errorText) {
|
|
4190
|
-
if (!errorText)
|
|
4191
|
-
return void 0;
|
|
4192
|
-
try {
|
|
4193
|
-
const parsed = JSON.parse(errorText);
|
|
4194
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
4195
|
-
return void 0;
|
|
4196
|
-
const reason = parsed.reason;
|
|
4197
|
-
return typeof reason === "string" && reason.length > 0 ? reason : void 0;
|
|
4198
|
-
} catch {
|
|
4199
|
-
return void 0;
|
|
4200
|
-
}
|
|
4201
|
-
}
|
|
4202
|
-
function parseRetryAfterMs(headers, nowMs = Date.now()) {
|
|
4203
|
-
const get = headers?.get?.bind(headers);
|
|
4204
|
-
if (!get)
|
|
4205
|
-
return void 0;
|
|
4206
|
-
const milliseconds = nonNegativeNumber(get("retry-after-ms"));
|
|
4207
|
-
if (milliseconds !== void 0)
|
|
4208
|
-
return Math.round(milliseconds);
|
|
4209
|
-
const retryAfter = get("retry-after");
|
|
4210
|
-
if (retryAfter !== null && retryAfter.trim() !== "") {
|
|
4211
|
-
const seconds = Number(retryAfter);
|
|
4212
|
-
if (Number.isFinite(seconds)) {
|
|
4213
|
-
if (seconds >= 0) {
|
|
4214
|
-
const delayMs = seconds * 1e3;
|
|
4215
|
-
if (Number.isFinite(delayMs))
|
|
4216
|
-
return Math.round(delayMs);
|
|
4217
|
-
}
|
|
4218
|
-
} else {
|
|
4219
|
-
const dateMs = Date.parse(retryAfter);
|
|
4220
|
-
if (!Number.isNaN(dateMs))
|
|
4221
|
-
return Math.max(0, dateMs - nowMs);
|
|
4222
|
-
}
|
|
4223
|
-
}
|
|
4224
|
-
const resetAfterSeconds = nonNegativeNumber(get("x-ratelimit-reset-after"));
|
|
4225
|
-
if (resetAfterSeconds !== void 0) {
|
|
4226
|
-
const delayMs = resetAfterSeconds * 1e3;
|
|
4227
|
-
if (Number.isFinite(delayMs))
|
|
4228
|
-
return Math.round(delayMs);
|
|
4229
|
-
}
|
|
4230
|
-
return void 0;
|
|
4231
|
-
}
|
|
4232
|
-
function resolveRequestRateRetryDelay(headers, nowMs = Date.now()) {
|
|
4233
|
-
const advertisedDelayMs = parseRetryAfterMs(headers, nowMs);
|
|
4234
|
-
const requestedDelayMs = advertisedDelayMs ?? REQUEST_RATE_FALLBACK_DELAY_MS;
|
|
4235
|
-
return {
|
|
4236
|
-
delayMs: Math.min(requestedDelayMs, MAX_RETRY_DELAY),
|
|
4237
|
-
...advertisedDelayMs !== void 0 ? { advertisedDelayMs } : {},
|
|
4238
|
-
capped: requestedDelayMs > MAX_RETRY_DELAY
|
|
4239
|
-
};
|
|
4240
|
-
}
|
|
4241
|
-
function nonNegativeNumber(value) {
|
|
4242
|
-
if (value === null || value.trim() === "")
|
|
4243
|
-
return void 0;
|
|
4244
|
-
const parsed = Number(value);
|
|
4245
|
-
return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
|
|
4246
|
-
}
|
|
4247
|
-
var KIRO_REASON_CODES = Object.freeze({
|
|
4248
|
-
/** Request body exceeded the service's size threshold. */
|
|
4249
|
-
CONTENT_LENGTH_EXCEEDS_THRESHOLD: "CONTENT_LENGTH_EXCEEDS_THRESHOLD",
|
|
4250
|
-
/** Prose-only size rejection; the service sends no reason code for this one. */
|
|
4251
|
-
INPUT_TOO_LONG: "Input is too long",
|
|
4252
|
-
/** Monthly request quota exhausted — hard limit, not transient. */
|
|
4253
|
-
MONTHLY_REQUEST_COUNT: "MONTHLY_REQUEST_COUNT",
|
|
4254
|
-
/** Model capacity temporarily unavailable — transient, worth retrying. */
|
|
4255
|
-
INSUFFICIENT_MODEL_CAPACITY: "INSUFFICIENT_MODEL_CAPACITY",
|
|
4256
|
-
/** Short-window request throttle — retry only within the provider budget. */
|
|
4257
|
-
USER_REQUEST_RATE_EXCEEDED: "USER_REQUEST_RATE_EXCEEDED",
|
|
4258
|
-
/**
|
|
4259
|
-
* Generic request-validation rejection, returned for a malformed body of any
|
|
4260
|
-
* size (empty `content`, history referencing tools absent from the catalog).
|
|
4261
|
-
* Not a size signal: classifying it as "too big" makes the caller compact a
|
|
4262
|
-
* history that was never the problem, a loop it can never satisfy.
|
|
4263
|
-
*/
|
|
4264
|
-
REQUEST_BODY_INVALID: "REQUEST_BODY_INVALID"
|
|
4265
|
-
});
|
|
4266
|
-
var TOO_BIG_PATTERNS = Object.freeze([
|
|
4267
|
-
KIRO_REASON_CODES.CONTENT_LENGTH_EXCEEDS_THRESHOLD,
|
|
4268
|
-
KIRO_REASON_CODES.INPUT_TOO_LONG
|
|
4269
|
-
]);
|
|
4270
|
-
var NON_RETRYABLE_BODY_PATTERNS = Object.freeze([KIRO_REASON_CODES.MONTHLY_REQUEST_COUNT]);
|
|
4271
|
-
var CAPACITY_PATTERN = KIRO_REASON_CODES.INSUFFICIENT_MODEL_CAPACITY;
|
|
4272
|
-
var CAPACITY_MAX_RETRIES = 3;
|
|
4273
|
-
var CAPACITY_BASE_DELAY_MS = 5e3;
|
|
4274
|
-
var capacityRetryConfig = {
|
|
4275
|
-
maxRetries: CAPACITY_MAX_RETRIES,
|
|
4276
|
-
baseDelayMs: CAPACITY_BASE_DELAY_MS
|
|
4277
|
-
};
|
|
4278
|
-
function isTooBigError(status, errorText) {
|
|
4279
|
-
return status === 413 || status === 400 && TOO_BIG_PATTERNS.some((p) => errorText.includes(p));
|
|
4280
|
-
}
|
|
4281
|
-
function isNonRetryableBodyError(errorText) {
|
|
4282
|
-
return NON_RETRYABLE_BODY_PATTERNS.some((p) => errorText.includes(p));
|
|
4283
|
-
}
|
|
4284
|
-
function isCapacityError(errorText) {
|
|
4285
|
-
return errorText.includes(CAPACITY_PATTERN);
|
|
4286
|
-
}
|
|
4287
|
-
|
|
4288
4644
|
// ../kiro-core/dist/stream.js
|
|
4645
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
4289
4646
|
init_debug();
|
|
4290
4647
|
init_effort();
|
|
4291
4648
|
init_endpoints();
|
|
@@ -4358,7 +4715,64 @@ function createResponseHeaderDeadline(callerSignal, timeoutMs) {
|
|
|
4358
4715
|
};
|
|
4359
4716
|
}
|
|
4360
4717
|
|
|
4718
|
+
// ../kiro-core/dist/usage-tracking.js
|
|
4719
|
+
var DEFAULT_USD_PER_CREDIT = 0.04;
|
|
4720
|
+
var DEFAULT_ESTIMATED_CACHE_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
4721
|
+
var KIRO_USAGE_TRACKING_DISABLED = Object.freeze({
|
|
4722
|
+
estimateDollarValue: false,
|
|
4723
|
+
usdPerCredit: DEFAULT_USD_PER_CREDIT,
|
|
4724
|
+
estimateCacheUsage: false,
|
|
4725
|
+
estimatedCacheTimeout: DEFAULT_ESTIMATED_CACHE_TIMEOUT_MS
|
|
4726
|
+
});
|
|
4727
|
+
var CREDIT_UNITS = /* @__PURE__ */ new Set(["credit", "credits"]);
|
|
4728
|
+
function estimateKiroCreditCost(tracking, metering) {
|
|
4729
|
+
if (!tracking.estimateDollarValue || !metering)
|
|
4730
|
+
return void 0;
|
|
4731
|
+
if (typeof metering.unit !== "string" || !CREDIT_UNITS.has(metering.unit.toLowerCase()))
|
|
4732
|
+
return void 0;
|
|
4733
|
+
const { credits } = metering;
|
|
4734
|
+
if (typeof credits !== "number" || !Number.isFinite(credits) || credits < 0)
|
|
4735
|
+
return void 0;
|
|
4736
|
+
return credits * tracking.usdPerCredit;
|
|
4737
|
+
}
|
|
4738
|
+
|
|
4361
4739
|
// ../kiro-core/dist/stream.js
|
|
4740
|
+
function describeAttempts(count) {
|
|
4741
|
+
return count === 1 ? "1 attempt" : `${count} attempts`;
|
|
4742
|
+
}
|
|
4743
|
+
var DIAGNOSTIC_QUOTE_LIMIT = 200;
|
|
4744
|
+
function clampForDiagnostic(text) {
|
|
4745
|
+
return text.length <= DIAGNOSTIC_QUOTE_LIMIT ? text : `${text.slice(0, DIAGNOSTIC_QUOTE_LIMIT)}\u2026 (truncated)`;
|
|
4746
|
+
}
|
|
4747
|
+
function encodeBytesForDiagnostic(bytes) {
|
|
4748
|
+
let encoded = "";
|
|
4749
|
+
for (const byte of bytes) {
|
|
4750
|
+
encoded += String.fromCharCode(65 + (byte >> 4), 65 + (byte & 15));
|
|
4751
|
+
}
|
|
4752
|
+
return encoded;
|
|
4753
|
+
}
|
|
4754
|
+
function encodeToolNameForDiagnostic(name) {
|
|
4755
|
+
const identity = typeof name === "string" ? name : `${typeof name}:${JSON.stringify(name)}`;
|
|
4756
|
+
let encoded = "";
|
|
4757
|
+
for (let i = 0; i < identity.length; i++) {
|
|
4758
|
+
const codeUnit = identity.charCodeAt(i);
|
|
4759
|
+
encoded += String.fromCharCode(65 + (codeUnit >> 12), 65 + (codeUnit >> 8 & 15), 65 + (codeUnit >> 4 & 15), 65 + (codeUnit & 15));
|
|
4760
|
+
}
|
|
4761
|
+
return encoded;
|
|
4762
|
+
}
|
|
4763
|
+
function describeDroppedToolNames(names) {
|
|
4764
|
+
const encoded = names.map((name) => `A-P:${encodeToolNameForDiagnostic(name)}`).join(", ");
|
|
4765
|
+
if (encoded.length <= DIAGNOSTIC_QUOTE_LIMIT)
|
|
4766
|
+
return encoded;
|
|
4767
|
+
const digest = createHash3("sha256").update(JSON.stringify(names)).digest();
|
|
4768
|
+
return `A-P-DIGEST:${encodeBytesForDiagnostic(digest)} (tool identities fingerprinted)`;
|
|
4769
|
+
}
|
|
4770
|
+
function describeReturnedContent(kinds) {
|
|
4771
|
+
const unique = [...new Set(kinds)].sort();
|
|
4772
|
+
if (unique.length === 0)
|
|
4773
|
+
return "returning empty content";
|
|
4774
|
+
return `returning only ${unique.join(" and ")} content`;
|
|
4775
|
+
}
|
|
4362
4776
|
var skipProfileResolutionForTests = false;
|
|
4363
4777
|
var TEST_PROFILE_ARN = "arn:aws:codewhisperer:us-east-1:000000000000:profile/test";
|
|
4364
4778
|
async function* streamKiro(request) {
|
|
@@ -4369,7 +4783,6 @@ async function* streamKiro(request) {
|
|
|
4369
4783
|
}
|
|
4370
4784
|
let accessToken = initialAccessToken;
|
|
4371
4785
|
const region = model.region ?? "us-east-1";
|
|
4372
|
-
const endpoint = new URL("generateAssistantResponse", getKiroEndpoints(region).runtime).toString();
|
|
4373
4786
|
let managementAuth = { accessToken, region };
|
|
4374
4787
|
const cliCreds = getKiroCliCredentials() ?? getKiroCliCredentialsAllowExpired();
|
|
4375
4788
|
const cliProfileArn = cliCreds?.access === accessToken ? cliCreds.profileArn : void 0;
|
|
@@ -4388,9 +4801,11 @@ async function* streamKiro(request) {
|
|
|
4388
4801
|
managementAuth = { accessToken, region };
|
|
4389
4802
|
profileArn = freshCreds.profileArn || (skipProfileResolutionForTests ? TEST_PROFILE_ARN : await resolveKiroProfileArn(managementAuth));
|
|
4390
4803
|
}
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4804
|
+
let runtimeRegion = getKiroRegionFromProfileArn(profileArn) ?? region;
|
|
4805
|
+
let endpoint = new URL("generateAssistantResponse", getKiroEndpoints(runtimeRegion).runtime).toString();
|
|
4806
|
+
if (!process.env.VITEST && isCacheStale(runtimeRegion)) {
|
|
4807
|
+
updateKiroModelsCache(accessToken, runtimeRegion, profileArn).catch((error2) => {
|
|
4808
|
+
console.warn(`[kiro-core] Failed to refresh Kiro model catalog in ${runtimeRegion}: ${formatSafeError(error2)}`);
|
|
4394
4809
|
});
|
|
4395
4810
|
}
|
|
4396
4811
|
const kiroModelId = resolveKiroModel(model.id, model.kiroModelId);
|
|
@@ -4419,8 +4834,13 @@ async function* streamKiro(request) {
|
|
|
4419
4834
|
${systemPrompt}` : ""}`;
|
|
4420
4835
|
}
|
|
4421
4836
|
const assembler = new KiroResponseAssembler(model, thinkingEnabled);
|
|
4837
|
+
const usageTracking = request.usageTracking ?? KIRO_USAGE_TRACKING_DISABLED;
|
|
4422
4838
|
let retryCount = 0;
|
|
4423
4839
|
const maxRetries = 3;
|
|
4840
|
+
let emptyAttempts = 0;
|
|
4841
|
+
let echoAttempts = 0;
|
|
4842
|
+
let credentialRefreshTotal = 0;
|
|
4843
|
+
let capacityRetryTotal = 0;
|
|
4424
4844
|
const conversationId = request.sessionId ?? crypto.randomUUID();
|
|
4425
4845
|
requestLoop: while (retryCount <= maxRetries) {
|
|
4426
4846
|
if (signal?.aborted)
|
|
@@ -4503,6 +4923,7 @@ ${systemPrompt}` : ""}`;
|
|
|
4503
4923
|
});
|
|
4504
4924
|
if (isCapacityError(errText) && capacityRetryCount < capacityRetryConfig.maxRetries) {
|
|
4505
4925
|
capacityRetryCount++;
|
|
4926
|
+
capacityRetryTotal++;
|
|
4506
4927
|
const delayMs = exponentialBackoff(capacityRetryCount - 1, capacityRetryConfig.baseDelayMs, 3e4);
|
|
4507
4928
|
logCapacityEvent(`INSUFFICIENT_MODEL_CAPACITY \u2014 retrying in ${delayMs}ms (${capacityRetryCount}/${capacityRetryConfig.maxRetries})`);
|
|
4508
4929
|
await abortableDelay(delayMs, signal);
|
|
@@ -4530,6 +4951,7 @@ ${systemPrompt}` : ""}`;
|
|
|
4530
4951
|
}
|
|
4531
4952
|
if (response.status === 403 && !isCapacityError(errText) && retryCount < maxRetries) {
|
|
4532
4953
|
retryCount++;
|
|
4954
|
+
credentialRefreshTotal++;
|
|
4533
4955
|
invalidateKiroProfileArn(managementAuth);
|
|
4534
4956
|
const rejectedAccessToken = accessToken;
|
|
4535
4957
|
const rejectedProfileArn = profileArn;
|
|
@@ -4541,16 +4963,23 @@ ${systemPrompt}` : ""}`;
|
|
|
4541
4963
|
managementAuth = { accessToken, region };
|
|
4542
4964
|
const inheritedDesktopProfileArn = rejectedCliCreds?.authMethod === "desktop" && freshCreds?.authMethod === "desktop" ? rejectedProfileArn : void 0;
|
|
4543
4965
|
profileArn = freshCreds?.profileArn || inheritedDesktopProfileArn || (skipProfileResolutionForTests ? TEST_PROFILE_ARN : await resolveKiroProfileArn(managementAuth));
|
|
4966
|
+
runtimeRegion = getKiroRegionFromProfileArn(profileArn) ?? region;
|
|
4967
|
+
endpoint = new URL("generateAssistantResponse", getKiroEndpoints(runtimeRegion).runtime).toString();
|
|
4544
4968
|
await abortableDelay(exponentialBackoff(retryCount - 1, 500, MAX_RETRY_DELAY), signal);
|
|
4545
4969
|
break;
|
|
4546
4970
|
}
|
|
4971
|
+
const errorMeta = {
|
|
4972
|
+
reasonCode: extractKiroReasonCode(errText),
|
|
4973
|
+
retryAfterMs: parseRetryAfterMs(response.headers),
|
|
4974
|
+
providerAttempts: { credentialRefresh: credentialRefreshTotal, capacity: capacityRetryTotal }
|
|
4975
|
+
};
|
|
4547
4976
|
if (isNonRetryableBodyError(errText) || isCapacityError(errText)) {
|
|
4548
|
-
throw new
|
|
4977
|
+
throw new KiroApiError(`Kiro API error: ${errText || safeStatusText}`, response.status, errorMeta.reasonCode, errorMeta.retryAfterMs, errorMeta.providerAttempts);
|
|
4549
4978
|
}
|
|
4550
4979
|
if (isTooBigError(response.status, errText)) {
|
|
4551
|
-
throw new
|
|
4980
|
+
throw new KiroApiError(`Kiro API error: context_length_exceeded (${response.status} ${errText})`, response.status, errorMeta.reasonCode, errorMeta.retryAfterMs, errorMeta.providerAttempts);
|
|
4552
4981
|
}
|
|
4553
|
-
throw new
|
|
4982
|
+
throw new KiroApiError(`Kiro API error: ${response.status} ${safeStatusText} ${errText}`, response.status, errorMeta.reasonCode, errorMeta.retryAfterMs, errorMeta.providerAttempts);
|
|
4554
4983
|
}
|
|
4555
4984
|
break;
|
|
4556
4985
|
}
|
|
@@ -4564,7 +4993,8 @@ ${systemPrompt}` : ""}`;
|
|
|
4564
4993
|
throw new Error("No response body");
|
|
4565
4994
|
assembler.beginAttempt();
|
|
4566
4995
|
const { frames, outcome } = readKiroEventStream(response.body, {
|
|
4567
|
-
firstTokenTimeoutMs: model.firstTokenTimeout ?? firstTokenTimeoutForModel(model.id)
|
|
4996
|
+
firstTokenTimeoutMs: model.firstTokenTimeout ?? firstTokenTimeoutForModel(model.id),
|
|
4997
|
+
signal
|
|
4568
4998
|
});
|
|
4569
4999
|
for await (const frame of frames) {
|
|
4570
5000
|
assembler.handle(frame);
|
|
@@ -4574,6 +5004,11 @@ ${systemPrompt}` : ""}`;
|
|
|
4574
5004
|
if (outcome.firstTokenTimedOut || outcome.idleTimedOut || outcome.error) {
|
|
4575
5005
|
if (retryCount < maxRetries) {
|
|
4576
5006
|
retryCount++;
|
|
5007
|
+
if (outcome.errorData && debugEnabled()) {
|
|
5008
|
+
debugLog("stream.error.typed", [outcome.errorData]);
|
|
5009
|
+
}
|
|
5010
|
+
assembler.discard();
|
|
5011
|
+
yield* assembler.takeEvents();
|
|
4577
5012
|
await abortableDelay(exponentialBackoff(retryCount - 1, 1e3, MAX_RETRY_DELAY), signal);
|
|
4578
5013
|
continue;
|
|
4579
5014
|
}
|
|
@@ -4583,7 +5018,13 @@ ${systemPrompt}` : ""}`;
|
|
|
4583
5018
|
}
|
|
4584
5019
|
const summary = assembler.endTurn();
|
|
4585
5020
|
yield* assembler.takeEvents();
|
|
4586
|
-
|
|
5021
|
+
const degenerate = summary.isEmpty || summary.isEchoLoop;
|
|
5022
|
+
if (summary.isEchoLoop)
|
|
5023
|
+
echoAttempts++;
|
|
5024
|
+
else if (degenerate)
|
|
5025
|
+
emptyAttempts++;
|
|
5026
|
+
let errorMessage;
|
|
5027
|
+
if (degenerate) {
|
|
4587
5028
|
const mayRetry = retryCount < maxRetries && (!summary.isEchoLoop || request.canDiscardEmittedBlocks === true);
|
|
4588
5029
|
if (mayRetry) {
|
|
4589
5030
|
retryCount++;
|
|
@@ -4595,15 +5036,39 @@ ${systemPrompt}` : ""}`;
|
|
|
4595
5036
|
}
|
|
4596
5037
|
if (summary.isEchoLoop) {
|
|
4597
5038
|
assembler.stripEcho();
|
|
4598
|
-
|
|
5039
|
+
const alsoEmpty = emptyAttempts > 0 ? ` (plus ${describeAttempts(emptyAttempts)} with no text at all)` : "";
|
|
5040
|
+
console.warn(`[kiro-core] Echo loop persisted across ${describeAttempts(echoAttempts)}${alsoEmpty} \u2014 stripping "Continue" response (${summary.responseText.length} chars)`);
|
|
5041
|
+
errorMessage = `Kiro model echoed its own continuation prompt (${JSON.stringify(clampForDiagnostic(summary.responseText))}) on ${describeAttempts(echoAttempts)}${alsoEmpty} and emitted no tool calls; retry budget exhausted, text stripped, stopReason:"${summary.stopReason}"`;
|
|
4599
5042
|
} else {
|
|
4600
|
-
|
|
5043
|
+
const alsoEchoed = echoAttempts > 0 ? ` (plus ${describeAttempts(echoAttempts)} that echoed the continuation prompt)` : "";
|
|
5044
|
+
console.warn(`[kiro-core] Empty response on ${describeAttempts(emptyAttempts)}${alsoEchoed}, retry budget exhausted \u2014 returning stopReason:"${summary.stopReason}" to avoid agent loop stall`);
|
|
5045
|
+
errorMessage = `Kiro returned no text and no tool calls on ${describeAttempts(emptyAttempts)}${alsoEchoed}; retry budget exhausted, ${describeReturnedContent(assembler.contentKinds())} with stopReason:"${summary.stopReason}"`;
|
|
4601
5046
|
}
|
|
4602
5047
|
}
|
|
4603
|
-
|
|
5048
|
+
if (summary.droppedToolCalls.length > 0) {
|
|
5049
|
+
const names = describeDroppedToolNames(summary.droppedToolCalls);
|
|
5050
|
+
const one = summary.droppedToolCalls.length === 1;
|
|
5051
|
+
const dropDiagnostic = `Kiro sent ${one ? "a tool call" : "tool calls"} with unparseable arguments (${names}); ${one ? "it was" : "they were"} dropped and never reached the agent, stopReason:"${summary.stopReason}"`;
|
|
5052
|
+
errorMessage = errorMessage ? `${errorMessage}. ${dropDiagnostic}` : dropDiagnostic;
|
|
5053
|
+
}
|
|
5054
|
+
const { stopReason, usage, wireUsage, metering } = assembler.complete();
|
|
4604
5055
|
yield* assembler.takeEvents();
|
|
5056
|
+
if (!errorMessage) {
|
|
5057
|
+
const estimatedRead = applyCacheEstimate(conversationId, usage, wireUsage, usageTracking);
|
|
5058
|
+
if (estimatedRead > 0) {
|
|
5059
|
+
debugLog("usage.estimate", {
|
|
5060
|
+
conversationId,
|
|
5061
|
+
estimatedRead,
|
|
5062
|
+
input: usage.input,
|
|
5063
|
+
cacheRead: usage.cacheRead
|
|
5064
|
+
});
|
|
5065
|
+
}
|
|
5066
|
+
const estimatedCost = estimateKiroCreditCost(usageTracking, metering);
|
|
5067
|
+
if (estimatedCost !== void 0)
|
|
5068
|
+
usage.cost.total = estimatedCost;
|
|
5069
|
+
}
|
|
4605
5070
|
yield { type: "usage", usage };
|
|
4606
|
-
yield { type: "done", stopReason };
|
|
5071
|
+
yield { type: "done", stopReason, ...errorMessage ? { errorMessage } : {} };
|
|
4607
5072
|
return;
|
|
4608
5073
|
}
|
|
4609
5074
|
}
|
|
@@ -4698,7 +5163,12 @@ async function loginKiro(callbacks) {
|
|
|
4698
5163
|
return existing;
|
|
4699
5164
|
}
|
|
4700
5165
|
if (!callbacks.onPrompt) throw new Error(NO_SESSION_MESSAGE);
|
|
4701
|
-
const apiKey = (await callbacks.onPrompt({
|
|
5166
|
+
const apiKey = (await callbacks.onPrompt({
|
|
5167
|
+
message: NO_SESSION_MESSAGE,
|
|
5168
|
+
placeholder: "ksk_\u2026",
|
|
5169
|
+
allowEmpty: true,
|
|
5170
|
+
secret: true
|
|
5171
|
+
})).trim();
|
|
4702
5172
|
if (!apiKey) throw new Error(NO_SESSION_MESSAGE);
|
|
4703
5173
|
return await loginKiroWithApiKey(apiKey, callbacks.onProgress);
|
|
4704
5174
|
}
|
|
@@ -4976,10 +5446,20 @@ function streamKiroForOmp(model, context, options) {
|
|
|
4976
5446
|
if (event.usage.contextPercent !== void 0) {
|
|
4977
5447
|
output.usage.contextPercent = event.usage.contextPercent;
|
|
4978
5448
|
}
|
|
5449
|
+
if (event.usage.credits !== void 0) {
|
|
5450
|
+
output.usage.credits = event.usage.credits;
|
|
5451
|
+
}
|
|
5452
|
+
if (event.usage.creditUnit !== void 0) {
|
|
5453
|
+
output.usage.creditUnit = event.usage.creditUnit;
|
|
5454
|
+
}
|
|
5455
|
+
if (event.usage.cacheEstimated !== void 0) {
|
|
5456
|
+
output.usage.cacheEstimated = event.usage.cacheEstimated;
|
|
5457
|
+
}
|
|
4979
5458
|
break;
|
|
4980
5459
|
}
|
|
4981
5460
|
case "done":
|
|
4982
5461
|
output.stopReason = event.stopReason;
|
|
5462
|
+
if (event.errorMessage) output.errorMessage = event.errorMessage;
|
|
4983
5463
|
stream.push({ type: "done", reason: event.stopReason, message: output });
|
|
4984
5464
|
break;
|
|
4985
5465
|
}
|
|
@@ -5065,7 +5545,7 @@ function toUsageReport(provider, usage, fetchedAt = Date.now()) {
|
|
|
5065
5545
|
}
|
|
5066
5546
|
var kiroUsageProvider = {
|
|
5067
5547
|
id: "kiro",
|
|
5068
|
-
async fetchUsage(params) {
|
|
5548
|
+
async fetchUsage(params, _ctx) {
|
|
5069
5549
|
const token = params.credential.accessToken ?? params.credential.apiKey;
|
|
5070
5550
|
if (!token) return null;
|
|
5071
5551
|
const usage = await fetchKiroUsage({
|